PAYATHON 2026

如何将 httpx 日志路由到主程序的自定义命名空间?

数据小许

结论

标准库 logging 的配置无法把第三方库使用的 logger 名称改成 program.network.httpx。库通常通过 logging.getLogger(__name__) 获取 logger,名称由库自身的模块名决定,例如 httpx 或 httpcore。logger 只沿实际名称的层级传播:httpx.client 会向 httpx 传播,不会传播到 program.network。

你可以让 httpx、httpcore 的日志使用同一个 handler,也可以在根 logger 上按名称过滤。这样可以集中处理日志,但 LogRecord.name 仍保持原值,这些记录也不会成为 program.network 的子 logger。

将库日志交给同一个 handler

在主程序中使用 dictConfig 为相关 logger 配置 handler。将 disable_existing_loggers 设为 False,以免禁用其他已创建的 logger:

import logging.config

logging.config.dictConfig({
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "standard": {
            "format": "%(asctime)s %(name)s %(levelname)s: %(message)s",
        },
    },
    "handlers": {
        "network": {
            "class": "logging.StreamHandler",
            "formatter": "standard",
        },
    },
    "loggers": {
        "httpx": {
            "handlers": ["network"],
            "level": "INFO",
            "propagate": False,
        },
        "httpcore": {
            "handlers": ["network"],
            "level": "INFO",
            "propagate": False,
        },
    },
})

import httpx

if __name__ == "__main__":
    httpx.get("https://www.example.com")

logger 配置会作用于对应名称及其子 logger。设为 propagate: False 后,记录不会继续传到根 logger,因此可以避免重复处理。如果希望根 logger 也处理这些记录,可以移除该设置或将其设为 True,并留意是否出现重复输出。日志级别可按需调整。

示例配置了 httpx 和 httpcore。实际请求会产生哪些 logger 名称,取决于使用的库。可以先查看输出中的 %(name)s,再补充相应配置。

按自定义规则分流

你可以把 handler 配置在根 logger 上,再通过 filter 根据 record.name 选择要处理的记录。这样可以设置路由规则,记录名称仍是库原本的名称。也可以编写自定义 handler,对选中的记录进行额外处理;这也不会改变 logger 的父子关系。

如果只想让自己写的模块使用 program.network 层级,可以在这些模块中显式创建对应名称的 logger:

import logging

logger = logging.getLogger("program.network")
logger.info("request started")

要让 program.network 接收第三方库的记录,需要在 httpx、httpcore 等实际 logger 上配置 handler,或使用自定义路由逻辑。只在 program.network 上添加 handler,无法接收到名称为 httpx 的记录。

注意事项

  • logging.getLogger("program.network.httpx") 创建的是一个独立命名的 logger,不会自动接管 httpx logger。
  • 格式化器显示自定义名称,只会改变日志文本的展示,不会改变记录的 name 或传播路径。
  • 如果同时在库 logger 和根 logger 上添加相同的输出 handler,同一条记录可能会输出多次。

备注:内容仅供参考。