系列文章目录
一、日志级别
-
日志级别,严重程度由低到高:
- DEGUG(调试):程序员用来调试程序的;
- INFO(消息):程序正常运行时,记录一些需要的信息;
- WARGING(警告):程序运行过程中,有不正常的地方,可能会导致错误,但目前对程序影响不大;
- ERROR(错误):程序运行过程中,发生错误,但程序可以自我修复,继续运行;
- CRITICAL(危险):十分严重的错误,程序无法自我修复,导致程序停止运行。
-
默认级别为WARNING,严重等级高于此级别的事件才会被记录到日志内,低于此级别的事件会被忽略。
二、logging模块
主要是用来记录程序的日志:
1.基本用法:
# 配置日志
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 获取日志对象
logger = logging.getLogger(__name__)
# 设置记录的内容
logger.debug('调试用的信息')
logger.info('正常运行')
logger.warning('警告信息')
logger.error('出错了!')
logger.critical('严重的错误,崩溃了')
默认会在终端输出:
2021-07-12 11:19:41,863 - __main__ - WARNING - 警告信息
2021-07-12 11:19:41,864 - __main__ - ERROR - 出错了!
2021-07-12 11:19:41,864 - __main__ - CRITICAL - 严重的错误,崩溃了
注意:默认级别是WARNING,所以比它级别低的DEBUG和INFO没有记录下来。
2.基本配置——basicConfig()
的参数
-
日志格式——
format
:# 日志时间-日志级别-日志消息 format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' # 2021-07-12 11:19:41,863 - __main__ - WARNING - 警告信息
“-”不是固定的,它可以是任意一个符号,起连接符的作用。
参数 作用 %(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 %(message)s 打印日志消息 -
时间格式——
datefmt
:该参数设置的是
%(asctime)s
的格式,它与data模块中的时间格式定义是一样的:datefmt='%Y-%m-%d %H:%M:%S %p'
-
日志级别——
level
:日志级别保存在loggin模块中,因为是常量,所以是全大写形式。
level=logging.INFO
-
日志输出的文件——
filename
:不指定时,输出到终端,若指定一个文件,则输出到该文件。文件的编码默认为系统的默认编码。
三、日志详细配置
-
日志的配置比较复杂,可以将其以字典形式单独写在一个配置文件中。
-
logging日志的配置项主要包括:
-
日志输出格式的配置项——
formatters
:可以定义多个格式,通过格式名称在不同的地方用。
'formatters': { '格式名称1': { 'format': '%(asctime)s - %(levelname)s - %(message)s' }, '格式名称2': {...}, # 更多格式 },
-
过滤器对象的配置项——
filters
(暂时用不到):之前对日志的分级是对日志的简单过滤,使用
filters
配置项,可以实现更加详细的过滤。 -
处理器对象的配置项——
handlers
:它接收日志输出内容的。
'handlers': { # 输出到终端 'handler名称1':{ # 可以接收日志的最低等级 'level': 'DEBUG', # 打印到屏幕 'class': 'logging.StreamHandler', # '格式2'就是famtters中的格式 'formatter': '格式2' }, # 输出到文件 'handler名称2':{ # 可以接收日志的最低等级 'level': 'INFO', # 输出到文件 'class': 'logging.FileHandler', # 指定文件 'filename': '文件路径', # 格式 'formatter': '格式1', # 日志文件的编码 'encoding': 'utf-8' }, # 更多handler
-
记录器对象的配置项——
loggers
:它是输出日志内容的。
'loggers': { 'logger名称1': { # 指定日志输出内容的接收对象, 此处会同时输出到文件和终端 'handlers': ['handler名称1','handler名称2'], # 输出日志的最低等级,只管输出,能不能被接收,就看handlers中设置的等级了 'level': 'DEBUG', # 与日志继承有关,默认为True,不使用继承时应改为False 'propagate': False, }, 'logger名称2': {...}, # 更多logger }
-
-
handler
与logger
的关系:logger
只负责输出日志内容给handler
,handler
则根据自身的配置,决定最终输出到文件或终端的日志内容。
四、加载配置并使用日志
from logging import config, getLogger
# 从配置文件导入配置,此处假设配置字典名称为LOGGING_DIC
from settings import LOGGING_DIC
# 加载配置,配置字典LOGGING_DIC在settings.py文件下
config.dictConfig(LOGGING_DIC)
# 实例化Logger对象
logger1 = getLogget('logger名称1')
logger2 = getLogget('logger名称2')
# 通过Logger对象记录日志
logger1.info('logger1消息日志')
logger2.error('logger2的错误日志')
五、日志命名和日志轮转
-
日志名称的命名:
日志名称是区分日志业务归属的一种重要标识。也就是说,通过日志名称应该容易的得知该日志所属的模块或业务。
比如,用户交易相关的应该起名为“用户交易”,用户登录相关的应该为“用户登录”。
注意:如果
getLogger
在配置中匹配不到传入的日志名,而配置中恰好有一个空的日志名''
,那么getLogger
就会匹配这个空的日志名。 -
日志轮转:
日志需要长期保存,在此期间日志文件的大小也会越来越大。为了防止单个日志文件过大,就需要在日志文件达到一定大小时,再重现建立一个日志文件保存日志。
需要使用时,配置
handlers
项,重点在于class
项:'handler名称3':{ 'level': 'DEBUG', # 输出到轮转文件接收对象 'class': 'logging.handlers.RotatingFileHander', # 日志文件大小的最大值,比如5M 'mxBytes': 1024*1024*5, 'filename': '文件路径', 'formatter': '格式1', # 日志文件的最大数量 'backupCount': 500, 'encoding': 'utf-8' },