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-记录器-信息-文本信息
2017-12-19 15:06:43,021-记录器-调试-文本调试
2017-12-19 15:06:43,022-记录器-警告-文本警告
2017-12-19 15:06:43,022-记录器-错误-文本错误
2017-12-19 15:06:43,022-记录器-严重-文本严重
好吧,我想添加一个新的日志记录级别,如下所示:
logger.message("Text message")
输出应该是这样
2017-12-19 15:06:43,022-记录器-消息-短信
谢谢
来自日志记录级别的概述:>
但是,如果您仍然愿意,可以设置自己的日志级别:
在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'
如果您不想创建自己的记录器类,但仍然希望记录其他日志级别,则可以在传统记录器上使用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)
使logging
功能在logging
中可用:
logging.message = message
# or setattr(logging, 'message', message)
使记录器中的message()
功能可用:
logging.Logger.message = message
# or setattr(logging.Logger, 'message', message)
制作自定义Logger类
您可以创建自己的logger类来创建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)
一起使用的最佳方法是什么,但是下面是两种方法.
参考评论,我认为第一种方法更好:
任一将新的记录器设置为默认的记录类,这意味着新的记录器实例将属于MyLogger
类,而不是默认的logging.Logger
类:
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 )
I have this code which works just fine for me.
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")
And the output looks great:
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
Well, I want to add a new logging level like this:
logger.message("Text message")
And the output should be like this
2017-12-19 15:06:43,022 - Logger - MESSAGE - Text message
Thanks
From Logging documentation (emphasis added):
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.
An overview of default logging levels:
But if you still want to, you can make your own log level:
In the logging
-module, _levelToName
and _nameToLevel
are mappings between logging names and levels. Instead of manually adding to them, the addLevelName()
function does this for you.
Here, a new logging level called MESSAGE is added with log level 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'
If you don't want to make your own logger class but still wants to log other log levels, then you can use the Logger.log(level, msg)
-method on the traditional loggers:
logging.log(MESSAGE, 'This is a message')
EDIT: Add message directly
def message(self, msg, *args, **kwargs):
if self.isEnabledFor(MESSAGE):
self._log(MESSAGE, msg, args, **kwargs)
Make the message()
-function available in logging
:
logging.message = message
# or setattr(logging, 'message', message)
Make the message()
-function available in the logger:
logging.Logger.message = message
# or setattr(logging.Logger, 'message', message)
Make custom Logger class
You could make your own logger class to make a message(msg)
-method, to be used similarily as the others (e.g. info(msg)
, warning(msg)
, etc.)
In the following example, a new logger is made with a message(msg)
-method to log MESSAGE:
class MyLogger(logging.Logger):
def message(self, msg, *args, **kwargs):
if self.isEnabledFor(MESSAGE):
self._log(MESSAGE, msg, args, **kwargs)
Get logger
I'm not sure of what's the best way to make it work with logging.getLogger(name)
, but below are two approaches.
Ref. comments, I believe the first approach is better:
Either make the new logger the default logging class, which means new logger instances will be of the MyLogger
class instead of the default logging.Logger
class:
logging.setLoggerClass(MyLogger)
logger = logging.getLogger('A new logger name')
logger.message('This seems to work')
assert isInstance(logger, MyLogger)
Or just make an instance of the logger and add it to the loggerDict
in the active logging.Manager
instance (EDIT: not recommended, see comments):
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 log level
# 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')
This assumes that MESSAGE
is predefined as an integer numerical value representing the log level. (E.g. 25 as previously mentioned)
这篇关于Python3添加日志记录级别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!