I need a unique request ID for my logger, so I can track each request in the log file.
我的记录器需要一个唯一的请求ID,因此我可以跟踪日志文件中的每个请求。
So far I got this
到目前为止我得到了这个
REQUEST_ID = Digest::MD5.hexdigest(Time.now.to_f.to_s + $PID.to_s)
The problem is that I don't know where to put this. I tried placing it inside my custom logger file, outside the class. But it must be being cached or something because I'm always getting the same hash.
问题是我不知道在哪里放这个。我尝试将它放在我的自定义记录器文件中,在类外面。但它必须被缓存或其他东西,因为我总是得到相同的哈希。
Any ideas?
有任何想法吗?
note. I'm using Rails 3 and Passenger standalone
注意。我正在使用Rails 3和Passenger独立版
UPDATE:
更新:
Rails 3.2 :uuid tag won't work. Look how badly formatted the logs are:
Rails 3.2:uuid标签不起作用。看看日志的格式是多么糟糕:
[0909413851b79676cb06e0842d21c466] [127.0.0.1]
Started HEAD "/" for 127.0.0.1 at Tue Feb 21 14:08:25 -0300 2012
[0909413851b79676cb06e0842d21c466] [127.0.0.1] Processing by PagesController#home as HTML
[0909413851b79676cb06e0842d21c466] [127.0.0.1] bla
[0909413851b79676cb06e0842d21c466] [127.0.0.1] Rendered pages/home.html.erb within layouts/application (2.0ms)
In production this will be a mess. Notice the newlines after the first line? Now imagine how the logs would look like in a server handling many requests per second. It will be hard to associate a request with a URI
在生产中,这将是一个烂摊子。请注意第一行之后的换行符?现在想象一下在每秒处理许多请求的服务器中日志的样子。将请求与URI关联起来很困难
3 个解决方案
#1
4
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:
如果要在2012年2月21日星期二14:00:00 -0300的日志行开始GET“/”为127.0.0.1插入请求UUID,您可以修补或子类Rails :: Rack :: Logger来修改call_app方法:
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
.
请求对象在日志记录语句之前创建,因此您可以更改logging语句以包含request.uuid。
#2
34
Rails core team took care of it for you!
Rails核心团队为您服务!
Rails 3.2 introduces request.uuid
method, which returns, um, unique request identifier, which looks like this: ab939dfca5d57843ea4c695cab6f721d
.
Rails 3.2引入了request.uuid方法,该方法返回唯一的请求标识符,如下所示: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]
#3
5
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.
使用log_tags对答案进行后续跟踪,因为:uuid在请求中仅是唯一的,因此很难将其与会话跟踪一起使用。
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)
我发现log_tags接受Proc,并将请求对象作为参数传递。因此,以下代码将使用session_id标记所有日志条目(假设您正在使用基于ActiveRecord的会话存储)
config.log_tags = [ lambda {|req| "#{req.cookie_jar["_session_id"]}" }, :remote_ip, :uuid ]
#1
4
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:
如果要在2012年2月21日星期二14:00:00 -0300的日志行开始GET“/”为127.0.0.1插入请求UUID,您可以修补或子类Rails :: Rack :: Logger来修改call_app方法:
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
.
请求对象在日志记录语句之前创建,因此您可以更改logging语句以包含request.uuid。
#2
34
Rails core team took care of it for you!
Rails核心团队为您服务!
Rails 3.2 introduces request.uuid
method, which returns, um, unique request identifier, which looks like this: ab939dfca5d57843ea4c695cab6f721d
.
Rails 3.2引入了request.uuid方法,该方法返回唯一的请求标识符,如下所示: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]
#3
5
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.
使用log_tags对答案进行后续跟踪,因为:uuid在请求中仅是唯一的,因此很难将其与会话跟踪一起使用。
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)
我发现log_tags接受Proc,并将请求对象作为参数传递。因此,以下代码将使用session_id标记所有日志条目(假设您正在使用基于ActiveRecord的会话存储)
config.log_tags = [ lambda {|req| "#{req.cookie_jar["_session_id"]}" }, :remote_ip, :uuid ]