Rails 5 logstash 产生太多的日志项而不是一个

Ben*_*lte 6 logging ruby-on-rails logstash kibana

有什么方法可以自定义记录标准错误的方式?从 Rails 5 开始,logstash 收到一个致命错误作为许多错误项。Rails 4 只创建了一个项目(我喜欢它的方式)

问题似乎是,从 Rails 5 开始,中间件的log_error方法单独DebugExceptions打印回溯调用的所有行logger.fatal,而不是 Rails 4,后者在logger.fatal仅调用一次之前将所有行连接到一个字符串。

比较的:

Rails 4:debug_exceptions.rb

message = "\n#{exception.class} (#{exception.message}):\n"
message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
message << "  " << trace.join("\n  ")
logger.fatal("#{message}\n\n")
Run Code Online (Sandbox Code Playgroud)

Rails 5:debug_exceptions.rb

logger.fatal "  "
logger.fatal "#{exception.class} (#{exception.message}):"
log_array logger, exception.annoted_source_code if exception.respond_to?(:annoted_source_code)
logger.fatal "  "
log_array logger, trace
Run Code Online (Sandbox Code Playgroud)

我正在通过 UDP使用带有格式化程序的logstash-logger:json_lines

我使用的 logstash 配置非常适用于 rails 4 和其他应用程序,但不适用于 rails 5(因为它将一个错误分成几个)。

我知道,我可以rescue_from用来挽救控制器中的错误,但这不会捕获路由或其他方面的错误,我猜?

先感谢您。

Vas*_*fed 2

实际上,对于错误处理,使用专用的异常跟踪解决方案(例如 rollbar、airbrake、sentry、errbit 或类似解决方案)会更方便。要点在于,对于例外情况,您需要:

  1. 一种快速查明发生位置和条件的方法,包括请求参数、用户 ID、标头等。默认情况下,并非所有这些都会写入日志。但大多数异常捕获器还会记录有关请求的附加信息。
  2. 警报,但不要太吵,因为当生产中出现问题时 - 您很快就会有数百个记录的错误,并且您不能简单地将所有这些错误转发到您的电子邮件或即时消息。所以必须支持聚合
  3. 可选,但有用 - 跟踪未解决/已解决的错误

很难在原始日志中导航异常,即使它们已被标记和索引,也可能存在这样的情况:您有一个嘈杂的非任务关键型异常,它会淹没日志,并使您错过一些罕见的真正重要的异常。

至于捕获 Rails 中的异常 - 最好在中间件中执行,就像上面提到的所有工具(以及 Rails 本身)所做的那样:

class MyExceptionMidleware
  def initialize(app)
    @app = app
  end

  def call(env)
    @app.call(env)
  rescue => e
    # handle the error any way you like, for example:
    Rails.logger.fatal("oops, #{e.inspect}, backtrace: #{e.backtrace.join("\n")}")
  end
end
Run Code Online (Sandbox Code Playgroud)
config.middleware.insert_after(ActionDispatch::DebugExceptions, MyExceptionMidleware)
Run Code Online (Sandbox Code Playgroud)

(或者insert_before,但是这样,如果您不重新引发异常,或者如果它发生在中间件本身中,则不会记录异常,不推荐)