logging主要功能
logging模块主要用以日志记录。包括日志的级别、写日志的文件、日志的过滤、日志的切分等。
logging常规用法
1、logging的全局用法,可写日志到控制台、到指定文件、指定日志格式
import logging
fmt = "%(asctime)s - %(filename)s[line: %(lineno)d] - %(levelname)s - %(message)s"
loggging.basicConfig(filename=None, format=fmt, level=logging.DEBUG) #filename为None写入到控制台,filename非空写入到指定文件下
logging.debug("This is a debug log.")
logging.info("This is an info log.")
logging.warning("This is a warning log.")
loggging.error("This is an error log.")
logging.critical("This is a critical log.")
logging.log(level=logging.ERROR, msg="An error log.") # 把日志msg设置为level级别的日志
basicConfig方法定义了log的全局配置,包括filename、格式、级别等。
如filename为空,日志会默认输出到控制台;如level为空,默认展示warning及其高级别的日志。
2、日志生成器,主要负责生成日志
logger = logging.getLogger(name=None) # 返回一个日志生成器,如name为None,日志生成器名为root;如name非None,返回日志生成器为name的取值,根日志生成器为root logger.setLevel(level=logging.DEBUG)
logger.debug("This is a debug log.")
logger.info("This is an info log.")
logger.warning("This is a warning log.")
logger.error("This is an error log.")
logger.critical("This is a critical log.")
logger.addHandler(hdlr=hdlr) # 添加控制器
logger是单例模式,就是无论程序中哪里有日志,获取到的logger对象都是同一个。
问题:logger.setLevel(level=logging.DEBUG)为什么没有生效?目前只能设置为WARNINIG及其以上级别才能生效。
是因为setLevel方法可以运用到logger,也可以运用到handler,这2者取较高级别的日志级别。
3、日志处理器Handler,主要负责处理日志,包括日志写的位置、日志的级别、日志的格式、日志的时间大小划分等。比如写入到文本FileHandler(),写入到控制台StreamHandler(),写入到指定系统、写入到邮件中等。
# 写入文件
hdlr_file = logging.FileHandler(filename=filename, encoding="utf-8")
# 写入控制台
hdlr_stream = logging.StreamHandler() # 设置处理器的日志级别,如和logging设置的日志级别冲突,取高级别日志
hdlr_file.setLevel(level=logging.DEBUG) # 设置日志格式
log_fmt = logging.Formatter(fmt=fmt)
hdlr_file.setFormatter(fmt=log_fmt)
logger.addHandler(hdlr=hdlr_file)
logger.addHandler(hdlr=hdlr_stream)
logger.debug("xxx")
logger.info("xxx")
logger.warning("xxxx")
logger.error("xxx")
logger.critical("xxx")
最后在控制台输出WARNING日志,在文件中也输出WARNING日志。
from logging import handlers
handlers.RotatingFileHandler(filename="test.log") # 按大小分日志
handlers.TimedRotatingFileHandler(filename="test.log") # 按时间分日志
handlers.SMTPHandler() #将日志发送到给邮件
有几个地方需要注意:1)logger只负责生成日志,默认写入到控制台,默认级别是WARNINIG,如其他的handler设置自己的日志级别,取2者的高级别日志;2)可以控制不同的控制器不同的格式或日志级别,比如控制台ERROR级别,文件CRITICAL级别等。
4、日志过滤器Filter
5、日志格式Formatter
log_fmt = logging.Formatter(fmt=fmt) # 返回的是对象,不是一个fmt的字符串
hdlr_file.addFormatter(fmt=log_fmt) # 参数fmt不是一个字符串,而是格式对象
遇到的问题
1、logger.setLevel(level=logging.DEBUG)和hdlr.setLevel(level=logging.DEBUG)设置不生效?只能展示WARNRIN及其高级别日志。
默认生成器和控制器的日志级别都为WARNING级别,可展示WARNING及其以上高级别日志,如果这2着级别不一致,取更高级别。
所以会看到设置了hdlr.setlevel(level=logging.DEBUG),仍会展示成WARNING级别日志,是因为取了默认的生成器的日志级别WARNINIG。
2、生成器和控制器都有setLevel方法,如两者冲突,选择高级别的日志级别
3、一般的logging使用如下:
import logging
class Test_log(object):
def __init__(self):
fmt = "%(asctime)s - %(levelname)s -%(filename)s[line: %(lineno)d - %
(message)s] "
self.logger = logging.getLogger()
fh = logging.FileHandler(filename="test_aa.log")
log_fmt = logging.Formatter(fmt=fmt) # fh.setLevel(level=logging.WARNING) #
默认是WARNING级别日志
fh.setFormatter(fmt=log_fmt)
self.logger.addHandler(fh)
def log_for_test(self):
self.logger.debug("This is a debug log.")
self.logger.info("This is an info log.")
self.logger.warning("This is a warning log.")
self.logger.error("This is an error log.")
self.logger.critical("This is a critical log.")
if __name__ == '__main__':
test_aa = Test_log()
test_aa.log_for_test()