python 内置模块(一):logging
python
本文字数:1.3k 字 | 阅读时长 ≈ 5 min

python 内置模块(一):logging

python
本文字数:1.3k 字 | 阅读时长 ≈ 5 min

1. 为什么要用 logging 模块

logging 模块主要是用来记录程序运行日志,在调试的时候我们是可以直接看到是哪一步出了问题,但是程序运行时我们是不知道的,只能看到结果错误,如果能够实时记录相关的内容和状态,就会有更多的信息来排查问题,因此,日志记录非常重要

logging 模块相比于 print 有什么优点?

2. logging 日志级别分类

logging 日志的输出氛围下面六个级别,准确来讲是五个(NOTEST 不算,因为他继承自父类),当我们设置 logging 一个级别如 INFO 级别后,大于等于他的信息将被输出,即 INFO,WARNING,ERROR 以及 CRITICAL 信息即将被输出

注意 NOTSET 不是最低级别的意思,他是继承自父类,logging 是可以继承的,因此父类用什么级别,子类和他一样

Level 用法 等级
NOTSET 不设置 按照父 logger 级别来过滤日志 0
DEBUG 调试需要的详细信息 10
INFO 确认程序正常工作 20
WARNING 程序仍旧正常工作,但是报警未来可能出现的问题(如空间不够) 30
ERROR 程序某些功能不能继续运行 40
CRITICAL 非常严重的错误,程序无法继续运行 50

3. logging 日志的具体使用

下面举几个例子来演示日志的使用方法

1. logger 等级输出

首先我们在 basicConfig 函数中设置 logging 的基本信息,有等级 level 以及 format 格式,然后初始化一个 logger 对象并对其命名,logger 在记录下面记录日志的时候,由于 DEBUG 信息等级低于 INFO 信息,因此 DEBUG 信息不输出

import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger('test')
logger.info('This is a log info')
logger.debug('Debugging')
logger.warning('Warning exists')

'''
2023-01-09 11:23:53,259 - test - INFO - This is a log info
2023-01-09 11:23:53,259 - test - WARNING - Warning exists
'''

2. 深入理解 basicConfig 函数

其中 basicConfig 是一个很重要的函数,还有多个参数,这里介绍几个比较常用的,例如:level 输出等级,filename 默认创建一个 FileHandler,filemode 输出文件格式(只读只写等),datefmt 输出日期格式,format 输出词条的前缀,basicConfig 的其他参数在这里查到

import logging
logging.basicConfig(level=logging.DEBUG, filename='output.log', 
					filemode = 'a',
					datefmt='%Y/%m/%d %H:%M:%S', 
					format='%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(module)s - %(message)s')
logger = logging.getLogger('test')
logger.info('This is a log info')

'''
output.log
2023/01/09 13:03:08 - test - INFO - 115 - a - This is a log info
'''

logging 默认使用 StreamHandler 来处理输出,如果我们加入 filename 参数,就被改为 FileHandler,此时我们命令行不在有输出,而是将输出加到了 output.log 文件,如果也要在命令行输出,只需要将 StreamHandler 再次加入即可(下面介绍如何加入额外的 Handler)

filemode 是输出到文件的方式,默认为 a,即加到文件末尾,其他格式参考filemode
datafmt 函数会更改时间的输出,时间格式参考time.strftime()
format 是输出每一行的开头格式,格式参考

logging 日志的 Handler 用法

上面我们介绍了 basicConfig 函数,他可以设置默认的 StreamHandler 输出或者设置 FileHandler 输出,如果我们不适用 basicConfig 函数的话,要更改输出的方式就需要自己设置 Handler 部分了

Handler的文档都可在这里找到

1. 一个简单的 FileHandler 示例

之前的 basicConfig 方法有几个比较重要的参数,level,format,datafmt,在这里默认的 logger 有 setLevel 函数可以设置 level,Handler 则有 setLevel 以及 setFormatter 来分别设置 level 和 foramt

import logging

logger = logging.getLogger('test')
logger.setLevel(level=logging.INFO)
# 设置filehandler
handler = logging.FileHandler(filename='output.log', mode='a')
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
handler.setLevel(level=logging.WARNING)  # handler的level会覆盖logger的level
logger.addHandler(handler)

logger.info('This is a log info')
logger.warning('Warning exists')

'''
2023-01-09 14:34:28,580 - test - WARNING - Warning exists
'''

2. 使用多个 Handler

上面我们使用了 FileHandler 了以后,只有输出文件中有信息,命令行没有实时输出,这里只需要加上 StramHandler 即可,恰巧 FileHandler 也是继承自 StreamHandler

import logging

logger = logging.getLogger('test')
logger.setLevel(level=logging.DEBUG)

# StreamHandler
stream_handler = logging.StreamHandler()
stream_handler.setLevel(level=logging.DEBUG)
logger.addHandler(stream_handler)

# FileHandler
file_handler = logging.FileHandler('output.log')
file_handler.setLevel(level=logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)

# Log
logger.info('This is a log info')
logger.debug('Debugging')
logger.warning('Warning exists')

'''
This is a log info
Debugging
Warning exists

# output.log
2023-01-09 14:54:12,875 - test - INFO - This is a log info
2023-01-09 14:54:12,875 - test - WARNING - Warning exists
'''

对应上面的讲解,就很容易理解为什么会输出这些内容

4月 06, 2025
3月 10, 2025
12月 31, 2024