Python logging 模块的原理和常用配置
前言
在 程序开发中,日志是调试、监控、问题排查的核心工具,而在python程序开发中,内置的 logging 模块是处理日志的首选方案。这篇博客主要汇总和总结logging模块的原理和常用配置。
一、logging 核心架构:4 个核心组件
logging 模块的设计遵循 “分层解耦” 思想,核心由 4 个组件(日志级别、格式化器、处理器、日志器)构成,理解它们就能灵活配置日志。
1.1 日志级别(Log Level)
日志级别用于区分日志的重要程度,logging 模块内置了 5 个核心级别(按严重程度从低到高)
| 级别名称 | 数值 | 适用场景 |
|---|---|---|
| DEBUG | 10 | 调试信息,如变量值、函数执行步骤,仅开发 / 测试环境使用 |
| INFO | 20 | 正常运行信息,如程序启动、任务完成,记录关键流程 |
| WARNING | 30 | 警告信息,如非致命错误、不规范使用,程序仍可运行 |
| ERROR | 40 | 错误信息,如功能执行失败、数据处理异常,影响部分功能 |
| CRITICAL | 50 | 严重错误,如程序崩溃、核心资源不可用,需立即处理 |
核心规则:只有日志级别 ≥ 日志器设置的级别时,日志才会被输出。例如日志器级别设为 INFO,那么 DEBUG 级别的日志会被过滤,INFO 及以上级别会被保留。
1.2 格式化器(Formatter)
格式化器用于定义日志输出的格式,控制日志中包含哪些信息(如时间、级别、模块、内容等),核心是通过格式字符串配置。
1.2.1 常用格式占位符
| 占位符 | 含义 |
|---|---|
| %(asctime)s | 日志记录的时间(默认格式:2026-02-23 10:00:00,123) |
| %(name)s | 日志器的名称 |
| %(levelname)s | 日志级别名称(如 INFO/ERROR) |
| %(levelno)s | 日志级别对应的数值 |
| %(filename)s | 日志所在的文件名(不含路径) |
| %(funcName)s | 日志所在的函数名 |
| %(lineno)d | 日志所在的行号 |
| %(message)s | 日志的具体内容(必选) |
| %(process)d | 进程 ID |
| %(thread)d | 线程 ID |
1.2.2 Formatter 基本用法
import logging
# 创建格式化器:自定义输出格式 + 时间格式
formatter = logging.Formatter(
fmt='%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S' # 自定义时间格式,可选
)1.3 处理器(Handler)
处理器决定日志的输出目标(控制台、文件、网络等),一个日志器可以绑定多个处理器,实现 “日志同时输出到控制台和文件” 的效果。
1.3.1 常用处理器类型
| 处理器类 | 作用 | 核心参数 |
|---|---|---|
| StreamHandler | 输出到控制台(stdout/stderr) | stream:指定输出流(默认 sys.stderr) |
| FileHandler | 输出到文件(覆盖 / 追加) | filename:文件路径;mode:模式(默认 ‘a’ 追加) |
| RotatingFileHandler | 按文件大小分割日志 | maxBytes:单个文件最大字节;backupCount:保留备份数 |
| TimedRotatingFileHandler | 按时间分割日志 | when:分割单位(S/ M/ H/ D/ W0-W6/midnight);interval:间隔;backupCount:保留备份数 |
| SMTPHandler | 发送日志到邮箱 | mailhost/fromaddr/ toaddrs/subject/ credentials:邮箱配置 |
1.3.2 Handler 基本用法
# 1. 控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO) # 处理器级别(仅输出≥该级别的日志)
console_handler.setFormatter(formatter) # 绑定格式化器
# 2. 文件处理器(按大小分割,单个文件最大10MB,保留5个备份)
from logging.handlers import RotatingFileHandler
file_handler = RotatingFileHandler(
filename='app.log',
maxBytes=10*1024*1024, # 10MB
backupCount=5,
encoding='utf-8' # 避免中文乱码
)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)1.4 日志器(Logger)
日志器是 logging 模块的核心入口,所有日志操作都通过日志器对象完成(而非直接调用 logging.debug () 等全局方法),支持层级继承(如 logger = logging.getLogger(‘app.db’) 继承 app 日志器的配置)。
1.4.1 日志器核心操作
# 1. 获取日志器(推荐使用模块名/项目名作为名称,避免全局冲突)
logger = logging.getLogger('my_blog_app')
# 2. 设置日志器级别(全局过滤,优先级最高)
logger.setLevel(logging.DEBUG)
# 3. 绑定处理器(可绑定多个)
logger.addHandler(console_handler)
logger.addHandler(file_handler)
# 4. 禁用日志传播(避免子日志器的日志被父日志器重复处理)
logger.propagate = False
# 5. 输出日志
logger.debug('调试信息:数据库连接参数')
logger.info('正常信息:用户登录成功')
logger.warning('警告信息:密码复杂度不足')
logger.error('错误信息:接口调用失败')
logger.critical('严重错误:数据库连接中断')1.4.2 日志器层级规则
- 日志器名称以 . 分隔表示层级,如 app → app.db → app.db.mysql;
- 子日志器默认继承父日志器的级别、处理器、格式化器;
- 若子日志器单独设置了级别 / 处理器,则优先使用自身配置。
二、常见的 logging 组合配置(可直接复用)
以下是可直接复制使用的 “生产级” 配置示例,实现:
- 日志同时输出到控制台(INFO 及以上)和文件(DEBUG 及以上);
- 文件日志按大小分割,避免单个文件过大;
- 中文无乱码,格式清晰;
- 避免重复输出日志。
import logging
from logging.handlers import RotatingFileHandler
import os
def setup_logger():
"""配置全局日志器"""
# 1. 定义日志器名称(推荐用项目名)
logger = logging.getLogger('blog_demo')
# 防止重复添加处理器(多次调用该函数时)
if logger.handlers:
return logger
# 2. 设置日志器全局级别(最低级别,让处理器过滤)
logger.setLevel(logging.DEBUG)
# 禁用日志传播,避免根日志器重复输出
logger.propagate = False
# 3. 创建格式化器
formatter = logging.Formatter(
fmt='%(asctime)s [%(threadName)s:%(thread)d] [%(name)s:%(lineno)d] %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
encoding='utf-8'
)
# 4. 配置控制台处理器(仅输出INFO及以上)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
console_handler.setFormatter(formatter)
# 5. 配置文件处理器(输出DEBUG及以上,按大小分割)
# 确保日志目录存在
log_dir = 'logs'
if not os.path.exists(log_dir):
os.makedirs(log_dir)
file_handler = RotatingFileHandler(
filename=os.path.join(log_dir, 'app.log'),
maxBytes=5*1024*1024, # 5MB
backupCount=10, # 保留10个备份
encoding='utf-8' # 中文编码
)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
# 6. 绑定处理器到日志器
logger.addHandler(console_handler)
logger.addHandler(file_handler)
return logger
# 使用示例
if __name__ == '__main__':
logger = setup_logger()
logger.debug('这是调试信息,仅输出到文件')
logger.info('这是普通信息,控制台和文件都输出')
logger.warning('这是警告信息')
logger.error('这是错误信息')
logger.critical('这是严重错误信息')三、总结
- 核心层级:日志器(Logger)是入口,处理器(Handler)决定输出目标,格式化器(Formatter)定义输出格式,日志级别控制日志过滤规则;
- 关键规则:日志器级别是全局过滤,处理器级别是局部过滤,只有日志级别同时≥两者才会输出;
- 实用配置:生产环境建议同时配置控制台(INFO 级)和文件(DEBUG 级)处理器,结合日志分割(按大小 / 时间)避免文件过大,且禁用日志传播防止重复输出。
到此这篇关于Python logging 模块深度解析的文章就介绍到这了,更多相关Python logging 模块内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
python GUI库图形界面开发之PyQt5图片显示控件QPixmap详细使用方法与实例
这篇文章主要介绍了python GUI库图形界面开发之PyQt5图片显示控件QPixmap详细使用方法与实例,需要的朋友可以参考下2020-02-02
Python实现爆破ZIP文件(支持纯数字,数字+字母,密码本)
这篇文章主要为大家分享了如何利用Python实现破解zip文件的密码,能实现破解纯数字、数字+字母、密码本等种类的密码,需要的可以参考一下2022-03-03


最新评论