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

如何在Python中为整个应用使用自定义控制台日志记录器?

Python全局日志格式配置方案

核心思路

Python的日志系统是层级式的:所有logger实例都隶属于树形结构,子logger默认会将日志向上传播到父logger,直至根logger(logging.getLogger()不带参数获取的实例)。因此只需配置根logger或应用级顶级父logger,所有子logger(包括各模块的logging.getLogger(__name__))都会自动继承其格式、handler等配置,无需逐个模块设置。

实现步骤

1. 自定义带颜色的日志格式器

实现支持级别缩写和控制台颜色的自定义格式器:

import logging
from logging import StreamHandler

class ColoredFormatter(logging.Formatter):
    # ANSI控制台颜色码
    _COLOR_MAP = {
        logging.DEBUG: "\033[94m",    # 蓝色
        logging.INFO: "\033[92m",     # 绿色
        logging.WARNING: "\033[93m",  # 黄色
        logging.ERROR: "\033[91m",    # 红色
        logging.CRITICAL: "\033[95m"  # 紫色
    }
    _RESET_CODE = "\033[0m"
    _LEVEL_ABBR = {
        "DEBUG": "DBG",
        "INFO": "INF",
        "WARNING": "WRN",
        "ERROR": "ERR",
        "CRITICAL": "CRT"
    }

    def format(self, record):
        # 替换级别为缩写
        record.levelname = self._LEVEL_ABBR.get(record.levelname, record.levelname)
        # 为消息添加颜色
        color = self._COLOR_MAP.get(record.levelno, self._RESET_CODE)
        record.msg = f"{color}{record.msg}{self._RESET_CODE}"
        # 调用父类完成最终格式化
        return super().format(record)

2. 全局配置日志系统

在应用入口(如main.py)中配置根logger,覆盖默认日志处理规则:

def setup_global_logging():
    # 获取根日志器
    root_logger = logging.getLogger()
    # 设置全局日志级别(低于此级别的日志会被过滤)
    root_logger.setLevel(logging.DEBUG)

    # 移除默认handler(避免重复输出)
    for handler in root_logger.handlers[:]:
        root_logger.removeHandler(handler)

    # 创建控制台handler
    console_handler = StreamHandler()
    console_handler.setLevel(logging.DEBUG)

    # 绑定自定义格式器,可按需调整日志模板
    formatter = ColoredFormatter(
        "%(asctime)s - %(levelname)s - %(name)s - %(message)s",
        datefmt="%Y-%m-%d %H:%M:%S"
    )
    console_handler.setFormatter(formatter)

    # 将handler添加到根日志器
    root_logger.addHandler(console_handler)

# 应用启动时初始化
if __name__ == "__main__":
    setup_global_logging()
    main_logger = logging.getLogger(__name__)
    main_logger.info("主应用启动完成")

    # 导入并使用其他模块
    import my_module
    my_module.run_task()

3. 模块中直接使用日志

各模块无需额外配置,直接通过logging.getLogger(__name__)获取logger即可自动继承根logger的格式:

# my_module.py
import logging

logger = logging.getLogger(__name__)

def run_task():
    logger.debug("模块内调试信息")
    logger.info("模块内常规信息")
    logger.warning("模块内警告提示")
    logger.error("模块内错误信息")

可选:隔离应用日志与第三方库日志

如果不想让第三方库的日志应用自定义格式,可以放弃配置根logger,转而创建应用级顶级logger,让所有业务模块的logger作为它的子节点:

# main.py中配置应用顶级logger
def setup_app_logging():
    app_logger = logging.getLogger("my_app")
    app_logger.setLevel(logging.DEBUG)
    app_logger.propagate = False  # 避免向上传播到根logger

    # 移除默认handler(如果有)
    for handler in app_logger.handlers[:]:
        app_logger.removeHandler(handler)

    # 添加自定义handler和格式器(同之前的ColoredFormatter)
    console_handler = StreamHandler()
    console_handler.setFormatter(ColoredFormatter(...))
    app_logger.addHandler(console_handler)

# 模块中使用应用子logger
# my_module.py
logger = logging.getLogger(f"my_app.{__name__}")
# 若模块在my_app包下,直接用__name__即可(自动成为my_app的子logger)

原有代码不生效的原因

你之前仅给名为test的logger添加了handler,但模块中的logger = logging.getLogger(__name__)是根logger的子节点,并未继承test logger的配置。只有当模块logger是test的子节点(如logging.getLogger("test.module")),或你将handler配置到根logger时,模块日志才会使用自定义格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 03:40:22