2

我想将调用记录器方法的方法的名称插入到我的日志文件中。不是整个堆栈跟踪,但类、方法和/或行号会很棒。

在任何方法中,都可以使用caller获取字符串数组,每个字符串包含文件、行号和方法名称。我使用正则表达式想出了一个非常糟糕的组合,并Enumerable#find尝试返回第一个非记录器堆栈帧。我想它可以工作,但是如果日志记录 Ruby 文件的位置在不同版本或 Rails 中发生更改,或者我将我的文件命名为与日志有关的名称,它就会中断。与如果我从堆栈顶部获取给定索引相同(我一开始这样做,然后重构了一件事,自然它给了我错误的框架)。

请注意,我不希望只记录控制器或操作,因为它们可以轻松检索。这主要用于lib/目录中的内容。

没有简单的方法可以做到这一点吗?我不想__method__每次做日志记录时都必须传入。

4

2 回答 2

3

我已经查看了不同的解决方案来捕获我从我的 rails 应用程序中调用任何给定记录器实例方法的确切位置(文件、行号、方法名称)。为此,您需要覆盖 Logger 的 format_message 方法,而这样做的好地方是在您的 rails 项目config/environment.rb文件中。

这就是我想出的,这对我来说已经足够了;o)

class Logger
  def format_message(severity, timestamp, progname, msg)
    line = ''
    Kernel.caller.each{|entry|
      if (entry.include? Rails.root.to_s)
        line = " #{entry.gsub(Rails.root.to_s,'').gsub(/\/(.+)\:in `(.+)'/, "\\1 -> \\2")}"
        break
      end
    }
    "[#{timestamp.strftime("%Y%m%d.%H:%M:%S")}] #{severity}#{line}: #{msg}\n"
  end
end

Kernel.caller包含整个回溯的可枚举数组。如果您完整地查看它,您会发现大多数调用都位于项目之外某个地方的 gem 内部。我发现通过循环Kernel.caller直到找到包含 my 的第一个位置Rails.root,我可以获得包含我想要解析的信息的行。

示例:如果我Rails.logger.debug("Streamer class started!")从 Streamer 类的 start 方法调用,原始条目将如下所示:

/Users/chikoon/www/my_rails_app/lib/streamer.rb:7:in `start'

所以当它通过我的格式化程序时,我已经得到了时间戳、严重性模式、文件路径、行号、方法名称和消息:

[20140919.19:23:44] DEBUG lib/streamer.rb:7 -> start: Streamer class started!

我希望这有助于让你的车轮转动。

于 2014-09-19T18:07:39.923 回答
0

如何设置 log_tags 来调用__method__

Blog::Application.configure do
  config.log_tags = [lambda { |req| __method__ }]
end
于 2013-09-13T06:24:14.360 回答