Alex Rivera | Logout

How to log user_name in Rails?

Asked 2012-05-30T06:58:08.997
19

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_name]
Edit
Report

2 Answers

3

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'; }
answered 2012-05-30T09:01:19.370
1

As @viktortron has said in his answer at log_tags initialization time we have not a proper session objet available, but the session_id is in the request.

If you are using a _database session_store_, as it is my case, you can rebuild the session ad-hoc:

session = ActiveRecord::SessionStore::Session.find_by_session_id(request.cookie_jar["_session_id"])

This is how my log_tags are defined:

# config/initializers/rails_log.rb
def get_user_id(req)
  session = ActiveRecord::SessionStore::Session.find_by_session_id(req.cookie_jar["_session_id"])
  result = session ? session.data["user_id"] : 0

  "%07d" % result
end

log_tags = []
log_tags << lambda { |req| Time.now.strftime("%F %T.%L") }
log_tags << lambda { |req| req.uuid.first(8) }
log_tags << lambda { |req| get_user_id(req) }

Rails.configuration.log_tags = log_tags

The result is something like:

[2013-01-22 13:51:36.659] [e52435d1] [0036484] <the log line>
answered 2013-01-22T13:00:26.523

Your Answer