python3中的自定义日志级别不起作用?

时间:2018-01-09 09:36:06

标签: python logging python-3.4

我使用addLevelName()更改了日志级别的数值,然后将日志放入我的模块中,但是在日志文件中,log.error将我的级别名称作为DEBUG。 这是我试图

的代码片段
class LogAttribute:

def __init__(self):

    logger = logging.getLogger()

    logging.addLevelName(50, "ERROR")
    logging.addLevelName(40, "DEBUG")
    logging.addLevelName(30, "WARNING")
    logging.addLevelName(20, "INFO")
    logging.addLevelName(10, "VERBOSE")

    check = logging.getLevelName(40)
    logger.setLevel(config_obj["loggerLevel"])
    output_dir = (os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    filename = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")+"_EP_script.log"
    handler = logging.FileHandler(os.path.join(output_dir, filename))
    formatter = logging.Formatter(" %(levelname)s - %(message)s")
    handler.setFormatter(formatter)
    logger.addHandler(handler)

1 个答案:

答案 0 :(得分:3)

logging模块未设置为任意重新分配标准日志记录级别。 logging.addLevelName()方法实际上只是为了添加新的级别,而不是用于调整现有级别。

幕后发生的事情是logging.error()使用模块级常量logging.ERROR来记录错误消息。该常量已设置为40,这是您刚刚告诉模块映射到字符串'DEBUG'的数值。

如果你真的必须重新映射所有级别,你还需要重新分配常量。因为Python是一种动态语言,所以这当然是可能的:

logging.ERROR = 50

但是,强烈建议您不要这样做。可能存在依赖于常量的第三方框架,嗯,常量

如果您尝试调整第三方库日志记录的方式,则可以选择更好的方法。每条日志消息都包含一个记录器名称,其中包含.的名称构成层次结构,因此记录器名称foo.bar.baz被视为{{1}的子项和foo.bar,让您通过父节点上的设置调整子日志记录节点的日志记录。有关详细信息以及如何配置这些内容,请参阅Logger objects documentation intro

即使per-logger-object和per-hierarchy配置选项不适合您的特定用例,您几乎可以肯定 monkeypatch 这样的模块用基于自定义包装器的logger对象替换在LoggerAdapter pattern上。这是因为在第三方库中登录的标准,最佳实践方法是创建顶级foo对象并将所有日志记录应用于该对象。您可以使用包装器替换该对象:

logger

您可以使用相同的模式来过滤特定的消息;在这种情况下提供自定义import logging level_map = { logging.ERROR: logging.CRITICAL, logging.DEBUG: logging.ERROR } class RemappingLogger(logging.LoggerAdapter): def __init__(self, logger, extra=None): # make the extra parameter optional if extra is None: extra = {} super().__init__(logger, extra) def log(self, lvl, *args, **kwargs): lvl = level_map.get(lvl, lvl) super().log(lvl, *args, **kwargs) import somelibrary import somelibrary.submodule somelibrary.logger = RemappingLogger(somelibrary.logger) somelibrary.submodule.logger = RemappingLogger(somelibrary.submodule.logger) 方法可能就足够了。