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

如何通过环境变量切换logging.ini中定义的Python日志格式化器?

通过环境变量切换Python日志格式化器的解决方案

问题背景

我有如下logging.ini配置文件:

[loggers]
keys=root

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter,json

[logger_root]
level=INFO
handlers=consoleHandler

[handler_consoleHandler]
class=StreamHandler
formatter=json
args=(sys.stdout,)

[formatter_json]
class=pythonjsonlogger.jsonlogger.JsonFormatter
format=%(asctime)s %(name)s %(levelname)s %(message)s

[formatter_simpleFormatter]
format=%(asctime)s %(name)s - %(levelname)s:%(message)s

尝试通过环境变量切换日志格式化器时,代码报错AttributeError: 'RootLogger' object has no attribute 'setFormatter',原代码如下:

import logging.config
import os
from pathlib import Path

# 加载日志配置文件
logging_config_file_path = Path.joinpath(
    Path(__file__).parent.absolute(), "logging.ini"
)
logging.config.fileConfig(logging_config_file_path)

# 通过环境变量覆盖日志设置
LOGLEVEL = os.environ.get("LOGLEVEL", "INFO").upper()
LOG_FORMATTER = os.environ.get("LOG_FORMATTER", "simpleFormatter").upper()
LOGLEVEL_NUMBER = logging.getLevelName(LOGLEVEL)
logger = logging.getLogger()
logger.setLevel(LOGLEVEL)
# 错误尝试:直接给logger设置格式化器
logger.setFormatter(LOG_FORMATTER)

另外尝试用defaults参数传递配置时,也出现解析错误:
修改后的logging.ini片段:

[handler_consoleHandler]
class=StreamHandler
# formatter=simpleFormatter
formatter='%(formatter)s'

调用代码:

logging.config.fileConfig(
    logging_config_file_path, defaults={"formatter": "simpleFormatter"}
)

报错信息:

configparser.InterpolationSyntaxError: bad interpolation variable reference '%(formatter)'

两种可行解决方案

方案一:加载配置后动态修改Handler的格式化器

报错核心原因:格式化器是绑定在Handler上的,而非Logger对象,不能直接调用logger.setFormatter()。正确步骤是找到Logger对应的Handler,再给Handler替换格式化器。

代码示例:

import logging.config
import os
from pathlib import Path

# 加载日志配置文件
logging_config_file_path = Path.joinpath(
    Path(__file__).parent.absolute(), "logging.ini"
)
logging.config.fileConfig(logging_config_file_path)

# 读取环境变量
LOGLEVEL = os.environ.get("LOGLEVEL", "INFO").upper()
LOG_FORMATTER_NAME = os.environ.get("LOG_FORMATTER", "simpleFormatter")

# 修改日志级别
logger = logging.getLogger()
logger.setLevel(LOGLEVEL)

# 动态替换格式化器
for handler in logger.handlers:
    # 从日志管理器中获取已定义的格式化器对象
    target_formatter = logging.getLoggerClass().manager.formatterDict.get(LOG_FORMATTER_NAME)
    if target_formatter:
        handler.setFormatter(target_formatter)

方案二:利用configparser插值加载时指定格式化器

之前的插值错误是因为给%(formatter)s加了多余的单引号,configparser的语法不需要引号。修改配置和代码如下:

修改后的logging.ini关键片段:

[handler_consoleHandler]
class=StreamHandler
formatter=%(formatter)s
args=(sys.stdout,)

调用代码:

import logging.config
import os
from pathlib import Path

# 从环境变量获取格式化器名称,默认用simpleFormatter
LOG_FORMATTER_NAME = os.environ.get("LOG_FORMATTER", "simpleFormatter")

# 加载配置时传入defaults参数,替换插值变量
logging_config_file_path = Path.joinpath(
    Path(__file__).parent.absolute(), "logging.ini"
)
logging.config.fileConfig(
    logging_config_file_path,
    defaults={"formatter": LOG_FORMATTER_NAME},
    disable_existing_loggers=False  # 可选,保留已存在的日志实例
)

# 同时设置日志级别
LOGLEVEL = os.environ.get("LOGLEVEL", "INFO").upper()
logger = logging.getLogger()
logger.setLevel(LOGLEVEL)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 23:25:17