使用Rails 3.2进行日志记录时,我想记录日志条目所发生的文件名和行号。
所以,如果在customer.rb
行的ruby脚本23
内,我有一个类似的日志:
Rails.logger.debug "Debug message"
我希望日志记录如下:
[customer.rb:23] Debug message
这可能吗?
答案 0 :(得分:4)
我终于找到了最好的解决方案,它也会影响我的应用程序正在使用的其他gem的日志格式如下:
Logger::SimpleFormatter
并覆盖方法call
。您可以在初始化文件(config/initializers
)中执行此操作。call
以记录caller[5]
。以下是一个适用于我的示例实现:
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版本中保持正确?
文件名和行号是否真的是默认的记录器格式?我不这么认为。