【问题标题】:Is it possible to have different level names for different handlers in Python LoggingPython Logging 中的不同处理程序是否可以有不同的级别名称
【发布时间】:2014-06-11 19:51:27
【问题描述】:

在 python 2.6(可能还有更高版本,但我现在只看 2.6)中,似乎日志记录模块的 _levelnames 映射是一个顶级对象,不属于任何类:

_levelNames = {
    CRITICAL : 'CRITICAL',
    ERROR : 'ERROR',
    WARNING : 'WARNING',
    INFO : 'INFO',
    DEBUG : 'DEBUG',
    NOTSET : 'NOTSET',
    'CRITICAL' : CRITICAL,
    'ERROR' : ERROR,
    'WARN' : WARNING,
    'WARNING' : WARNING,
    'INFO' : INFO,
    'DEBUG' : DEBUG,
    'NOTSET' : NOTSET,
}

该模块提供了一种覆盖这些名称的方法:

def addLevelName(level, levelName):
    """
    Associate 'levelName' with 'level'.

    This is used when converting levels to text during message formatting.
    """
    _acquireLock()
    try:    #unlikely to cause an exception, but you never know...
        _levelNames[level] = levelName
        _levelNames[levelName] = level
    finally:
        _releaseLock()

但这是在全球范围内。

我需要记录到 syslog,以便将 ERROR 日志消息标记为“MAJOR”,将 WARNING 日志消息标记为“MINOR”。

现在可以很容易地使用 addLevelName() 方法来更改名称,但同样,这是在全局基础上进行的。我希望我的系统日志处理程序使用 MAJOR 和 MINOR,但将 ERROR 和 WARNING 保留为程序日志。我绝对不必这样做,并且可以接受全局重命名,但我宁愿不这样做。我翻遍了源代码,找不到可以让我这样做的钩子。

我错过了什么吗?

【问题讨论】:

    标签: python logging python-2.6


    【解决方案1】:

    Vinay Sajip 的回答基本上是正确的想法,但存在语法错误,至少在 python 2.6 下是这样。

    这是我对他的回答的修改:

    from logging import Formatter
    class MyFormatter(Formatter):
        def format(self, record):
            orig_levelname = record.levelname
            if record.levelname == 'ERROR':
                record.levelname = 'MAJOR'
            elif record.levelname == 'WARNING':
                record.levelname = 'MINOR'
            result = Formatter.format(self, record)
            record.levelname = orig_levelname
            return result
    

    【讨论】:

      【解决方案2】:

      您可以在适当的处理程序上使用自定义Formatter,它将LogRecordlevelname 属性更改为您想要的任何内容。这不会对关卡名称进行任何全局更改:

      class MyFormatter(logging.Formatter):
          def format(self, record):
              if record.levelname == 'ERROR':
                  record.levelname = 'MAJOR'
              elif record.levelname == 'WARNING':
                  record.levelname = 'MINOR'
              result = super(MyFormatter, self).format(record)
              if record.levelname == 'MAJOR':
                  record.levelname = 'ERROR'
              elif record.levelname == 'MINOR':
                  record.levelname = 'WARNING'
              return result
      

      【讨论】:

      • 听起来合理且正确的解决方案。配置文件阅读器 [formatter] 部分是否采用类属性?
      • 没关系,查看 logging.config 的源代码告诉我,这确实是一个可行的选择。
      • @Vinay_Sajip 我接受了这个解决方案作为答案,因为它在概念上是正确的,尽管至少在 python 2.6 下似乎存在语法错误。我将根据您的回答提供我自己的答案,但我希望您获得信任。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-18
      • 2014-09-30
      相关资源
      最近更新 更多