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.
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
.
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]
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 ]