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

如何在持续运行的Python应用中动态修改Logging level?

如何在运行时修改Python应用的日志级别

嘿,我来帮你搞定这个运行时修改日志级别的问题!先看看你的现有代码里需要调整的地方,再一步步给出可行的解决方案:

现有代码的小问题

  • 你的run循环每次都会调用getLogger,虽然做了if not len(logger.handlers)的判断,但一旦logger初始化完成,后续调用就不会再更新日志级别了——因为setLevel只在第一次创建handler时执行。
  • 目前没有结合ConfigParser实现配置的动态读取,没法自动感知配置文件的修改。

解决方案拆解

1. 实现配置的动态读取

首先用RawConfigParser加载你的配置文件,然后在循环里定时重新读取,这样就能实时获取最新的myLoggingLevel值。

2. 实时更新已存在Logger的级别

拿到新的日志级别后,不仅要更新logger本身的级别,还要更新它所有handler的级别——因为每个handler也有自己的级别过滤规则,只更新logger的话可能不会生效。

3. 优化Logger的创建逻辑

避免每次循环都尝试创建新Logger,应该复用已经存在的实例,只在配置变化时更新级别,这样也能避免重复添加handler导致日志重复输出。

修改后的完整代码

import time
import logging
import datetime
from configparser import RawConfigParser

def getLogger(loggerName='myLoggerName', logLevel='INFO', log_path='C:/logs/'):
    class Formatter(logging.Formatter):
        def formatTime(self, record, datefmt=None):
            return (datetime.datetime.utcnow()).strftime('%H:%M:%S')
    
    logLevel = logLevel.upper()
    levels = {
        'DEBUG': logging.DEBUG,
        'INFO': logging.INFO,
        'WARNING': logging.WARNING,
        'ERROR': logging.ERROR,
        'CRITICAL': logging.CRITICAL
    }
    today = datetime.datetime.utcnow().strftime('%Y-%m-%d')
    logger_key = f"{loggerName}.{today}"
    logger = logging.getLogger(logger_key)
    
    if not len(logger.handlers):
        # 第一次初始化时设置基础配置
        logger.setLevel(levels[logLevel])
        logger.propagate = False
        
        # 文件Handler配置
        full_log_path = log_path + '%s.%s.log' % (loggerName, today)
        fh = logging.FileHandler(full_log_path)
        formatter = Formatter('%(asctime)s.%(msecs)03d | %(message)s', datefmt='%H:%M:%S')
        fh.setFormatter(formatter)
        fh.setLevel(levels[logLevel])  # 给文件Handler也设置对应级别
        logger.addHandler(fh)
        
        # 控制台Handler配置(这里固定为ERROR级别,需要的话也可以从配置读取)
        ch = logging.StreamHandler()
        ch.setLevel(logging.ERROR)
        ch.setFormatter(formatter)
        logger.addHandler(ch)
        
        logger.info(f'Logger initialized: {loggerName}, current level: {logLevel}')
    
    return logger

def update_logger_level(logger, new_level):
    """更新已存在Logger的级别及其Handler的级别"""
    levels = {
        'DEBUG': logging.DEBUG,
        'INFO': logging.INFO,
        'WARNING': logging.WARNING,
        'ERROR': logging.ERROR,
        'CRITICAL': logging.CRITICAL
    }
    new_level_upper = new_level.upper()
    # 处理无效的日志级别
    if new_level_upper not in levels:
        logger.warning(f"Invalid log level '{new_level}' detected, falling back to INFO")
        new_level_upper = 'INFO'
    
    # 更新Logger本身的级别
    logger.setLevel(levels[new_level_upper])
    # 更新所有文件Handler的级别(控制台Handler如果需要跟随变化可以去掉判断)
    for handler in logger.handlers:
        if isinstance(handler, logging.FileHandler):
            handler.setLevel(levels[new_level_upper])
    
    logger.info(f"Successfully updated log level to: {new_level_upper}")

def load_config(config_path='config.ini'):
    """从配置文件读取当前的日志级别"""
    config = RawConfigParser()
    config.read(config_path)
    # 假设你的配置文件有[Logging] section,key为myLoggingLevel
    return config.get('Logging', 'myLoggingLevel', fallback='INFO')

def run():
    # 初始化配置和Logger
    current_level = load_config()
    log = getLogger(loggerName='testLogLevel', logLevel=current_level)
    
    while True:
        # 每次循环读取最新配置,检查是否有变化
        new_level = load_config()
        if new_level != current_level:
            current_level = new_level
            update_logger_level(log, current_level)
        
        # 业务日志输出示例
        log.debug('I am in debug')
        log.info('I am in info')
        time.sleep(3)

if __name__ == '__main__':
    run()

配套的配置文件示例(config.ini)

[Logging]
myLoggingLevel = DEBUG

关键细节说明

  • 动态感知配置变化:每次循环都会重新读取配置文件,只要你修改config.ini里的myLoggingLevel,应用会在3秒内感知到并更新级别。
  • 完整的级别更新:update_logger_level函数同时更新logger和handler的级别,确保新的过滤规则立即生效。
  • Logger复用:只在第一天启动时创建handler,后续复用同一个logger实例,避免日志重复输出的问题。
  • 容错处理:如果配置里写了无效的日志级别,会自动 fallback 到INFO,避免应用崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:50:23