如何为每个日志消息添加会话id (Rails 3)



我的想法是捕获session_id并将其存储在线程本地存储中,例如

Thread.current[:session_id] = session[:session_id]

但是一些rails日志记录发生在我的过滤器被调用之前。

我想我可以通过编写中间件插件来捕获session_id。但是,我似乎没有得到足够早的所有日志。

我最早可以捕获session_id是什么时候?

谢谢!

由于Rails 3.2支持使用log_tags配置数组标记日志,log_tags数组接受Proc对象,并且Proc对象被请求对象调用,我可以配置log_tags如下方式:

config.log_tags = [ :uuid, :remote_ip,
                    lambda {|req| "#{req.cookie_jar["_session_id"]}" } ]

它与Rails 3.2.3一起工作,ActiveRecord的会话存储正在使用中

好了,我终于想通了。

  1. 我将ActionDispatch::CookiesActionDispatch::Session::CookieStore移动到机架堆栈的更早位置。这看起来是安全的,并且是必要的,否则在会话初始化之前会发生一些日志记录。

  2. 我添加了自己的机架中间件组件,该组件在线程本地存储中设置session_id

  3. 我覆盖rails记录器并在每个日志消息前添加session_id

这对于能够分离和分析特定用户会话的所有日志非常有帮助。

我很想知道其他人是怎么做到的。

基于@Felix的答案。我已经在rails 4中完成了这些:

# config/application.rb
config.middleware.delete "ActionDispatch::Cookies"
config.middleware.delete "ActionDispatch::Session::CookieStore"
config.middleware.insert_before Rails::Rack::Logger, ActionDispatch::Cookies
config.middleware.insert_before Rails::Rack::Logger, ActionDispatch::Session::CookieStore
# config/environment/development.rb and production.rb
config.log_tags = [
  lambda {|req| "#{req.subdomain}/#{req.session["user_id"]}" },
  :uuid
]
config.log_formatter = Logger::Formatter.new

生成如下日志:

I, [2015-11-05T15:45:42.617759 #22056]  INFO -- : [verimor/2] [77e593dc-c852-4102-a999-5c90ea0c9d66] Started GET "/home/dashboard" for 192.168.1.37 at 2015-11-05 15:45:42 +0200

[verimor/2]subdomain/user_id(这是一个多租户应用)。

[77e593dc-c852-4102-a999-5c90ea0c9d66]是此请求的唯一id。用于跟踪请求的生命周期。

HTH .

对于Rails 3.2与ActiveSupport::TaggedLogging,如果你正在使用:cookie_store:

config.log_tags = [ :uuid, :remote_ip, 
                    lambda { |r| "#{r.cookie_jar.signed["_session_id"]["session_id"]}" } ]

注意:改变"_session_id"与你的:key值在config/initializers/session_store.rb

相关:https://stackoverflow.com/a/22487360/117382

最新更新