8

为了帮助跟踪用户操作以进行调试,我们正在考虑将会话的登录用户 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

这似乎对日志前哨没有任何影响。我也尝试过使用 TaggedLogging,但这似乎不是一个好的解决方案,因为您必须将任何标记代码放入一个块中。

我还尝试config.log_tags通过给它一个 Proc 在应用程序配置中进行定义,但 Authlogic 抛出了相同的Authlogic::Session::Activation::NotActivatedError异常。试图捕捉这个异常会使 Ruby 进入一个非常奇怪的状态,在某处似乎是一个无限循环,并将我的 CPU 固定在 100%。

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

4

3 回答 3

6

无法session从对象访问request对象。但您可以访问cookies.

因此,在您的用户登录后添加此代码:

cookies.signed[:user_id] = @user.id

并添加一个初始化器,如:

MyApp::Application.config.log_tags = [
    -> request { "user-#{request.cookie_jar.signed[:user_id]}" }
]

现在您的所有日志都将具有[user-980191314][user-]前置。

于 2017-01-11T12:29:30.403 回答
1

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

config.logger = ActiveSupport::TaggedLogging.new(UserLogger.new)
于 2012-12-12T07:11:51.377 回答
0

只需添加 Vedant 的答案。如果用户未登录,有时我们不需要打印任何内容。在这种情况下:

config.log_tags = [Proc.new { |request| !request.cookie_jar.signed[:user_id].nil? ? “user_id:#{request.cookie_jar.signed[:user_id]}”:假}]

现在,当任何用户登录时,日志将在[user_id: XXXXXXXXX]前面添加,否则,将不会添加任何内容。

于 2021-09-26T14:39:22.663 回答