使用Rails 3.2进行日志记录时,如何记录日志语句发生的文件名和行号?

时间:2014-04-28 10:50:23

标签: ruby-on-rails logging ruby-on-rails-3.2

使用Rails 3.2进行日志记录时,我想记录日志条目所发生的文件名和行号。

所以,如果在customer.rb行的ruby脚本23内,我有一个类似的日志:

Rails.logger.debug "Debug message"

我希望日志记录如下:

[customer.rb:23] Debug message

这可能吗?

3 个答案:

答案 0 :(得分:4)

我终于找到了最好的解决方案,它也会影响我的应用程序正在使用的其他gem的日志格式如下:

  1. 打开课程Logger::SimpleFormatter并覆盖方法call。您可以在初始化文件(config/initializers)中执行此操作。
  2. 更改方法call以记录caller[5]
  3. 中的文件和行

    以下是一个适用于我的示例实现:

    class Logger::SimpleFormatter
      def call(severity, time, progname, msg)
        call_details = Kernel.caller[5].gsub(/#{Rails.root}/, '')
        call_details.match /(.+):(.+):/
        filename = $1
        line = $2
        length = 40
        filename = "#{filename[-length, filename.length]}" if filename.length >= length
        filename = filename.rjust(length + 2, '.')
        "[#{severity} #{time} #{filename}:#{line}] #{msg}\n"
      end
    end
    

    在上面的解决方案中,我还将文件名限制为最后40个字符,以避免打印大文件路径。

答案 1 :(得分:1)

当然最简单的解决方案是在代码中使用__LINE__和__FILE__ 作为邮件的一部分,但我认为您要更改记录器的格式选项。我不知道在Logger格式化程序中直接执行此操作,但是,如果您想使用某些自定义规则过滤日志,则Active Upport中的 TaggedLogging 有助于完成使用子域,请求ID和其他任何内容标记日志行以帮助调试此类应用程序。您可以使用__FILE__和__LINE__变量代替标签 这是一个例子:

logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
logger.tagged("BCX") { logger.info "Stuff" }                            # Logs "[BCX] Stuff"
logger.tagged("BCX", "Jason") { logger.info "Stuff" }                   # Logs "[BCX] [Jason] Stuff"
logger.tagged("BCX") { logger.tagged("Jason") { logger.info "Stuff" } } # Logs "[BCX [Jason] Stuff

我还建议改变格式化程序,如下例所示:

Log = Logger.new(STDOUT)
  Log.formatter = proc { |severity, datetime, progname, msg|
    "#{severity} #{caller[4]} #{msg}\n"
  }

现在,每当您拨打Log.INFO('某些消息')时,您应该拥有'来电者的文件和行号。日志方法

答案 2 :(得分:1)

我只想在config/environments/....rb中的环境配置中添加以下行:

config.log_formatter = proc { |severity, datetime, progname, msg|
  callee = caller[5]                         # get caller from stack
  callee = callee.split('/').last            # remove path from callee info
  callee = callee.split(':')[0, 2].join(':') # remove method name from info

  "[#{callee}] #{msg}\n"
}

这取决于您的Rails版本,您可以在caller堆栈中找到正确的文件和行号。较新版本的Rails似乎有caller[5]的信息,其他版本可能在其他位置有。

我看到的问题:拥有文件的名称真的有用吗?如何处理来自Rails本身的日志消息?如何测试这一点以确保堆栈跟踪中的位置在以后的Rails版本中保持正确?

文件名和行号是否真的是默认的记录器格式?我不这么认为。

相关问题