I use Devise in Rails 3. I want to see name of current_user in production.log.
I would like to configure rails like this:
config.log_tags = [:user_na
What almost worked for me (Rails 3.2.22.2) is the answer from here: http://benjit.com/rails/logger/2016/02/26/getting-admin-user-into-rails-logfile/
This assumes that the cookie_jar object responds to encrypted. However it wasn't the case for me. What ultimately worked for me is as follows:
config/initializers/logging.rb:
Rails.configuration.log_tags = [
lambda { |req|
session_key = Rails.application.config.session_options[:key]
session_data = req.cookie_jar.signed[Rails.application.config.session_options[:key] ]
warden_data = ( session_data["warden.user.user.key"]|| [[]])
admin_user = warden_data[0][0]
"u: #{admin_user || 0}"
}
]
For anyone using Redis::Store @fjuillen's answer looks like this:
redis = Redis::Store.new
redis.select 3 # only if you use a different database
result = redis.get req.cookie_jar["_session_id"]
tested on rails 4.
Unfortunately log tags are evaluated only once at the very beginning of request delegation (in Rails::Rack::Logger middleware). At this stage there is no controller so any current_user helper is not yet available. No warden or even session set up yet, but there is a cookiejar at least, so if you store your session_id there you could restore the session or log session_id instead directly.
config.log_tags = [ lambda { |req| req.cookie_jar["_session_id"].to_s } ]
I think the best alternative is to store username in the cookie directly at log_in, and destroy it with the session.
config.log_tags = [ lambda { |req| req.cookie_jar["user_name"] || 'Noone' } ]
NOT WORKING:
But if you use devise, it uses warden raack middleware, so env['warden'] should be available, so can you try?
config.log_tags = [ lambda { |req| user = req.env['warden'].user; user && user.name || 'Noone'; } ]
Even without warden, since you do have session available via env['rack.session'], if you store user id in session, you can do something like
config.log_tags = [ lambda { |req| user = User.find_by_id(req.env['rack.session']['user_id']); user && user.name || 'Noone'; }
And Now for Something Completely Different...
https://github.com/roidrage/lograge/issues/23#issuecomment-11709861
I just tried this with Rails 4, latest Devise and Lograge.
In Rails 4 encrypted_cookie_store is the default session store. This is how you can access session data:
session_data = req.cookie_jar.signed[ "_qnaire_session" ]
And it looks like warden_data looks differently in my new app, e.g.: [[542], "$2a$10$e5aYxr/PIp6OOj8jzE7mke"], where first item is user id.
Here's my current snippet: https://gist.github.com/wojt-eu/5109643
This is what I came up with:
config.log_tags = [
:remote_ip,
->(req){
session_data = req.cookie_jar.signed[ "_qnaire_session" ]
warden_data = session_data["warden.user.provider_user.key"]
if warden_data
'#' + warden_data[1][0].to_s
else
"guest"
end
}
]
_qnaire_session can be replaced with instance.config.session_options[:key] or via singleton: Rails.application.config.session_options[:key]
I have ProviderUser model, hence warden.user.provider_user.key. I suppose with User model this would be warden.user.user.key.
It's messy, but it does not affect normal authentication process, middleware stack order etc. If it breaks during some update only tagging logs will be affected, which I should quickly notice while looking at development logs.
I found this little tricky but working solution.
Warden stores user information in session, but req.session is not available for logging.
So you must add this to config/application.rb
config.middleware.delete(ActionDispatch::Cookies)
config.middleware.delete(ActionDispatch::Session::CookieStore)
config.middleware.insert_before(Rails::Rack::Logger, ActionDispatch::Session::CookieStore)
config.middleware.insert_before(ActionDispatch::Session::CookieStore, ActionDispatch::Cookies)
Then create file config/initializers/logging.rb
Rails.configuration.log_tags = [
proc do |req|
if req.session["warden.user.user.key"].nil?
"Anonym"
else
"user_id:#{req.session["warden.user.user.key"][0][0]}"
end
end
]
Now I see this for Anonymous:
[Anonym] Served asset ...
and this for user:
[user_id:1] Served asset ...