我的记录器需要一个唯一的请求ID,因此我可以跟踪日志文件中的每个请求。
到目前为止我得到了这个
REQUEST_ID = Digest::MD5.hexdigest(Time.now.to_f.to_s + $PID.to_s)
问题在于我不知道在哪里放这个。我尝试将它放在我的自定义记录器文件中,在课外。但它必须被缓存或其他东西,因为我总是得到相同的哈希。
有什么想法吗?
请注意。我正在使用Rails 3和Passenger独立
更新
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)
在制作中,这将是一团糟。请注意第一行之后的换行符?现在想象一下在每秒处理许多请求的服务器中日志的样子。将请求与URI
关联起来很困难答案 0 :(得分:35)
Rails核心团队为您服务!
Rails 3.2引入了request.uuid
方法,该方法返回唯一的请求标识符,如下所示:ab939dfca5d57843ea4c695cab6f721d
。
另请查看at this awesome screencast以了解如何将此新方法用于记录。
# 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]
答案 1 :(得分:6)
使用log_tags
对答案进行后续跟踪,因为:uuid在请求中只是唯一的,很难将其用于会话跟踪。
我发现log_tags接受Proc,并将请求对象作为参数传递。因此,以下代码将使用session_id标记所有日志条目(假设您使用的是基于ActiveRecord的会话存储)
config.log_tags = [ lambda {|req| "#{req.cookie_jar["_session_id"]}" }, :remote_ip, :uuid ]
答案 2 :(得分:5)
如果要在日志行Started GET "/" for 127.0.0.1 at Tue Feb 21 14:00:00 -0300 2012
插入请求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
请求对象是在日志记录语句之前创建的,因此您可以将日志记录语句更改为包含request.uuid
。