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 ...