假设我有以下代码:
import logging
import logging.handlers
a = logging.getLogger('myapp')
h = logging.handlers.RotatingFileHandler('foo.log')
h.setLevel(logging.DEBUG)
a.addHandler(h)
# The effective log level is still logging.WARN
print a.getEffectiveLevel()
a.debug('foo message')
a.warn('warning message')
Run Code Online (Sandbox Code Playgroud)
我希望logging.DEBUG
处理程序上的设置会导致调试级别的消息写入日志文件.但是,这将打印30作为有效级别(等于logging.WARNING
,默认值),并仅将warn
消息记录到日志文件,而不是调试消息.
似乎处理程序的日志级别被丢弃在地板上,例如它被默默地忽略.这让我想知道,为什么要setLevel
处理器呢?
Bak*_*riu 50
它允许更精细的控制.默认情况下,根记录器具有WARNING
级别设置,这意味着它不会打印较低级别的消息(无论处理程序的级别如何设置!).但是,如果将根记录器的级别设置为DEBUG
,则确实将消息发送到日志文件:
import logging
import logging.handlers
a = logging.getLogger('myapp')
a.setLevel(logging.DEBUG) # set root's level
h = logging.handlers.RotatingFileHandler('foo.log')
h.setLevel(logging.DEBUG)
a.addHandler(h)
print a.getEffectiveLevel()
a.debug('foo message')
a.warn('warning message')
Run Code Online (Sandbox Code Playgroud)
现在,您想添加一个不记录调试信息的新处理程序的图像.您只需设置处理程序日志记录级别即可完成此操作:
import logging
import logging.handlers
a = logging.getLogger('myapp')
a.setLevel(logging.DEBUG) # set root's level
h = logging.handlers.RotatingFileHandler('foo.log')
h.setLevel(logging.DEBUG)
a.addHandler(h)
h2 = logging.handlers.RotatingFileHandler('foo2.log')
h2.setLevel(logging.WARNING)
a.addHandler(h2)
print a.getEffectiveLevel()
a.debug('foo message')
a.warn('warning message')
Run Code Online (Sandbox Code Playgroud)
现在,日志文件foo.log
将包含两个消息,而该文件foo2.log
将仅包含警告消息.您可能对只有错误级别消息的日志文件感兴趣,然后只需添加一个Handler
并设置其级别logging.ERROR
,使用相同的一切Logger
.
你可能会认为的Logger
日志记录级别作为一个全球性的限制上的消息对于一个给定的记录器"有趣" 和它的处理程序.之后记录器考虑的消息将发送给处理程序,处理程序执行自己的过滤和日志记录过程.
cwa*_*ole 21
在Python日志记录中,有两个不同的概念:记录器记录的级别和处理程序实际激活的级别.
当进行日志调用时,基本上发生的是:
if self.level <= loglevel:
for handler in self.handlers:
handler(loglevel, message)
Run Code Online (Sandbox Code Playgroud)
然后,每个处理程序将调用:
if self.level <= loglevel:
# do something spiffy with the log!
Run Code Online (Sandbox Code Playgroud)
如果您想要对此进行真实演示,可以查看Django的配置设置.我会在这里提供相关代码.
LOGGING = {
#snip
'handlers': {
'null': {
'level': 'DEBUG',
'class': 'logging.NullHandler',
},
'console':{
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
'filters': ['special']
}
},
'loggers': {
#snip
'myproject.custom': {
# notice how there are two handlers here!
'handlers': ['console', 'mail_admins'],
'level': 'INFO',
'filters': ['special']
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,在上面的配置中,只有日志到达getLogger('myproject.custom').info
及以上才会进行日志记录处理.当发生这种情况时,控制台将输出所有结果(它将输出所有结果,因为它被设置为DEBUG
水平),而mail_admins
记录器将发生所有ERROR
s,FATAL
s和CRITICAL
s.
我想一些不是Django的代码也可能有所帮助:
import logging.handlers as hand
import logging as logging
# to make things easier, we'll name all of the logs by the levels
fatal = logging.getLogger('fatal')
warning = logging.getLogger('warning')
info = logging.getLogger('info')
fatal.setLevel(logging.FATAL)
warning.setLevel(logging.WARNING)
info.setLevel(logging.INFO)
fileHandler = hand.RotatingFileHandler('rotating.log')
# notice all three are re-using the same handler.
fatal.addHandler(fileHandler)
warning.addHandler(fileHandler)
info.addHandler(fileHandler)
# the handler should log everything except logging.NOTSET
fileHandler.setLevel(logging.DEBUG)
for logger in [fatal,warning,info]:
for level in ['debug','info','warning','error','fatal']:
method = getattr(logger,level)
method("Debug " + logger.name + " = " + level)
# now, the handler will only do anything for *fatal* messages...
fileHandler.setLevel(logging.FATAL)
for logger in [fatal,warning,info]:
for level in ['debug','info','warning','error','fatal']:
method = getattr(logger,level)
method("Fatal " + logger.name + " = " + level)
Run Code Online (Sandbox Code Playgroud)
这导致:
Debug fatal = fatal
Debug warning = warning
Debug warning = error
Debug warning = fatal
Debug info = info
Debug info = warning
Debug info = error
Debug info = fatal
Fatal fatal = fatal
Fatal warning = fatal
Fatal info = fatal
Run Code Online (Sandbox Code Playgroud)
再次,注意如何info
在记录的东西info
,warning
,error
,和fatal
当日志处理程序被设置为DEBUG
,但是当处理器被设置为FATAL
突然只有FATAL
电文提出它的文件.
当且仅当
handler.level <= message.level
&&
logger.level <= message.level
Run Code Online (Sandbox Code Playgroud)
然后打印消息。
提醒:值越低,内容越详细
Level | Numeric value
---------|--------------
CRITICAL | 50
ERROR | 40
WARNING | 30
INFO | 20
DEBUG | 10
NOTSET | 0
Run Code Online (Sandbox Code Playgroud)
参考: https: //docs.python.org/3/library/logging.html#logging-levels
如果记录器设置为WARNING
,则处理程序是否有更详细的设置也没关系。当它到达处理程序时它已经被过滤了。
import logging
handler_info = logging.StreamHandler()
handler_info.setLevel("INFO")
handler_info.setFormatter(logging.Formatter(
f"%(levelname)s message for %(name)s handled by handler_info: %(message)s"))
handler_debug = logging.StreamHandler()
handler_debug.setLevel("DEBUG")
handler_debug.setFormatter(logging.Formatter(
f"%(levelname)s message for %(name)s handled by handler_debug: %(message)s"))
logger_info = logging.getLogger('logger_info')
logger_info.setLevel("INFO")
logger_info.addHandler(handler_info)
logger_info.addHandler(handler_debug)
logger_debug = logging.getLogger('logger_debug')
logger_debug.setLevel("DEBUG")
logger_debug.addHandler(handler_info)
logger_debug.addHandler(handler_debug)
print()
print("output for `logger_info.info('hello')`")
logger_info.info("hello")
print()
print("output for `logger_info.debug('bonjour')`")
logger_info.debug("bonjour")
print()
print("output for `logger_debug.info('hola')`")
logger_debug.info("hola")
print()
print("output for `logger_debug.debug('ciao')`")
logger_debug.debug("ciao")
print()
Run Code Online (Sandbox Code Playgroud)
这使
output for `logger_info.info('hello')`
INFO message for logger_info handled by handler_info: hello
INFO message for logger_info handled by handler_debug: hello
output for `logger_info.debug('bonjour')`
# nothing, because message.level < logger.level
output for `logger_debug.info('hola')`
INFO message for logger_debug handled by handler_info: hola
INFO message for logger_debug handled by handler_debug: hola
output for `logger_debug.debug('ciao')`
DEBUG message for logger_debug handled by handler_debug: ciao
# nothing from handler_info, because message.level < handler.level
Run Code Online (Sandbox Code Playgroud)