我的想法是捕获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的会话存储正在使用中
好了,我终于想通了。
-
我将
ActionDispatch::Cookies
和ActionDispatch::Session::CookieStore
移动到机架堆栈的更早位置。这看起来是安全的,并且是必要的,否则在会话初始化之前会发生一些日志记录。 -
我添加了自己的机架中间件组件,该组件在线程本地存储中设置
session_id
。 -
我覆盖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