Python 日志继承配置的正确实现方式

夏辰同学_9135

夏辰同学_9135

2026-08-07

333人浏览

原创

Python 日志继承配置的正确实现方式

本文详解如何在 Python 包中通过 logging.config.dictConfig 正确初始化日志配置,确保子模块能自动继承根 logger 设置,解决因配置位置错误、字段名不规范或格式器缺失导致的日志不输出问题。

本文详解如何在 python 包中通过 `logging.config.dictconfig` 正确初始化日志配置,确保子模块能自动继承根 logger 设置,解决因配置位置错误、字段名不规范或格式器缺失导致的日志不输出问题。

在构建可复用的工具包(如 core)时,统一日志配置是提升可观测性的关键一步。但若配置不当,即使子模块调用 logging.getLogger(__name__),日志也可能静默丢失——这通常并非代码逻辑错误,而是日志系统初始化时机与配置结构的问题。以下为经过验证的专业实践方案。

✅ 关键修正点

  1. 配置文件位置必须是 __init__.py,而非 __main__.py
    __main__.py 仅在执行 python -m core 时触发,而包导入(如 from core.utils import test)会首先执行 core/__init__.py。将日志初始化逻辑移至此处,才能确保所有子模块在首次导入前完成 logger 树的构建。

  2. formatter 字段名必须为 "format",而非 "fmt"
    logging.config.dictConfig 严格遵循 官方字典配置 Schema,"format" 是唯一识别的日志格式字符串键。使用 "fmt" 将导致 formatter 初始化失败,进而使 handler 无法格式化日志。

    Python Use Agent
    Python Use Agent

    智能执行Python任务,自动生成、执行代码并反馈结果,无需额外配置,兼容旧命令。

    下载
  3. 日志格式字段需匹配所用 formatter 类型

    • 若使用标准 logging.Formatter:应使用 %(levelname)s(如 "INFO"),%(levelprefix)s 是无效字段;
    • 若依赖 uvicorn.logging.DefaultFormatter(支持彩色 INFO: 前缀),则需显式指定其类路径,并保留 %(levelprefix)s:
      "formatters": {
          "default": {
              "()": "uvicorn.logging.DefaultFormatter",  # 启用 Uvicorn 格式器
              "format": "%(levelprefix)s %(asctime)s  %(name)s:%(lineno)d: %(message)s",
              "datefmt": "%Y-%m-%d %H:%M:%S",
          }
      }

✅ 完整可运行配置示例

# core/__init__.py
import logging
import logging.config
from pydantic import BaseModel


class BaseLoggerConfig(BaseModel):
    LOG_FORMAT: str = "%(levelname)s %(asctime)s  %(name)s:%(lineno)d: %(message)s"
    DATEFMT: str = "%Y-%m-%d %H:%M:%S"
    LOG_LEVEL: int = logging.INFO

    version: int = 1
    disable_existing_loggers: bool = False

    formatters: dict = {
        "default": {
            "format": LOG_FORMAT,      # ⚠️ 必须是 'format',非 'fmt'
            "datefmt": DATEFMT,
        }
    }

    handlers: dict = {
        "default": {
            "formatter": "default",
            "class": "logging.StreamHandler",
            "stream": "ext://sys.stderr",
        }
    }

    loggers: dict = {}

    def __init__(self, name: str, **data):
        super().__init__(**data)
        # 为当前包名(如 'core')创建 logger 配置,并禁用传播以避免重复输出
        self.loggers[name] = {
            "handlers": ["default"],
            "level": self.LOG_LEVEL,
            "propagate": False,
        }


# 初始化:在包导入时立即生效
LOG_CONFIG = BaseLoggerConfig("core")  # 使用包名 'core',非 __name__
logging.config.dictConfig(LOG_CONFIG.dict())
# core/utils.py
import logging

logger = logging.getLogger(__name__)  # → 'core.utils'

def test():
    logger.info(f"I am a log from {__name__}")
# test.py
from core.utils import test

if __name__ == "__main__":
    test()  # 输出:INFO 2024-11-30 11:06:28  core.utils:8: I am a log from core.utils

⚠️ 注意事项与最佳实践

  • propagate=False 的含义:在 core logger 上设置 propagate=False 可防止日志向上冒泡至 root logger(避免被未配置的 root handler 二次处理或丢弃),但需确保 core 及其子 logger 均被显式配置在 loggers 字典中;否则子模块(如 core.utils)将 fallback 到 root logger,而 root 默认 level 为 WARNING,导致 INFO 日志被忽略。
  • 动态 logger 注册(进阶):若需支持任意子模块自动注册,可在 __init__.py 中监听 logging.getLogger 调用,或改用 logging.setLoggerClass() 自定义 logger 工厂。
  • 测试验证技巧:在 test.py 中添加 print(logging.getLogger('core.utils').level) 和 print(logging.getLogger('core.utils').handlers),确认 logger 实例已正确继承配置。

通过以上调整,日志系统即可在包层级完成声明式初始化,所有 from core.xxx import yyy 的导入均能无缝获得一致、可控的日志能力——这才是 Python 包内日志继承的稳健实现方式。

Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

python

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1651

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4044

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1649

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

23397

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

2867

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

2907

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1143

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

596

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2243

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程