【问题标题】:Rails: Logging the entire stack trace of an exceptionRails:记录异常的整个堆栈跟踪
【发布时间】:2011-03-29 21:35:27
【问题描述】:

我一直在尝试找出记录堆栈跟踪的正确方法。我遇到了this 链接,该链接指出 logger.error $!, $!.backtrace 是可行的方法,但这对我不起作用 log_error 可以。根据文档,我看不出如何将第二个参数传递给错误方法,因为 rails 使用的 ruby​​ 记录器只接受一个参数。

奇怪的是(或者可能不是)第二个参数被接受而没有任何解释器投诉。但是,我传递给它的任何内容都会被忽略。

谁能解释我错过了什么?任何关于错误的第二个论点是什么以及它在吃什么的见解?

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    如果您查看 ActiveSupport 中 BufferedLogger 类的源代码,您会看到第二个参数是“progname”。这仅在第一个参数为 nil 并且您没有给它任何块或块返回非真值时使用。

    本质上,你不能使用第二个参数来输出额外的东西。

    你想做的是更类似于:

    begin
      raise
    rescue => e
      logger.error e.message
      logger.error e.backtrace.join("\n")
    end
    

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

    begin
      raise
    rescue => e
      logger.error e.message
      e.backtrace.each { |line| logger.error line }
    end
    

    【讨论】:

    • 我会加入使用 "\r\n" 以保持跨平台兼容性。
    • 你不会使用$/ 来实现跨平台兼容吗?让 Ruby 来处理它,因为 \r\n 仅特定于少数平台。
    • 您的消息可能会被拆分且无法读取,因为多次调用 logger 不是线程安全的。虽然记录器本身是线程安全的。通常我会在一个字符串中加入我的消息然后记录它。
    • 当时 logger 似乎不支持日志条目中的换行符,因此拆分但是是的,你是对的,你应该知道这种方法的局限性
    • +1 @JackWatson 绝对奇怪的答案,因为它是非线程安全的。这很重要,因为我们在这里讨论的是网络应用
    【解决方案2】:

    这就是答案。

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

    【讨论】:

    • 少标点:Rails.logger.error [e.message, *e.backtrace].join($/)
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-21
      • 1970-01-01
      • 2011-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多