我正在使用带有rails的lograge,我已经使用JSON格式配置了我的日志。我希望每次拨打logger.info
,logger.warn
等时都要包含请求uuid。 rails使用标记日志记录处理这种方式的方式达不到我想要的程度,因为它似乎无法将请求uuid与JSON有效负载的其余部分合并,而是将其以非JSON格式排在线上。
例如,如果我调用logger.info(client: :ig)
,我希望以下日志输出:
{"request_id": <request uuid>, "client": "ig"}
但是相反,rails会在请求uuid之前(通过config.log_tags = [:uuid]
配置时),如下所示:
[<request uuid>] {"client": "ig"}
有没有人知道是否有办法让标记行为与JSON有效负载合并而不是将它预先放在同一行上?我想使用一个简单的JSON格式化器将我们的日志配置为转发到Splunk,而不是处理这种前置格式。
此外,我已将lograge配置为在request_id
中传递给custom_options
的lambda中将config/application.rb
设置为请求uuid。这只有在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
然后在config / environments / production.rb
中config.log_tags = [ -> (req) { { request_id: req.env["action_dispatch.request_id"] } } ]
感谢任何帮助,谢谢。
答案 0 :(得分:1)
问题是有效负载没有request_id。 正如您所见:
./ ActionPack的-3.2.11 / LIB / action_controller /金属/ 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")
}
我重写此方法(在config / initializer.rb 中复制 ./ actionpack-3.2.11 / lib / action_controller / metal / instrumentation.rb)并添加PARAM。
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"]
}
也许有更好的方法来覆盖仪器,但这已经足够了。
答案 1 :(得分:0)
使用class_eval更容易覆盖初始化程序,如下所示: Access to Rails request inside ActiveSupport::LogSubscriber subclass