【问题标题】:Stop ActiveSupport::TaggedLogging from interfering with structured logs阻止 ActiveSupport::TaggedLogging 干扰结构化日志
【发布时间】:2019-10-15 17:59:32
【问题描述】:

ActiveSupport::TaggedLogging 通过Object#extendActiveSupport::TaggedLogging::Formatter 附加到当前格式化程序的继承链中。

很遗憾,ActiveSupport::TaggedLogging::Formatter#call 假设 msg 参数始终是一个字符串,导致 在将标签添加到哈希之前(例如,使用 Lograge 和 Ougai)时产生垃圾。而某些标准库,比如Webpacker,坚持注入TaggedLogging

我想出了下面的元编程技巧,以防止 ActiveSupport::TaggedLogging::Formatter#call 覆盖超类实现(在本例中来自 Ougai):

class MyBunyanFormatter < Ougai::Formatters::Bunyan
  def extend(mod)
    return super unless mod.method_defined?(:call)

    call_original = self.method(:call)            # 1. preserve original
    super(mod)                                    # 2. overridden here
    define_singleton_method(:call, call_original) # 3. de-overridden here
  end
end

但它笨拙且违反直觉,我对此并不感到兴奋。

另一种选择,at least in the case of Webpacker,似乎是编写一个实现tagged()的自定义记录器:

class MyLogger < Ougai::Logger
  def tagged(*tags)
    # do something with tags
    yield self
  end
end

这至少不涉及任何元编程恶作剧,但我想知道我是否可以指望除 Webpacker 之外的其他库不注入 TaggedLogging

自从人们开始尝试从 Rails 应用程序进行结构化日志记录以来,我当然不是第一个遇到此问题的人。什么是正确的解决方案?

【问题讨论】:

    标签: ruby logging activesupport ruby-on-rails-6


    【解决方案1】:

    Ougai docs 中给出的解决方案是猴子补丁TaggedLogging 以消除这种行为。

    module ActiveSupport::TaggedLogging::Formatter
      def call(severity, time, progname, data)
        data = { msg: data.to_s } unless data.is_a?(Hash)
        tags = current_tags
        data[:tags] = tags if tags.present?
        _call(severity, time, progname, data)
      end
    end
    

    请注意,_call 仅适用于基于 Ougai 的 Formatters

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-19
      • 2015-10-18
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 2017-10-11
      • 2015-04-21
      • 1970-01-01
      相关资源
      最近更新 更多