Python logging 模块详解
一、为什么要用 logging?
初学者常用 print() 来输出调试信息,但 print() 有如下缺点:
- 不方便管理输出等级(如错误信息 vs 普通信息)
- 不能自动记录时间、模块等信息
- 无法将信息同时输出到文件和屏幕
- 程序发布时必须手动删除调试信息
logging 模块是专门用于记录日志的标准模块,功能强大且灵活,适用于调试、运维、审计等场景。
二、最基本的用法
import logging
logging.basicConfig(level=logging.INFO)
logging.info("程序开始运行")
basicConfig 参数说明:
| 格式 | 描述 |
|---|---|
| filename | 指定创建一个 FileHandler,使用指定的文件名,而不是一个 StreamHandler。 |
| filemode | 如果指定了 filename,则以此 模式 打开文件。默认为 'a'。 |
| format | 为处理器使用指定的格式字符串。默认为由冒号分隔的属性 levelname、name 和 message。 |
| datefmt | 使用指定的日期/时间格式,该格式被 time.strftime() 接受。 |
| level | 将根日志记录器级别设置为指定的 级别。 |
| handlers | 如果指定,这应该是一个包含已创建处理器的可迭代对象,用于添加到根日志记录器。任何尚未设置格式化器的处理器都将被分配此函数中创建的默认格式化器。请注意,此参数与 filename 或 stream 不兼容——如果两者都存在,则会引发 ValueError。 |
三、日志等级(Level)
日志等级是指日志的重要程度,低级别包含的信息多,高级别只包含重要信息。
| 等级名称 | 英文 | 数值 | 用途说明 |
|---|---|---|---|
| 调试 | DEBUG | 10 | 最详细,开发调试时使用 |
| 信息 | INFO | 20 | 程序正常运行的信息 |
| 警告 | WARNING | 30 | 程序运行中可能出现的问题 |
| 错误 | ERROR | 40 | 程序出错,但未崩溃 |
| 严重错误 | CRITICAL | 50 | 程序崩溃或严重错误 |
示例:
logging.debug("调试信息")
logging.info("一般信息")
logging.warning("警告信息")
logging.error("错误信息")
logging.critical("严重错误")
默认只输出
WARNING及以上的等级,如果需要输出更低的日志,要设置level参数。
四、设置输出格式(format)
1. 日志格式:
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s [%(levelname)s] %(filename)s:%(lineno)d - %(message)s'
)
常见格式参数:
| 占位符 | 含义 |
|---|---|
%(asctime)s |
日志时间 |
%(levelname)s |
日志等级 |
%(message)s |
日志内容 |
%(filename)s |
文件名 |
%(lineno)d |
行号 |
%(name)s |
Logger 名称 |
2. 时间格式:
# 日志配置
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
handlers=[logging.FileHandler('app.log'), logging.StreamHandler()])
| 指令 | 含义 |
|---|---|
%a |
区域设置的缩写工作日名称。 |
%A |
区域设置的完整工作日名称。 |
%b |
区域设置的缩写月份名称。 |
%B |
区域设置的完整月份名称。 |
%c |
区域设置的适当日期和时间表示。 |
%d |
月份中的日期,以十进制数字 [01,31] 表示。 |
%f |
微秒,以十进制数字表示。[000000,999999]. |
%H |
小时(24 小时制),以十进制数字 [00,23] 表示。 |
%I |
小时(12 小时制),以十进制数字 [01,12] 表示。 |
%j |
一年中的第几天,以十进制数字 [001,366] 表示。 |
%m |
月份,以十进制数字 [01,12] 表示。 |
%M |
分钟,以十进制数字 [00,59] 表示。 |
%p |
区域设置的 AM 或 PM 等效项。 |
%S |
秒,以十进制数字 [00,61] 表示。 |
%U |
一年中的周数(周日作为一周的第一天),以十进制数字 [00,53] 表示。新年中第一个周日之前的任何一天都被视为第 0 周。 |
%u |
星期几(周一为 1;周日为 7),以十进制数字 [1, 7] 表示。 |
%w |
工作日,以十进制数字 [0(周日),6] 表示。 |
%W |
一年中的周数(周一作为一周的第一天),以十进制数字 [00,53] 表示。新年中第一个周一之前的任何一天都被视为第 0 周。 |
%x |
区域设置的适当日期表示。 |
%X |
区域设置的适当时间表示。 |
%y |
不带世纪的年份,以十进制数字 [00,99] 表示。 |
%Y |
带世纪的年份,以十进制数字表示。 |
%z |
时区偏移量,表示与 UTC/GMT 的正或负时间差,格式为 +HHMM 或 -HHMM,其中 H 表示十进制小时数字,M 表示十进制分钟数字 [-23:59, +23:59]。[1] |
%Z |
时区名称(如果不存在时区,则无字符)。已弃用。[1] |
%G |
ISO 8601 年份(类似于 %Y,但遵循 ISO 8601 日历年的规则)。年份从包含日历年第一个周四的那一周开始。 |
%V |
ISO 8601 周数(以十进制数字 [01,53] 表示)。一年中的第一周是包含该年第一个周四的那一周。周一是一周的开始。 |
%% |
字面上的 '%' 字符。 |
五、写入日志文件
logging.basicConfig(
level=logging.INFO,
filename='app.log',
filemode='w', # 写入模式:'w'覆盖, 'a'追加
format='%(asctime)s - %(levelname)s - %(message)s'
)
logging.info("日志写入文件成功")
注意:
basicConfig()只在首次调用logging时生效,重复调用无效。
六、高级用法:Logger、Handler、Formatter
当你想将日志分别输出到文件和控制台,或者有多个模块时,推荐使用高级配置。
1. Logger(日志记录器)
用于记录日志的入口。
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)
2. Handler(日志处理器)
决定日志输出到哪里,如控制台、文件等。
console_handler = logging.StreamHandler()
file_handler = logging.FileHandler('log.txt')
3. Formatter(日志格式器)
定义日志的格式。
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)
4. 完整配置
import logging
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)
# 控制台输出
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
# 文件输出
file_handler = logging.FileHandler('app.log')
file_handler.setLevel(logging.DEBUG)
# 设置格式
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)
# 添加 Handler 到 Logger
logger.addHandler(console_handler)
logger.addHandler(file_handler)
# 开始记录日志
logger.debug("调试信息")
logger.info("信息")
logger.warning("警告")
logger.error("错误")
logger.critical("严重错误")
七、补充:日志文件自动轮转
from logging.handlers import RotatingFileHandler
handler = RotatingFileHandler('app.log', maxBytes=1024*1024, backupCount=3)
logger.addHandler(handler)
表示日志文件最大 1MB,保留最近 3 个日志文件轮换。
八、总结
| 内容 | 说明 |
|---|---|
basicConfig() |
快速配置日志输出 |
| 日志等级 | 控制输出重要程度 |
| Logger / Handler / Formatter | 模块化、灵活控制日志 |
| 控制台 + 文件输出 | 可同时记录多个地方 |

浙公网安备 33010602011771号