Python标准库自带日志模块。python程序的日志记录可直接调用标准库的日志模块。
日志的严重等级 严重等级为NOTSET, DEBUG, INFO, WARNING, ERROR, CRITICAL, 严重程度依次递增。
1 2 3 4 5 6 7 |
CRITICAL: 50 ERROR: 40 WARNING: 30 INFO: 20 DEBUG: 10 NOTSET: 0 |
基本用法
开发轻量级的应用,对日志要求简单,直接在相关代码逻辑中加入日志功能即可。
1 2 3 4 5 6 7 8 |
import logging logging.info('info message') logging.debug('debug message') logging.warning('warning message') logging.error('error message') logging.critical('critical message') |
输出日志:
1 2 3 4 |
WARNING:root:warn message ERROR:root:error message CRITICAL:root:critical message |
默认情况下,日志级别在WARNING及以上的日志输出到标准输出。
日志输出到文件,需要使用logging.basicConfig()
做简单的配置
代码示例如下:
1 2 3 4 5 6 7 8 9 10 11 |
import logging # 配置日志文件和日志级别 logging.basicConfig(filename='logger.log', level=logging.INFO) logging.info('info message') logging.debug('debug message') logging.warning('warning message') logging.error('error message') logging.critical('critical message') |
日志级别在INFO及以上的日志会输出到文件logger.log。
更加完善的日志功能
关键概念
Logger
、Handler
、Formatter
和Filter
是日志模块的基本概念,其包含的成员和方法可以查看官方文档。
- 记录器
Logger
,提供日志相关功能的调用接口 -
处理器
Handler
,将(记录器产生的)日志发送到合适的目的地 -
格式化器
Formatter
,指明输出的日志记录的格式 -
过滤器
Filter
,决定输出日志记录的粒度
Logger
Logging不直接实例化Logger对象,通过调用logging.getLogger(name)
创建Logger实例;若传入的参数name
值相同,则返回同一个Logger对象实例的引用。
1 2 |
logger = logging.getLogger('simple_example') |
若没有显式地创建Logger实例,默认创建一个root logger
,默认的日志级别是WARNING
,默认的处理器是StreamHandler
(即日志信息输出到标准输出),默认的格式化器Formatter(logging level:instance name:logging message
)。
Handler
通过Logger对象的addHandler()
方法为Logger对象添加0个或多个Handler的子类对象,将日志信息输出到设置的地方。比如,一个典型的应用场景:系统希望将所有的日志信息保存到log文件中,其中日志等级等于或高于ERROR
的消息还要在屏幕标准输出上显示,日志等级为CRITICAL
的还需要发送邮件通知;这种场景就需要3个独立的handler来实现需求。
需要注意的是,为Logger配置的handler不是Handler基类对象,而是Handler的子类对象,常用的Handler为StreamHandler
, FileHandler
, 和NullHandler
。
Formatter
Formatter用于设置日志输出的格式,可直接初始化对象,即formatter=logging.Formatter(fmt=None, datefmt=None)
。默认的日志格式fmt
为%(asctime)s - %(levelname)s - %(messages)
,默认的时间格式datefmt
为%Y-%m-%d %H:%M:%S
。
Filter
Filter 可用于Logger对象或Handler对象,用于提供比日志等级更加复杂的日志过滤方式。Filter在日志功能配置中是非必须的,对日志消息过滤需求比较复杂时配置使用。
日志产生流程
日志模块的使用
使用日志模块的关键在于日志的配置。开发者可以通过3种方法配置日志:
a. 在Python代码中显示创建Logger,Handler,Formatter和Filter对象,并调用各对象的配置函数进行日志配置
b. 将配置信息写到配置文件,通过读取配置文件进行日志配置
c. 将配置信息写到Dict
,通过读取配置字典进行日志配置
通过代码配置并使用日志模块
通过代码配置日志模块,简单方便,但不建议在大型项目中使用这种方法。
1) 创建Logger
1 2 3 4 |
import logging logger = logging.getLogger('simple_example') logger.setLevel(logging.DEBUG) |
2) 创建Handler
1 2 3 4 |
# create console handler and set level to warn ch = logging.StreamHandler() ch.setLevel(logging.WARNING) |
3) 创建Formatter
1 2 |
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') |
4) 配置Logger
1 2 3 4 5 6 |
ch.setFormatter(formatter) # add ch to logger # The final log level is the higher one between the default and the one in handler logger.addHandler(ch) |
5) 使用日志模块
1 2 3 4 5 6 |
logger.debug('debug message') logger.info('info message') logger.warn('warn message') logger.error('error message') logger.critical('critical message') |
输出结果(输出Warn及其以上的日志);
1 2 3 4 |
2018-01-21 20:54:30,605 - simple_example - WARNING - warn message 2018-01-21 20:54:30,606 - simple_example - ERROR - error message 2018-01-21 20:54:30,606 - simple_example - CRITICAL - critical message |
通过配置文件配置并使用日志模块
配置文件通常使用.ini
格式。日志模块调用fileConfig()
读取配置信息,完成日志配置,即logging.config.fileConfig('logging_config.ini')
。
文件logging_config.ini
的内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
[loggers] keys=root,simpleExample [handlers] keys=consoleHandler [formatters] keys=simpleFormatter [logger_root] level=DEBUG handlers=consoleHandler [logger_simpleExample] level=INFO handlers=consoleHandler qualname=simpleExample propagate=0 [handler_consoleHandler] class=StreamHandler level=DEBUG formatter=simpleFormatter args=(sys.stdout,) [formatter_simpleFormatter] format=%(asctime)s - %(name)s - %(levelname)s - %(message)s |
使用日志模块的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import logging import logging.config logging.config.fileConfig('logging_config.ini') logger = logging.getLogger('root') logger.debug('debug message') logger.info('info message') logger.warn('warn message') logger.error('error message') logger.critical('critical message') |
通过Dict对象配置并使用日志模块
基于Dict对象配置日志模块在python中应用广泛,比如Django、Flask项目采用这种方式。本文提供一个使用样例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
!/usr/local/bin/python -- coding: utf-8 -- import logging import logging.config config = { 'version': 1, 'formatters': { 'simple': { 'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s', }, }, 'handlers': { 'console': { 'class': 'logging.StreamHandler', 'level': 'DEBUG', 'formatter': 'simple' }, 'file': { 'class': 'logging.FileHandler', 'filename': 'logging.log', 'level': 'DEBUG', 'formatter': 'simple' }, }, 'loggers':{ 'root': { 'handlers': ['console'], 'level': 'DEBUG', # 'propagate': True, }, 'simple': { 'handlers': ['console', 'file'], 'level': 'WARN', } } } logging.config.dictConfig(config) print('logger:') logger = logging.getLogger('root') logger.debug('debug message') logger.info('info message') logger.warn('warn message') logger.error('error message') logger.critical('critical message') print('logger2:') logger2 = logging.getLogger('simple') logger2.debug('debug message') logger2.info('info message') logger2.warn('warn message') logger2.error('error message') logger2.critical('critical message') |
其他
学习Logging过程中,个人认为比较好的资源:
- 特别感谢Gevin的Python日志功能详解
- [Mario Corchero的A guide to logging in python
- Python logging 模块和使用经验
- Python中的logging模块