You need to enable JavaScript to run this app. Python3.7下使用requests写日志到文件时缺失send、reply及响应头内容的问题
优惠活动
大模型
产品
解决方案
定价
更多

Python3.7下使用requests写日志到文件时缺失send、reply及响应头内容的问题

问题根因

你当前日志文件中缺失的send:/reply:/header:类内容,根本没有接入Python标准logging的日志投递流程。
当你设置http_client.HTTPConnection.debuglevel = 1后,http.client模块输出的这类详细调试信息,是直接往标准输出流(sys.stdout)写入的原生打印内容,和logging体系完全独立。
这也直接解释了两个观测到的现象:

  • 控制台默认承接stdout的全部输出,所以能完整看到这部分调试信息
  • 你给urllib3 logger挂载的文件日志处理器,只能接收通过logging接口投递的日志(也就是目前日志里已有的“新建HTTPS连接”“请求返回状态码”这两条记录),完全捕获不到这些绕过logging流程的原生打印内容

全量日志写入的实现方案

有两种可落地的解决路径,其中第二种是生产环境推荐的规范方案:

方案1:拦截重定向标准输出

既然这部分调试内容是往stdout写入的,就可以通过自定义双写流,让stdout的输出同时保留在控制台、追加写入到日志文件。注意不要直接把系统stdout完全替换为文件句柄,否则控制台会丢失全部输出内容。
可直接运行的示例代码:

import sys
import requests
import logging
import http.client as http_client

# 开启http.client的详细调试输出
http_client.HTTPConnection.debuglevel = 1

# 原有urllib3 logging配置保持不变
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

# 配置文件日志格式
handler = logging.FileHandler('test2.log', mode='a', encoding='utf-8')
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
handler.setLevel(logging.DEBUG)
requests_log.addHandler(handler)

# 自定义双写流:同时把stdout内容写到控制台和日志文件
class DualWriter:
    def __init__(self, *target_writers):
        self.target_writers = target_writers
    def write(self, content):
        for writer in self.target_writers:
            writer.write(content)
    def flush(self):
        for writer in self.target_writers:
            writer.flush()

# 替换系统stdout为双写对象
log_writer = open('test2.log', 'a', encoding='utf-8')
sys.stdout = DualWriter(sys.__stdout__, log_writer)

# 发起请求
requests.get('https://httpbin.org/headers')

该方案的缺陷:抓取到的stdout调试内容没有统一的日志格式,会和原有logging输出的内容混杂,缺少时间戳、日志级别标记,日志可读性较差。

方案2:使用urllib3原生日志能力替代http.client的debug打印(推荐)

urllib3本身已经内置了完整的请求/响应细节日志能力,完全不需要依赖http.client.debuglevel的stdout打印。只要打开对应层级logger的DEBUG级别,所有请求发送、响应返回的详细内容都会通过logging体系正常投递,自然就能被你的文件日志处理器捕获,和原有日志保持统一格式。
需要调整的配置逻辑:

  • 删除http_client.HTTPConnection.debuglevel = 1代码行,避免冗余的stdout打印
  • 除了顶层的urllib3 logger,还要把负责连接细节日志的urllib3.connection logger设置为DEBUG级别,确保请求/响应头的内容能正常投递
    调整后的核心配置片段:
import requests
import logging

# 不需要手动开启http.client的debuglevel
# http_client.HTTPConnection.debuglevel = 1

logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)

# 配置统一的文件日志处理器
handler = logging.FileHandler('test2.log', mode='a', encoding='utf-8')
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
handler.setLevel(logging.DEBUG)

# 遍历挂载需要开启debug的logger
for logger_name in ["urllib3", "urllib3.connection"]:
    logger = logging.getLogger(logger_name)
    logger.setLevel(logging.DEBUG)
    logger.addHandler(handler)
    logger.propagate = True

requests.get('https://httpbin.org/headers')

该方案的优势:所有日志都走统一的logging管道,格式整齐、可追溯,没有冗余的stdout输出,是生产环境推荐的配置方式。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.31 05:54:04