Python日志配置需求:控制台仅显print、未处理异常并支持时间戳
问题:Python日志配置异常及需求实现
需求说明
我已将Python日志配置为同时输出至文件与流,期望实现:
- 控制台仅显示
print语句及Python默认输出的未处理exception,其余日志信息仅写入日志文件 - 解决设置
StreamLogging.setLevel(level=logging.CRITICAL)后,控制台仍显示API连接类日志的问题 - 恢复Python默认
stderr输出样式,并在输出前添加%(asctime)s格式的时间戳
我的日志代码
import logging FileLoggingFormat = f"%(message)s" FileLoggingDate = r"%m/%d/%Y %H:%M:%S" logging.basicConfig(level=logging.INFO) logger = logging.getLogger() # Add StreamHandler StreamLogging = logging.StreamHandler() logger.addHandler(StreamLogging) StreamLogging.setFormatter(logging.Formatter("%(message)s")) StreamLogging.setLevel(level=logging.CRITICAL) # Add FileHandler FileLogging = logging.FileHandler( filename="Log.log", mode="w", encoding="utf-8" ) logger.addHandler(FileLogging) FileLogging.setFormatter(logging.Formatter(FileLoggingFormat, FileLoggingDate))
❌ 不符合预期的控制台输出
(打印语句用📝标记)
📝 Port: 1523 📝 NotFound. INFO:library.connection.connection:Connecting... Traceback (most recent call last): File "c:\Users\test.py", line 20, in <module> f.write(message) TypeError: write() argument must be str INFO:library.session.session:Session stopped Session stopped
✅ 符合预期的控制台输出(基础版)
(仅显示打印语句与未处理异常)
📝 Port: 1523 📝 NotFound. Traceback (most recent call last): File "c:\Users\test.py", line 20, in <module> f.write(message) TypeError: write() argument must be str
✅ 符合预期的控制台输出(带时间戳版)
(仅显示打印语句与未处理异常,异常前添加时间戳)
2022/10/22 10:16:03.678 📝 Port: 1523 2022/10/22 10:16:03.700 📝 NotFound. 2022/10/22 10:16:03.706 Traceback (most recent call last): File "c:\Users\test.py", line 20, in <module> f.write(message) TypeError: write() argument must be str
解决方案
问题根源
logging.basicConfig(level=logging.INFO)会自动为根日志器添加一个默认的StreamHandler,后续手动添加的第二个StreamHandler与默认处理器同时工作,而默认处理器未设置级别限制,导致INFO级别的API连接日志仍会输出到控制台。
修正后代码
import logging import sys from datetime import datetime # 文件日志配置 file_log_format = "%(message)s" file_log_datefmt = r"%m/%d/%Y %H:%M:%S" # 获取根日志器并清除所有默认处理器 root_logger = logging.getLogger() for handler in list(root_logger.handlers): root_logger.removeHandler(handler) # 设置根日志级别,确保文件能捕获所有INFO及以上日志 root_logger.setLevel(logging.INFO) # 配置文件处理器 file_handler = logging.FileHandler( filename="Log.log", mode="w", encoding="utf-8" ) file_formatter = logging.Formatter(file_log_format, file_log_datefmt) file_handler.setFormatter(file_formatter) root_logger.addHandler(file_handler) # 自定义异常处理函数:添加时间戳并保留默认输出样式 def custom_excepthook(exc_type, exc_value, exc_traceback): # 生成带毫秒的时间戳 timestamp = datetime.now().strftime("%m/%d/%Y %H:%M:%S.%f")[:-3] print(timestamp, file=sys.stderr) # 调用系统默认异常处理逻辑,保持原样式 sys.__excepthook__(exc_type, exc_value, exc_traceback) # 替换系统默认的异常处理钩子 sys.excepthook = custom_excepthook
代码说明
- 清除默认处理器:移除根日志器的所有默认处理器,避免多余的控制台日志输出
- 文件日志配置:仅保留文件处理器,负责将所有INFO及以上级别的日志写入文件
- 自定义异常处理:通过
sys.excepthook为未处理异常添加时间戳,同时保留Python默认的异常输出样式 - print语句保留:
print会正常输出到控制台,无需额外配置
内容的提问来源于stack exchange,提问作者Ali Abdi
相关产品推荐
相关产品推荐

