我们有代码在Ruby 1.8.6 Web应用程序中记录数据.你大致如下调用它:
$log.info("Some text here")
Run Code Online (Sandbox Code Playgroud)
现在,在记录的输出中,我想要包含出现该行的模块.我知道Kernel#caller会给我一个数组,我可以提取日志行发生的文件和行号,但我不希望这样.我想要模块,而不是文件名.显而易见的解决方案是修改日志行,使其如下所示:
$log.info("Some text here", self.class.name)
Run Code Online (Sandbox Code Playgroud)
然后解析结果.但是,这不会起作用,因为我试图在默认情况下提取此信息.也就是说,如果程序员忘记指定模块,那么我需要解决方案才能工作,这是日志行的第二个参数.
有没有办法做到这一点?如果没有,我将只需要处理caller数组; 我们的大多数模块都在不同的目录中,因此这将是一个80%的解决方案.
更完整的示例,请原谅轻微的语法错误:
在文件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
Run Code Online (Sandbox Code Playgroud)
在文件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
Run Code Online (Sandbox Code Playgroud)
使用call_stack。
首先使用 RubyGems 安装它:
gem install call_stack
Run Code Online (Sandbox Code Playgroud)
然后将log.rb更改为:
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
Run Code Online (Sandbox Code Playgroud)
对我有用(Ruby 1.8.7)。
$ ruby foo.rb
Module: Foo::Bar Msg: I did something!
Run Code Online (Sandbox Code Playgroud)