将用户ID预先添加到Rails中的所有日志消息

Rya*_*vre 8 ruby session logging ruby-on-rails authlogic

为了帮助跟踪用户操作以进行调试,我们正在考虑将会话的登录用户ID添加到每个日志消息(如果适用).我们的堆栈由Rails和Authlogic组成.我尝试了几条不同的路线,但到目前为止还没有100%成功.

由于Authlogic不以明文形式在会话数据中存储用户ID,因此我们必须等待它被初始化.只有在ApplicationController初始化并设置为活动的Authlogic控制器之后才会发生这种情况.因此,我们不能依赖代码config/application.rb.在我看来,唯一的解决方案是稍后更换记录器.

我试图通过继承Logger并覆盖add()方法来创建一个新的记录器类:

class UserLogger < Logger
  def add(severity, message = nil, progname = nil, &block)
    begin
      session = UserSession.find
    rescue
      return super(severity, message, progname, &block)
    end

    user = session.user if session

    if block_given? || !user
      return super(severity, message, progname, &block)
    end

    unless message.nil?
      message = "[#{user.id}] " + message
    end

    super severity, message, progname, &block
  end
end
Run Code Online (Sandbox Code Playgroud)

这似乎对原木前哨没有任何影响.我也试过搞乱TaggedLogging,但这似乎不是一个好的解决方案,因为你必须在块中抛出任何标记的代码.

我也尝试config.log_tags通过给它一个Proc来定义应用程序配置,但Authlogic抛出相同的Authlogic::Session::Activation::NotActivatedError异常.试图捕获这个异常使得Ruby变成了一个非常奇怪的状态,似乎是某个无限循环并将​​我的CPU固定在100%.

是否有一个简单的解决方案或一个我完全失踪?

ved*_*ant 7

无法sessionrequest对象访问该对象。但你可以访问cookies.

因此,在用户登录后添加以下代码:

cookies.signed[:user_id] = @user.id
Run Code Online (Sandbox Code Playgroud)

并添加一个初始化程序,例如:

MyApp::Application.config.log_tags = [
    -> request { "user-#{request.cookie_jar.signed[:user_id]}" }
]
Run Code Online (Sandbox Code Playgroud)

现在您的所有日志都将带有[user-980191314][user-]预先添加。


Fio*_*a T 1

我的项目也使用自定义记录器,我们将其连接到environments/Production.rb中。您是否在 production.rb 中设置 Rails 记录器?

config.logger = ActiveSupport::TaggedLogging.new(UserLogger.new)
Run Code Online (Sandbox Code Playgroud)