How to log user_name in Rails?

后端 未结 12 1644
遇见更好的自我
遇见更好的自我 2020-12-15 06:52

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         


        
相关标签:
12条回答
  • 2020-12-15 07:27

    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}"
      }
    ]
    
    0 讨论(0)
  • 2020-12-15 07:35

    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.

    0 讨论(0)
  • 2020-12-15 07:42

    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'; }
    
    0 讨论(0)
  • 2020-12-15 07:43

    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.

    0 讨论(0)
  • 2020-12-15 07:44

    Added 2013-03-07:

    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

    Previous version:

    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.

    0 讨论(0)
  • 2020-12-15 07:45

    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 ...
    
    0 讨论(0)
提交回复
热议问题