Python 中如何同时把日志输出到文件和控制台?
Python 同时输出日志到文件和控制台:创建两个 Handler——FileHandler 写文件、StreamHandler 打控制台,添加到同一个 Logger。本文给出完整配置示例。
核心做法:给 Logger 添加两个 Handler——FileHandler 负责写文件,StreamHandler 负责输出控制台。每个 Handler 可以设置不同的级别和格式。
完整示例
import logging
logger = logging.getLogger('my_app')
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
# 文件 Handler:记录所有级别
file_handler = logging.FileHandler('app.log')
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
# 控制台 Handler:只显示 INFO 及以上
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
console_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.addHandler(console_handler)
logger.debug("调试信息") # 只写入文件
logger.info("普通信息") # 文件 + 控制台
logger.error("错误信息") # 文件 + 控制台
要点说明
- Logger 级别 vs Handler 级别:Logger 的级别是"总开关",Handler 级别是各自的过滤。Logger 设为 DEBUG 才能让 DEBUG 消息到达 Handler,再由各 Handler 自己的级别决定是否输出。
- 文件轮转:用
RotatingFileHandler替代FileHandler防止日志文件无限增长:
from logging.handlers import RotatingFileHandler
file_handler = RotatingFileHandler('app.log', maxBytes=10*1024*1024, backupCount=5)
观测云对照
生产环境建议日志统一输出到控制台(stdout),由观测云 DataKit 采集容器/进程的标准输出,不需要应用自己管理日志文件。
常见问题(FAQ)
Q:为什么控制台没有输出 DEBUG 日志?
A:检查两个级别——Logger 的和 Handler 的,两者都要设为 DEBUG。
Q:日志重复输出了怎么办?
A:可能是重复调用了 addHandler。在模块级别配置一次即可,或用 if not logger.handlers: 判断防止重复添加。
Q:能用 dictConfig 配置文件管理吗?
A:可以,logging.config.dictConfig() 支持用字典配置多个 Handler 和 Logger,适合复杂项目。