How to generate a unique request ID in Rails?

后端 未结 3 493
一个人的身影
一个人的身影 2021-01-11 10:16

I need a unique request ID for my logger, so I can track each request in the log file.

So far I got this

REQUEST_ID = Digest::MD5.hexdigest(Time.now.         


        
相关标签:
3条回答
  • 2021-01-11 10:40

    If you want to insert the request UUID at the log line Started GET "/" for 127.0.0.1 at Tue Feb 21 14:00:00 -0300 2012, you can patch or subclass Rails::Rack::Logger to modify the call_app method:

    def call_app(env)
      request = ActionDispatch::Request.new(env)
      path = request.filtered_path
      Rails.logger.info "\n\nStarted #{request.request_method} \"#{path}\" for #{request.ip} at #{Time.now.to_default_s}"
      @app.call(env)
    ensure
      ActiveSupport::LogSubscriber.flush_all!
    end
    

    The request object is created right before the logging statement, so you can change the logging statement to include request.uuid.

    0 讨论(0)
  • 2021-01-11 10:45

    Rails core team took care of it for you!

    Rails 3.2 introduces request.uuid method, which returns, um, unique request identifier, which looks like this: ab939dfca5d57843ea4c695cab6f721d.

    See release notes here.

    Also take a look at this awesome screencast to know how to use this new method with logging.

    # config/environments/development.rb 
    config.log_tags = [:uuid, :remote_ip]
    
    
    # log file
    [ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1] 
    
    Started GET "/" for 127.0.0.1 at 2012-01-27 21:52:58 +0000
    [ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1] Processing by ProductsController#index as HTML
    [ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1]   Product Load (0.3ms)  SELECT "products".* FROM "products" 
    [ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1]   Rendered products/index.html.erb within layouts/application (22.0ms)
    [ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1] Completed 200 OK in 81ms (Views: 73.1ms | ActiveRecord: 0.3ms)
    [98eec5f8976586c1165b981797086b6a] [127.0.0.1] 
    
    0 讨论(0)
  • 2021-01-11 10:56

    Follow-up to the answer using log_tags, since :uuid is only unique among a request, it is difficult to use it with session tracking.

    I found log_tags accept a Proc, and pass a request object as an parameter. So, following code will stamp all of log entry with session_id (assuming you're using ActiveRecord based session store)

    config.log_tags = [ lambda {|req| "#{req.cookie_jar["_session_id"]}" }, :remote_ip, :uuid  ]
    
    0 讨论(0)
提交回复
热议问题