我想改进我的应用程序的日志记录。我使用带有 request_id 的标记日志记录。基本上这是生产环境的 Rails 标准。
我想知道 sidekiq、actionmailer 和 activejob 的日志行来自哪里。
我使用 Rails Semantic Logger 来获取结构化日志。
对于 sidekiq,我发现使用了由 Rails 语义记录器拾取的作业标签,并且现在正在记录这些标签,这有助于识别属于一起的日志行。
这看起来如下
21:15:30 worker.1 | 2024-10-22 21:15:30.273383 I [71200:sidekiq.default/processor] {jid: 32abadde984a6b6c5a95e1ed, tags: ["my-request-id"], queue: default} (44.6ms) AppointmentCompletionMissingReminderJob -- Completed #perform
这可能不是最好的解决方案,但至少它可以完成工作。
现在我也想在由actionmailer和activejob创建的日志中包含请求id。假设使用自定义交付作业而不是默认的
ActionMailer::MailDeliveryJob
,可以将问题隔离到 activejob。
目前我的日志如下:
21:06:52 web.1 | 2024-10-22 21:06:52.433809 I [71197:worker-1] [ActionMailer::MailDeliveryJob] [3821d8b0-d6fe-4f12-8e6a-a5c3d152d2e1] Rails -- Performing ActionMailer::MailDeliveryJob (Job ID: 3821d8b0-d6fe-4f12-8e6a-a5c3d152d2e1) to Async(high) -- { :event_name => "perform_start.active_job", :adapter => "Async", :queue => "high", :job_class => "ActionMailer::MailDeliveryJob", :job_id => "3821d8b0-d6fe-4f12-8e6a-a5c3d152d2e1", :provider_job_id => "fcab8cb1-e661-4821-916a-695e5e42e70f", :arguments => "[\n \"UserMailer\",\n \"magic_link\",\n \"deliver_now\",\n {\n \"params\": {\n \"user\": \"gid://xxx/User/1\",\n \"redirect_path\": \"\"\n },\n \"args\": [\n\n ]\n }\n]" }
21:06:52 web.1 | 2024-10-22 21:06:52.434135 D [71197:worker-1] [ActionMailer::MailDeliveryJob] [3821d8b0-d6fe-4f12-8e6a-a5c3d152d2e1] UserMailer -- Sending magic link to user
21:06:52 web.1 | 2024-10-22 21:06:52.446786 D [71197:worker-1] [ActionMailer::MailDeliveryJob] [3821d8b0-d6fe-4f12-8e6a-a5c3d152d2e1] ActionView -- Rendering layout -- { :template => "layouts/mailer.haml" }
21:06:52 web.1 | 2024-10-22 21:06:52.446812 D [71197:worker-1] [ActionMailer::MailDeliveryJob] [3821d8b0-d6fe-4f12-8e6a-a5c3d152d2e1] ActionView -- Rendering -- { :template => "user_mailer/magic_link.html.erb" }
21:06:52 web.1 | 2024-10-22 21:06:52.470154 D [71197:worker-1] [ActionMailer::MailDeliveryJob] [3821d8b0-d6fe-4f12-8e6a-a5c3d152d2e1] (23.3ms) ActionView -- Rendered -- { :template => "user_mailer/magic_link.html.erb", :within => "layouts/mailer", :allocations => 33255 }
21:06:52 web.1 | 2024-10-22 21:06:52.472222 I [71197:worker-1] [ActionMailer::MailDeliveryJob] [3821d8b0-d6fe-4f12-8e6a-a5c3d152d2e1] ActionMailer::Base -- UserMailer#magic_link: processed outbound mail in 38.1ms -- { :event_name => "process.action_mailer", :mailer => "UserMailer", :action => :magic_link, :message_id => nil, :perform_deliveries => nil, :subject => nil, :to => nil, :from => nil, :bcc => nil, :cc => nil, :date => nil, :args => nil }
其中
3821d8b0-d6fe-4f12-8e6a-a5c3d152d2e1
是 activejob 创建的作业 ID。我想要另一个包含请求 ID 的日志标签。
我在应用程序中的任何地方都使用
ActiveSupport::CurrentAttributes
为其提供 Current.request_id
。
问题是,如何在创建作业时将请求 ID 注入到作业中,例如在我的登录控制器中?
结果应该是这样的:
21:06:52 web.1 | 2024-10-22 21:06:52.433809 I [71197:worker-1] [ActionMailer::MailDeliveryJob] [3821d8b0-d6fe-4f12-8e6a-a5c3d152d2e1] [my-request-id] Rails ...
21:06:52 web.1 | 2024-10-22 21:06:52.434135 D [71197:worker-1] [ActionMailer::MailDeliveryJob] [3821d8b0-d6fe-4f12-8e6a-a5c3d152d2e1] [my-request-id] UserMailer ...
21:06:52 web.1 | 2024-10-22 21:06:52.446786 D [71197:worker-1] [ActionMailer::MailDeliveryJob] [3821d8b0-d6fe-4f12-8e6a-a5c3d152d2e1] [my-request-id] ActionView ...
21:06:52 web.1 | 2024-10-22 21:06:52.446812 D [71197:worker-1] [ActionMailer::MailDeliveryJob] [3821d8b0-d6fe-4f12-8e6a-a5c3d152d2e1] [my-request-id] ActionView ...
21:06:52 web.1 | 2024-10-22 21:06:52.470154 D [71197:worker-1] [ActionMailer::MailDeliveryJob] [3821d8b0-d6fe-4f12-8e6a-a5c3d152d2e1] [my-request-id] (23.3ms) ActionView ...
21:06:52 web.1 | 2024-10-22 21:06:52.472222 I [71197:worker-1] [ActionMailer::MailDeliveryJob] [3821d8b0-d6fe-4f12-8e6a-a5c3d152d2e1] [my-request-id] ActionMailer::Base ...
Rails 提供了 RequestId 中间件,它会自动为每个请求分配唯一的请求 ID。这可以通过控制器中的 request.request_id 访问,但您需要将其显式传递给后台作业进行日志记录。
具体操作方法如下: 一个。将请求 ID 传递给 ActiveJob:
您可以将请求 ID 作为作业参数的一部分传递:
class SomeJob < ApplicationJob
queue_as :default
def perform(*args, request_id)
# Add the request_id to the logs using tagged logging
Rails.logger.tagged("RequestId: #{request_id}") do
# Your job code here
end
end
end