【问题标题】:How can I define my own levels in log4r without a conflict with other log4r-loggers?如何在 log4r 中定义自己的级别而不与其他 log4r 记录器发生冲突?
【发布时间】:2014-01-05 19:58:09
【问题描述】:

我可以使用 log4r 定义自己的日志级别:

require 'log4r'
require 'log4r/configurator'

# This is how we specify our levels
Log4r::Configurator.custom_levels "Foo", "Bar", "Baz"

log = Log4r::Logger.new('custom levels')
p log.levels  #-> ["ALL", "Foo", "Bar", "Baz", "OFF"]
log.add Log4r::StdoutOutputter.new('console')

puts log.foo? #-> true
log.foo "This is foo 1"

log.level = Log4r::Bar
puts log.foo? #->false
log.foo "This is foo 2"

log4r-documentation 说:

此外,应该在使用 Log4r 完成任何其他操作之前设置自定义级别,否则将加载默认级别。

这个限制是两个问题的根源:

  • 使用Log4r::Configurator.custom_levels 设置新级别仅适用于未定义记录器的情况。
  • 如果我在定义自己的级别后创建另一个记录器,我会再次获得自定义级别。

问题一:

例子:

require 'log4r'
require 'log4r/configurator'

#Create a dummy logger
Log4r::Logger.new('dummy')

# Define new levels -> does not work after creation of another logger.
Log4r::Configurator.custom_levels "Foo", "Bar", "Baz"
log = Log4r::Logger.new('custom levels')
p log.levels  #-> ["ALL", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF"]

不使用自定义级别。

问题 2

如果我定义自己的级别,我就不可能回到默认值。

例子:

require 'log4r'
require 'log4r/configurator'

# Define customer levels
Log4r::Configurator.custom_levels "Foo", "Bar", "Baz"
Log4r::Logger.new('dummy with custom levels')

#Reset to standard levels ["DEBUG", "INFO", "WARN", "ERROR", "FATAL"] <- this does not work
Log4r::Configurator.custom_levels( *Log4r::Log4rConfig::LogLevels )
log2 = Log4r::Logger.new('log')
p log2.levels #-> ["ALL", "Foo", "Bar", "Baz", "OFF"], but I wanted ["DEBUG", "INFO", "WARN", "ERROR", "FATAL"]

背景:

我想用我自己的levels similar to Apache 创建一个记录器: DEBUG INFO NOTICE WARN ERROR CRIT ALERT EMERG.

当我这样做时,我遇到了两个问题:

  • 如果另一个应用程序也使用 log4r,则该应用程序没有致命级别。 如果我在应用程序中添加致命级别,则可以解决此问题。
  • 如果在我的应用程序之前加载了另一个应用程序并创建了一个记录器, 我的申请将失败,因为我的客户级别不可用。

我的问题:

如何创建具有自定义日志级别且没有副作用的记录器 其他记录器?

【问题讨论】:

  • 看来你不能轻易做到这一点。日志级别以全局方式定义(查看 Github 上的 Log4r 源代码)。我会联系 Log4r 的作者,看看他是否能给你任何关于如何解决这个问题的提示。否则,您将不得不阅读 Log4r 源代码并为您自己的解决方法打猴子补丁。也许就像在这里修补这个方法一样简单,但这只是一个非常快速的猜测:github.com/colbygk/log4r/blob/…

标签: ruby logging log4r


【解决方案1】:

自定义级别是进程范围的,您无法在设置后重置它。但是可能有一些方法可以实现您想要的。

问题 1

必须设置以前的自定义级别是有原因的,并且在设置自定义级别期间会创建记录器方法和输出器方法,因此如果要删除一些可能导致意外错误的自定义级别,请务必小心.

但是,有一种解决方法可以从 my fork of Log4r 重置自定义级别,它适用于 test purpose。 (此方法将 log4r 重置为原始状态,清除所有现有的记录器和输出器)

问题 2

解决冲突有两种解决方案:

  • 在其他模块之前定义所有自定义级别。并且您必须包括所有自定义级别。例如['Foo', 'Bar', 'Bing', 'DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL']
  • 如果您无法在其他模块之前这样做,请使用上述方法重置 log4r 并重新定义自定义级别,并在需要时从其他模块加载配置
  • 使用如下别名方法并相应更改您的 log4r 配置(例如,将 foo 替换为 debug 等)
Log4r::Logger.module_eval %{
  alias_method :foo, :debug
  alias_method :bar, :info
  alias_method :baz, :error
  alias_method :qux, :fatal
}

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-06
    相关资源
    最近更新 更多