-2

我正在编写一个多记录器实现,以使我的应用程序能够记录到多个后端。实现看起来像:

class MultiLogger < Logger
  def initialize(loggers = [])
    @loggers = []
  end

  def add(severity, message, _attributes, _environment, progname)
    @loggers.each do |logger|
      logger.add(severity, message, progname)
    end
  end

  def info(message, attributes, environment, progname)
    add(Logger::INFO, message, attributes, environment, progname)
  end

  ...
end

基本上我只是将调用转发给MultiLogger#add实例化期间关联的所有记录器。问题是我需要将该记录器设置为 Rails 的默认记录器,但我不能这样做。

我正在添加config.logger = MultiLogger.new([Logger1.new, Logger2.new])到我的application.rb文件中,但是当我调用 时logger.info,我收到了与add方法的数量相关的错误。

最奇怪的是,我的自定义 add 从未被调用,并且该错误是从 引发的ActiveSupport::LogerThreadSafeLevel#add,如下所示.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/activesupport-6.0.3.2/lib/active_support/logger_thread_safe_level.rb:51:in 'add'

我想我遗漏了关于 Rails 日志记录机制内部工作的一些重要内容……但是什么?是ActiveSupport覆盖我的add方法吗?我能做些什么来避免这种情况?

4

2 回答 2

0

使用 ActiveSupport::Logger 或修改应用程序配置文件

默认情况下,Rails 期望记录器是 ActiveSupport::Logger 的一个实例。但是,您可以修改 application.rb 以使用其他兼容的东西。Rails 文档说:

2.1 什么是记录器?

Rails 使用 ActiveSupport::Logger 类来写入日志信息。也可以替换其他记录器,例如 Log4r。

您可以在 config/application.rb 或任何其他环境文件[.] 中指定替代记录器

于 2020-09-15T18:46:50.390 回答
0

Rails 期望 Logger#add 方法遵循 Ruby 记录器的接口,即一个强制参数(the severity),后跟两个可选参数(themessage和 the progname)以及一个可选块。

在这里,Rails 还假设了非常具体的语义,记录器实现如何使用这些参数来构建最终消息(当传递 a message、 a progname、块或它们的任何组合时。

class MultiLogger
  def add(severity, message = nil, progname = nil, &block)
    @loggers.each do |logger|
      logger.add(severity, message, progname, &block)
    end
    true
  end

  def info(message = nil, &block)
    add(Logger::INFO, message, &block)
  end

  # ...
end

在您的原始代码中,您在add方法中定义了额外的强制参数(即_attributesand _environment),这些参数在调用方法时未提供,因此是异常。一旦你修复了你的参数列表(并实现了缺少的快捷方法和访问器),一切都应该工作。

于 2020-09-15T19:02:03.537 回答