1.什么是日志级别
- 日志级别是日志的严重程度,如果设置的日志级别低于logging模块设置的级别,那么将被忽略;
- warning是默认的日志级别,critical和error的级别高于warning,而info和debug级别高于warning;
![bc3a77b3be691da4051b9fa530106ba0.png](https://i-blog.csdnimg.cn/blog_migrate/e54ea840377c91b525c822aa752ccec7.jpeg)
2.日志级别实例
我们知道默认的日志级别是warning,那下面我们通过一个实例来对比一下warning日志级别和其他的日志级别的等级高级,看看如果设置的日志级别低于logging模块设置的级别,那么将被忽略这个结论是否正确
import loggingfrom datetime import datetimelogging.basicConfig(format='%(message)s {}'.format(datetime.now()), level=logging.WARNING)logging.debug('我是 DEBUG 级别的日志')logging.info('我是 INFO 级别的日志')logging.warning('我是 WARNING 级别的日志')logging.error('我是 ERROR 级别的日志')logging.critical('我是 CRITICAL 级别的日志')输出结果:我是 WARNING 级别的日志 2019-04-11 15:37:14.254115我是 ERROR 级别的日志 2019-04-11 15:37:14.254115我是 CRITICAL 级别的日志 2019-04-11 15:37:14.254115
通过输出结果,我们知道了上面的那个结论是正确的啦~
我们再用其他的日志级别实践一下,日志级别为DEBUG,那只要日志级别比DEBUG高的都会打印;
import loggingfrom datetime import datetimelogging.basicConfig(format='%(message)s {}'.format(datetime.now()), level=logging.DEBUG)logging.debug('我是 DEBUG 级别的日志')logging.info('我是 INFO 级别的日志')logging.warning('我是 WARNING 级别的日志')logging.error('我是 ERROR 级别的日志')logging.critical('我是 CRITICAL 级别的日志')输出结果:我是 DEBUG 级别的日志 2019-04-11 15:39:25.098599我是 INFO 级别的日志 2019-04-11 15:39:25.098599我是 WARNING 级别的日志 2019-04-11 15:39:25.098599我是 ERROR 级别的日志 2019-04-11 15:39:25.098599我是 CRITICAL 级别的日志 2019-04-11 15:39:25.098599
3.日志格式参数有哪些
- %(levelno)s:打印日志级别的数值;
- %(levelname)s:打印日志级别的名称;
- %(pathname)s:打印当前执行程序的路径,其实就是sys.argv[0];
- %(filename)s:打印当前执行程序名;
- %(funcName)s:打印日志的当前函数;
- %(lineno)d:打印日志的当前行号;
- %(asctime)s:打印日志的时间;
- %(thread)d:打印线程ID;
- %(threadName)s:打印线程名称;
- %(process)d:打印进程ID;
- %(processName)s:打印线程名称;
- %(module)s:打印模块名称;
- %(message)s:打印日志信息;
4.日志时间格式化
打印日志的时候,时间精确到了毫秒,但有时候我们不需要精确到毫秒,那要怎么办?可以使用日志时间格式化,也就是设置datefmt
import loggingfrom datetime import datetimelogging.basicConfig(format='%(asctime)s %(message)s {}'.format(datetime.now()), level=logging.WARNING, datefmt='%Y-%m-%d')logging.debug('我是 DEBUG 级别的日志')logging.info('我是 INFO 级别的日志')logging.warning('我是 WARNING 级别的日志')logging.error('我是 ERROR 级别的日志')logging.critical('我是 CRITICAL 级别的日志')输出结果:2019-04-11 我是 WARNING 级别的日志 2019-04-11 15:43:41.1662452019-04-11 我是 ERROR 级别的日志 2019-04-11 15:43:41.1662452019-04-11 我是 CRITICAL 级别的日志 2019-04-11 15:43:41.166245
通过上面的例子,我们知道可以使用datefmt来设置打印时间的格式,如打印年月日时分秒为:datefmt='%Y-%m-%d %H:%M:%S';
5.日志输出处理 Handler
import loggingfrom pprint import pprintlogging.basicConfig(format='%(asctime)s %(message)s ', level=logging.DEBUG, datefmt='%Y-%m-%d %H:%M:%S')# 通过logging的工厂方法,返回logger实例root_logger = logging.getLogger()xkd_logger = logging.getLogger('xkd')root_logger.setLevel(40)# handler的level级别必须大于等于 logger实例的level级别才有意义# 如果日志的级别低于logger的级别是无法进入到logger的error_handler = logging.StreamHandler()error_handler.setLevel(level=logging.ERROR)error_handler.setFormatter(fmt=logging.Formatter('%(asctime)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S'))critical_handler = logging.FileHandler(filename='./app.log')critical_handler.setLevel(level=logging.CRITICAL)critical_handler.setFormatter(fmt=logging.Formatter('%(asctime)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S'))root_logger.addHandler(error_handler)root_logger.addHandler(critical_handler)root_logger.info('我是 root 的 INFO 级别的日志')root_logger.error('我是 root 的 ERROR 级别的日志')root_logger.critical('我是 root 的 CRITICAL 级别的日志')pprint(root_logger.handlers)# 子loggerxkd_level = xkd_logger.getEffectiveLevel()print(xkd_level)xkd_logger.info('我是 INFO 级别') # 不会打印xkd_logger.error('我是 error 级别') # 会打印
- handler的level级别必须大于等于logger实例的level级别才有意义,如果日志的级别低于logger的级别是无法进入到logger的;
- 日志的输出可以是控制台,可以是文件, 默认是终端 stderr;
- logger实例有继承关系,如果子logger没有设置level和handler,那么从父logger中继承;
- 每一个logger实例,默认有一个handler,StreamHandler;
- 每一个logger实例都有一个propagate属性,控制日志信息是否向父类传递, 默认propagate为True,则向父类传递日志信息;
6.第三方日志模块structlog的使用
安装命令行:
pip install structlog# 或者带颜色打印(如果是打印到文件,最好不要使用带颜色打印,会有转义字符)pip install structlog colorama
我们来看一下structlog的基本使用
from structlog import get_loggerlog = get_logger()# 可以直接传递key/valuelog.info("需要打印的信息