今天使用oslo_log时发生了一个和想象不同结果,程序如下
程序目录:
image.png
logging.conf
[loggers]
keys=root,debug_log
[handlers]
keys=warning_file,info_file,debug_file
[formatters]
keys=minimal,normal,debug
###########
# Loggers #
###########
[logger_root]
level=WARNING
qualname=warning
handlers=warning_file,info_file
[logger_debug_log]
level=DEBUG
qualname=log
handlers=debug_file
################
# Log Handlers #
################
[handler_warning_file]
class=cloghandler.ConcurrentRotatingFileHandler
level=WARNING
formatter=minimal
args=('warning.log','a',1024*1024*20,100)
[handler_info_file]
class=handlers.WatchedFileHandler
level=INFO
formatter=normal
args=('info.log','w')
[handler_debug_file]
class=StreamHandler
level=DEBUG
formatter=debug
args=(sys.stdout,)
##################
# Log Formatters #
##################
[formatter_minimal]
format=(%(name)s): %(asctime)s [%(levelname)s] %(module)s %(funcName)s %(message)s
[formatter_normal]
format=(%(name)s): %(asctime)s %(levelname)s %(message)s
[formatter_debug]
format=(%(name)s): %(asctime)s %(levelname)s %(module)s %(funcName)s %(message)s
test.py
from oslo_config.cfg import CONF
from oslo_log import log
CONF.log_config_append = 'logging.conf'
log.setup(CONF, "application")
LOG = log.getLogger('log')
LOG.debug("log info")
LOG.info("root info")
在test.py中LOG = log.getLogger('log')
按道理应该对应的是logging.conf文件logger中的debug_log,handle中的debug_file,按道理说test.py中的LOG.debug("log info")
,LOG.info("root info")
都应该只输出到屏幕,不应该保存到文件里面
神奇的结果如下:
在文件info.conf与屏幕都有输出,但是文件中只有info级别的信息
经过上网查找资料,知道了python logging模块中的日志是有级别之分的。
debug < info< warning< error< critical
因为logging.conf中定义了debug_file的级别是debug级别也就是最低的级别,在test.py中调用LOG.debug()时就直接向屏幕输出
但是当调用LOG.info()时,就和定义的不相符,则会调用程序中的root级别下相应的handle.
这也就是为什么只有info.log文件中有数据而warning.info中没有数据的原因
如果test.py 改为
from oslo_config.cfg import CONF
from oslo_log import log
CONF.log_config_append = 'logging.conf'
log.setup(CONF, "application")
LOG = log.getLogger('log')
LOG.debug("log info")
LOG.info("root info")
LOG.warning("root2 info")
则结果就变为
image.png
image.png
image.png
debug级别最低的打印了所有数据,info.log除了warning没有打印,warning.log只打印了warning
可以看出日志保留的原则是:保存显示大于等于当前级别的日志。因为级别越高日志越重要
配置文件解读
[loggers] #日志处理器root是必须的,当找不到合适的处理器时就默认找root
keys=root,debug_log
[handlers]#句柄,可以时标准输出也可以是文件等
keys=warning_file,info_file,debug_file
[formatters]#输出格式
keys=minimal,normal,debug
###########
# Loggers #
###########
[logger_root]
level=WARNING #可以输出的日志最大等级,当句柄定义的等级大于这个等级则句柄无效
qualname=warning #test.py 中log.getLogger('log')中的getLogger('log')中的log
handlers=warning_file,info_file #关联哪些句柄
[logger_debug_log]
level=DEBUG
qualname=log
handlers=debug_file
################
# Log Handlers #
################
[handler_warning_file]
class=cloghandler.ConcurrentRotatingFileHandler #这是进程安全的文件句柄其他文件句柄是线程安全的不是进程安全的
level=WARNING#文件记录的日志等级 要小于等于logger定义的等级
formatter=minimal #输出格式
args=('warning.log','a',1024*1024*20,100) #class的参数依次为:文件名,模式(a追加模式,w重写模式),每个文件大小,可以保存多少文件
[handler_info_file]
class=handlers.WatchedFileHandler
level=INFO
formatter=normal
args=('info.log','w')
[handler_debug_file]
class=StreamHandler
level=DEBUG
formatter=debug
args=(sys.stdout,)
##################
# Log Formatters #
##################
[formatter_minimal]
format=(%(name)s): %(asctime)s [%(levelname)s] %(module)s %(funcName)s %(message)s
[formatter_normal]
format=(%(name)s): %(asctime)s %(levelname)s %(message)s
[formatter_debug]
format=(%(name)s): %(asctime)s %(levelname)s %(module)s %(funcName)s %(message)s
网友评论