You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

代码说明

  1. 清除默认处理器:移除根日志器的所有默认处理器,避免多余的控制台日志输出
  2. 文件日志配置:仅保留文件处理器,负责将所有INFO及以上级别的日志写入文件
  3. 自定义异常处理:通过sys.excepthook为未处理异常添加时间戳,同时保留Python默认的异常输出样式
  4. print语句保留:print会正常输出到控制台,无需额外配置

内容的提问来源于stack exchange,提问作者Ali Abdi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 23:25:18