Rails:记录异常的整个堆栈跟踪

Moi*_*aja 105 ruby ruby-on-rails

我一直在试图找出记录堆栈跟踪的正确方法.我遇到了这个链接,声明logger.error $!,$ !. backtrace是要走的路,但这对我来说不起作用log_error.根据文档,我没有看到如何将第二个参数传递给error方法仍然可行,因为rails使用的ruby logger只接受一个参数.

奇怪的(或可能不是)第二个论点在没有任何翻译投诉的情况下被接受.但是,我传递给它的任何内容都会被忽略.

谁能解释我错过的东西?任何洞察错误的第二个论点是什么以及吃什么?

小智 196

如果你在ActiveSupport中查看BufferedLogger类的源代码,你会发现第二个参数是'progname'.仅当第一个参数为nil并且您没有给出任何块或块返回非真值时才使用它.

实质上,您不能使用第二个参数来输出其他内容.

你想做的是更类似于:

begin
  raise
rescue => e
  logger.error e.message
  logger.error e.backtrace.join("\n")
end
Run Code Online (Sandbox Code Playgroud)

根据您的日志设置方式,最好迭代回溯的每一行并单独打印,因为某些记录器不输出换行符,在这种情况下,您可以执行以下操作:

begin
  raise
rescue => e
  logger.error e.message
  e.backtrace.each { |line| logger.error line }
end
Run Code Online (Sandbox Code Playgroud)

  • 您可能会将邮件拆分并且不可读,因为多次调用记录器不是线程安全的.虽然记录器本身是线程安全的.通常我在一个字符串中加入我的消息然后记录它. (11认同)
  • 难道你不会使用`$ /`来实现跨平台兼容吗?让Ruby来处理它,因为`\ r \n`只针对几个平台. (9认同)
  • 我会加入"\ r \n"来维护跨平台兼容性. (5认同)

kub*_*oon 14

这就是答案.

begin
  raise
rescue => e
  logger.error ([e.message]+e.backtrace).join($/)
end
Run Code Online (Sandbox Code Playgroud)

  • 更少的标点符号:`Rails.logger.error [e.message,* e.backtrace] .join($ /)` (3认同)

Ale*_*oVD 6

根据 kuboon 的回答,我发现这种日志记录格式是通用的,对于对日志文件中的错误进行分类很有用:

begin
  raise
rescue StandardError => e
  Rails.logger.error (["#{self.class} - #{e.class}: #{e.message}"]+e.backtrace).join("\n")
end
Run Code Online (Sandbox Code Playgroud)