如何在Rails中记录user_name?

bob*_*lin 14 logging ruby-on-rails devise

我在Rails 3中使用Devise.我想在production.log中看到current_user的名称.

我想像这样配置rails:

config.log_tags = [:user_name]
Run Code Online (Sandbox Code Playgroud)

bob*_*lin 21

我发现这个小巧但有效的解决方案.

Warden在会话中存储用户信息,但req.session不可用于记录.

所以你必须将它添加到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)
Run Code Online (Sandbox Code Playgroud)

然后创建文件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
]
Run Code Online (Sandbox Code Playgroud)

现在我看到匿名:

[Anonym] Served asset ...
Run Code Online (Sandbox Code Playgroud)

这对用户来说:

[user_id:1] Served asset ...
Run Code Online (Sandbox Code Playgroud)


Mar*_*rom 14

我使用了Wojtek Kruszewski的这个解决方案:https://gist.github.com/WojtekKruszewski

我为我的项目调整了一点,只包括id,但基本相同.

# config/application.rb

config.log_tags = [
  ->(req){
    if user_id = WardenTaggedLogger.extract_user_id_from_request(req)
      user_id.to_s
    else
      "?"
    end
  }
]
Run Code Online (Sandbox Code Playgroud)

并创建此初始化程序

# initializers/warden_tagged_logger.rb

module WardenTaggedLogger
  def self.extract_user_id_from_request(req)
    session_key = Rails.application.config.session_options[:key]
    session_data = req.cookie_jar.encrypted[session_key]
    warden_data = session_data["warden.user.user.key"]
    warden_data[0][0]
    rescue
      nil
  end
end
Run Code Online (Sandbox Code Playgroud)


Woj*_*ski 5

新增2013-03-07:

在Rails 4中,encrypted_cookie_store是默认的会话存储.这是您访问会话数据的方法:

session_data = req.cookie_jar.signed[ "_qnaire_session" ]
Run Code Online (Sandbox Code Playgroud)

看起来warden_data在我的新应用中看起来不同,例如:[[542], "$2a$10$e5aYxr/PIp6OOj8jzE7mke"],其中第一项是用户ID.

这是我目前的片段:https://gist.github.com/wojt-eu/5109643

以前的版本:

这就是我想出的:

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
  }
]
Run Code Online (Sandbox Code Playgroud)

_qnaire_session可以替换为instance.config.session_options[:key]或通过单身:Rails.application.config.session_options[:key]

因此,我有ProviderUser模型warden.user.provider_user.key.我想用User模型就可以了warden.user.user.key.

这很麻烦,但它不会影响正常的身份验证过程,中间件堆栈顺序等.如果它在某些更新期间中断,则只会影响标记日志,我应该在查看开发日志时快速注意到这一点.