Python -- logging --日志模块
Python logging
模块自学指南
日志记录(logging)是一种非常重要的工具,它可以帮助我们跟踪程序的运行状态,调试错误以及记录重要信息。
logging
是 Python 内置的日志记录工具,用于替代 print(),提供更灵活、强大的日志管理能力
一、为什么用 logging 替代 print?
- 级别控制:区分调试/信息/警告/错误日志
- 多输出目标:同时输出到控制台/文件/邮件/网络
- 格式统一:标准化时间戳、模块名、行号等信息
- 异步处理:避免阻塞主线程
- 按需启用:生产环境可关闭调试日志
二、四大核心组件
组件 | 作用 | 示例 |
---|---|---|
Logger | 记录日志的入口 | logger = logging.getLogger('app') |
Handler | 日志输出位置(控制台/文件等) | FileHandler('app.log') |
Filter | 过滤特定日志 | 自定义过滤规则 |
Formatter | 日志格式 | '%(asctime)s - %(message)s' |
三、五大日志级别(从低到高)
logging.DEBUG # 调试细节 (10)
logging.INFO # 常规信息 (20)
logging.WARNING # 警告事件 (30)
logging.ERROR # 错误事件 (40)
logging.CRITICAL # 严重错误 (50)
设置全局级别:
logging.basicConfig(level=logging.INFO)
四、快速入门示例
import logging# 基础配置(输出到控制台)
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s [%(levelname)s] %(message)s',datefmt='%Y-%m-%d %H:%M:%S'
)# 记录日志
logging.debug("调试信息") # 生产环境自动忽略
logging.info("程序启动")
logging.warning("磁盘空间不足")
logging.error("连接数据库失败")
五、高级用法详解
- 输出到文件 + 控制台
logger = logging.getLogger("my_app")
logger.setLevel(logging.DEBUG) # 设置Logger级别# 文件处理器(记录DEBUG以上)
file_handler = logging.FileHandler("app.log")
file_handler.setLevel(logging.DEBUG)# 控制台处理器(只记录INFO以上)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)# 设置日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)# 添加处理器
logger.addHandler(file_handler)
logger.addHandler(console_handler)
- 日志文件轮转(防止过大)
from logging.handlers import RotatingFileHandler# 每个文件最大10MB,保留3个备份
rotating_handler = RotatingFileHandler("app.log", maxBytes=10*1024*1024, backupCount=3
)
- 异常栈记录
try:1/0
except Exception as e:logging.error("发生异常: %s", e, exc_info=True) # 记录完整堆栈# 或直接使用 logger.exception(e)
- 按模块区分日志
# 主模块
main_logger = logging.getLogger("main")
main_logger.info("主模块加载")# 子模块
sub_logger = logging.getLogger("main.submodule")
sub_logger.debug("子模块详细日志")
六、最佳实践
-
避免使用 root logger
始终通过getLogger(name)
创建具名Logger# 推荐 ✔️ logger = logging.getLogger(__name__)# 不推荐 ❌ logging.info("...")
-
配置分离
使用logging.config.dictConfig()
从JSON/YAML加载配置:import logging.configconfig = {'version': 1,'handlers': {'file': {'class': 'logging.FileHandler', 'filename': 'app.log'}},'root': {'level': 'INFO', 'handlers': ['file']} }logging.config.dictConfig(config)
-
生产环境建议
- 使用
WARNING
作为默认级别 - 对错误日志配置邮件报警(
SMTPHandler
) - 使用
TimedRotatingFileHandler
按天分割日志
- 使用
七、完整工作流示例
import logging
from logging.handlers import RotatingFileHandlerdef setup_logger():logger = logging.getLogger("my_app")logger.setLevel(logging.DEBUG)# 控制台输出console = logging.StreamHandler()console.setLevel(logging.INFO)# 文件输出(带轮转)file = RotatingFileHandler("app.log", maxBytes=1e6, backupCount=3)file.setLevel(logging.DEBUG)# 格式设置fmt = '%(asctime)s | %(levelname)8s | %(module)s:%(lineno)d - %(message)s'formatter = logging.Formatter(fmt, datefmt='%Y-%m-%d %H:%M:%S')console.setFormatter(formatter)file.setFormatter(formatter)logger.addHandler(console)logger.addHandler(file)return loggerif __name__ == "__main__":logger = setup_logger()logger.info("程序启动")try:# ...业务代码...except Exception as e:logger.exception("致命错误")
学习资源推荐
- 官方文档
- Logging Cookbook
- 调试技巧:临时提升日志级别
logging.getLogger("requests").setLevel(logging.DEBUG)
关键点:理解日志级别传播机制、合理设计Logger命名空间、生产环境使用异步日志库(如
loguru
或structlog
)提升性能。