Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting module of caller in Ruby

We have code to log data in our Ruby 1.8.6 web application. You call it roughly as follows:

$log.info("Some text here")

Now, in the logged output, I would like to include the module where that line appeared. I know that the Kernel#caller will give me an array where I can pull out the file and line number that the log line occurred, but I don't want that. I want the module, not the file name. The obvious solution is to modify the log line so that it reads like:

$log.info("Some text here", self.class.name)

and then parse the result. That's not going to work, though, because I am trying to extract this information in the default case. That is, I need the solution to work if the programmer forgot to specify the module, the second parameter to the log line.

Is there any way to do this? If not, I will just have to make do with the caller array; most of our modules are in separate directories, so this would be an 80% solution.

More complete example, please excuse minor syntax errors:

in file log.rb:

module Log
  class Logger
    def info(msg, mod = '')
      puts "Module: #{mod}  Msg: #{msg}"
    end
  end # class Logger
end # module Log
$log = Log::Logger.new

in file foo.rb:

module Foo
  class Bar
    def do_something
      # Do not pass in self.class.name.
      # We want the output to look like:
      # Module: Foo  Msg: I did something!
      $log.info "I did something!"
    end
  end # class Bar
end #module Foo
like image 223
ChrisInEdmonton Avatar asked Jan 06 '10 22:01

ChrisInEdmonton


1 Answers

Use call_stack.

First install it with RubyGems:

gem install call_stack

Then change log.rb to:

require 'rubygems'
require 'call_stack'

call_stack_on

module Log
  class Logger
    def info(msg, mod = '')
        mod = call_stack(2)[0][0] if mod == ''
        puts "Module: #{mod}  Msg: #{msg}"
    end
  end # class Logger
end # module Log
$log = Log::Logger.new

Works for me (Ruby 1.8.7).

$ ruby foo.rb
Module: Foo::Bar  Msg: I did something!
like image 171
Firas Assaad Avatar answered Sep 30 '22 11:09

Firas Assaad