如何使用请求ID标记rails中的每个日志调用(lograge)

Ben*_*Ben 7 logging json ruby-on-rails

我正在使用带有rails的lograge,我已经使用JSON格式配置了我的日志.我想我每次通话时间logger.info,logger.warn等来包括请求UUID.rails使用标记日志记录处理这种方式的方式达不到我想要的程度,因为它似乎无法将请求uuid与JSON有效负载的其余部分合并,而是将其以非JSON格式预先添加到行上.

例如,如果我打电话,logger.info(client: :ig)我会期望以下日志输出:

{"request_id": <request uuid>, "client": "ig"}
Run Code Online (Sandbox Code Playgroud)

但是相反,rails将在请求uuid之前(当配置为via时config.log_tags = [:uuid]),如下所示:

[<request uuid>] {"client": "ig"}
Run Code Online (Sandbox Code Playgroud)

有没有人知道是否有办法让标记行为与JSON有效负载合并而不是在同一行上预先添加?我想使用一个简单的JSON格式化器将我们的日志配置为转发到Splunk,而不是处理这种前置格式.

另外,我已经配置lograge到包括request_id设置为在传送到一个lambda请求UUID custom_optionsconfig/application.rb.这只有在rails记录请求时才有效.如果我在其他任何地方显式调用其中一个日志记录方法,request_id则不包括在内.

# application.rb
config.lograge.enabled = true
config.lograge.formatter = Lograge::Formatters::Json.new
config.lograge.custom_options = lambda do |e|
  {
    params: e.payload[:params].except("controller", "action", "utf8"),
    request_id: e.payload[:request_id] # added this in `append_info_to_payload` in ApplicationController
  }
end
Run Code Online (Sandbox Code Playgroud)

然后在config/environments/production.rb中

config.log_tags = [ -> (req) { { request_id: req.env["action_dispatch.request_id"] } } ]
Run Code Online (Sandbox Code Playgroud)

任何帮助表示赞赏,谢谢.

小智 1

问题是有效负载没有 request_id。正如您在以下内容中看到的:

./actionpack-3.2.11/lib/action_controller/metal/instrumentation.rb:18-25

raw_payload = {
    :controller => self.class.name,
    :action     => self.action_name,
    :params     => request.filtered_parameters,
    :format     => request.format.try(:ref),
    :method     => request.method,
    :path       => (request.fullpath rescue "unknown")
  }
Run Code Online (Sandbox Code Playgroud)

我重写此方法(在 config/initializer.rb 中复制 ./actionpack-3.2.11/lib/action_controller/metal/instrumentation.rb)并添加您的参数。

raw_payload = {
    :controller => self.class.name,
    :action     => self.action_name,
    :params     => request.filtered_parameters,
    :format     => request.format.try(:ref),
    :method     => request.method,
    :path       => (request.fullpath rescue "unknown"),
    :request_id => env["action_dispatch.request_id"]
  }
Run Code Online (Sandbox Code Playgroud)

也许有更好的方法来覆盖检测,但这已经足够了。