Properly using Log4r in Ruby Application

log4r, logging, ruby

Solution

Hmm, any reason why you don't instantiate `Log4r::Logger` class at the beginning of your script and pass the instance around? You don't even have to pass it around, you can always get it by name from `Logger` class:

run.rb:

require 'log4r'
require 'class_a'

logger = Log4r::Logger.new('test')
logger.outputters << Log4r::Outputter.stdout
logger.outputters << Log4r::FileOutputter.new('logtest', :filename =>  'logtest.log')
logger.info('started script')
a = A.new
a.do_something
logger.info('finishing')

class_a.rb:

class A
  def do_something
    logger = Log4r::Logger['test']
    logger.info('in do_something')
    puts 'hi!'
  end
end

and when you run `run.rb` you get:

$ ruby run.rb 
 INFO test: started script
 INFO test: in do_something
hi!
 INFO test: finishing

and a log file named `logtest.log` on disk.

Problem

I must really be missing something obvious, but I'm having trouble with general use of Log4r in my Ruby application. I am able to log without issue, but the overhead seems clunky the way I have it setup. I'm basically passing the full path to a filename to log in each class in my application. The ruby script that is called pulls the log file from one of the arguments in ARGV which is then passed around and set in each class that I call in ruby. In each class I use the patternFormatter to insert the class/file name into the log statement. Is there a better way to make this work? It feels like no matter what I think of will require something to be passed to each class in my ruby application. I could set the log file in a yaml configuration file instead, but then I would be passing around the configuration file to each class as well. Any advice? If this doesn't make sense I could try and post some more specific code samples to further explain what I mean. Thanks!

Original source