Python3 添加日志级别

Python3 add logging level

我有这段代码,对我来说工作得很好。

import logging
import logging.handlers

logger = None


def create_logger():
    global logger
    logger = logging.getLogger('Logger')
    logger.setLevel(logging.DEBUG)
    handler = logging.handlers.RotatingFileHandler("C:/Users/user/Desktop/info.log", maxBytes=1000000, backupCount=20)
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)
    logger.addHandler(handler)


create_logger()
logger.info("Text info")
logger.debug("Text debug")
logger.warning("Text warning")
logger.error("Text error")
logger.critical("Text critical")

输出看起来很棒:

2017-12-19 15:06:43,021 - Logger - INFO - Text info
2017-12-19 15:06:43,021 - Logger - DEBUG - Text debug
2017-12-19 15:06:43,022 - Logger - WARNING - Text warning
2017-12-19 15:06:43,022 - Logger - ERROR - Text error
2017-12-19 15:06:43,022 - Logger - CRITICAL - Text critical

好吧,我想像这样添加一个新的日志记录级别:

logger.message("Text message")  

输出应该是这样的

2017-12-19 15:06:43,022 - Logger - MESSAGE - Text message

谢谢

来自 Logging documentation(已强调):

Defining your own levels is possible, but should not be necessary, as the existing levels have been chosen on the basis of practical experience. However, if you are convinced that you need custom levels, great care should be exercised when doing this, and it is possibly a very bad idea to define custom levels if you are developing a library. That’s because if multiple library authors all define their own custom levels, there is a chance that the logging output from such multiple libraries used together will be difficult for the using developer to control and/or interpret, because a given numeric value might mean different things for different libraries.

默认概览logging levels

但是如果你还想,你可以设置自己的日志级别:

logging模块中,_levelToName_nameToLevel是日志名称和级别之间的映射。 addLevelName() 函数不是手动添加它们,而是为您完成此操作。

这里,添加了一个名为MESSAGE的新日志级别,日志级别为25:

import logging

# Define MESSAGE log level
MESSAGE = 25

# "Register" new loggin level
logging.addLevelName(MESSAGE, 'MESSAGE')  # addLevelName(25, 'MESSAGE')

# Verify
assert logging.getLevelName(MESSAGE) == 'MESSAGE'

如果不想做自己的loggerclass但又想记录其他日志级别,那么可以在传统logger上使用Logger.log(level, msg)-方法:

logging.log(MESSAGE, 'This is a message')

编辑:直接添加消息

 def message(self, msg, *args, **kwargs):
    if self.isEnabledFor(MESSAGE):
        self._log(MESSAGE, msg, args, **kwargs) 

使 message() 函数在 logging 中可用:

 logging.message = message
 # or setattr(logging, 'message', message)

使 message()-函数在记录器中可用:

 logging.Logger.message = message
 # or setattr(logging.Logger, 'message', message)

制作自定义记录器class

您可以制作自己的记录器 class 来制作 message(msg) 方法,与其他方法类似地使用(例如 info(msg)warning(msg) 等。 )

在下面的示例中,使用 message(msg) 方法创建了一个新的记录器来记录 MESSAGE:

class MyLogger(logging.Logger):
    def message(self, msg, *args, **kwargs):
        if self.isEnabledFor(MESSAGE):
            self._log(MESSAGE, msg, args, **kwargs)

获取记录器

我不确定使用 logging.getLogger(name) 的最佳方式是什么,但下面是两种方法。 参考评论,我认为第一种方法更好:

要么 使新记录器成为默认记录器 class,这意味着新记录器实例将属于 MyLogger class 而不是默认 logging.Logger class:

logging.setLoggerClass(MyLogger)
logger = logging.getLogger('A new logger name')
logger.message('This seems to work')
assert isInstance(logger, MyLogger)

只需创建记录器实例并将其添加到活动 logging.Manager 实例中的 loggerDict (EDIT:不推荐,见评论):

my_logger = MyLogger('Foo')
logging.Logger.manager.loggerDict['Foo'] = my_logger
logger = logging.getLogger('Foo')
logger.message('This is the same instance as my_logger')
assert logger is my_logger

使用新的日志级别

# Use the new logger class
logger.warning('Custom log levels might be a bad idea')
logger.message('Here is a message')
# Log with custom log level:
logger.log(MESSAGE, 'This is a message')

这里假设MESSAGE被预定义为代表日志级别的整数数值。 (例如 25 如前所述)