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

如何仅在有日志内容时创建Python logging日志文件?

问题描述

Python版本:3.11.8

使用logging包记录日志时,调用logging.basicConfig会直接创建日志文件,导致仓库中生成大量空日志文件。需求是仅在有日志内容需要记录时(比如platform等于"DRD",或者程序发生错误时)才创建日志文件,无日志输出时不生成空文件。

原代码片段:

from time import sleep
from json import dumps
from traceback import format_exc
import logging

def create_target_file(logs_file_path: str,
                       platform: str,
                        )-> str:

    try:
        
        data ={}

        try:
            logging.basicConfig(filename=logs_file_path,
                                filemode='a',
                                level=logging.INFO,
                                format="%(levelname)s | %(asctime)s | %(message)s", 
                                datefmt="%Y-%m-%d %H:%M:%S")
        except OSError as e:
            sleep(10)
            logging.basicConfig(filename=logs_file_path,
                                filemode='a',
                                level=logging.INFO,
                                format="%(levelname)s | %(asctime)s | %(message)s", 
                                datefmt="%Y-%m-%d %H:%M:%S")
        
        if platform == 'DRD':
            logging.info("Logging some important stuff")

    except Exception as e:
        
        logging.error(str(e))
        data['error_message'] = str(e)
        data['stack_trace'] = format_exc()
    
    finally:
        return dumps(data)

解决方案

核心思路是延迟日志配置,不在函数开头就调用logging.basicConfig,而是等到实际需要记录日志(调用logging.info/logging.error等)时再执行配置操作,同时避免重复配置日志处理器。

步骤1:封装日志初始化函数

将日志配置逻辑封装成独立函数,加入重试逻辑和重复配置检查:

import logging
from time import sleep

def init_logging(log_file_path: str):
    # 检查是否已配置过对应文件的FileHandler,避免重复配置
    for handler in logging.root.handlers:
        if isinstance(handler, logging.FileHandler) and handler.baseFilename == log_file_path:
            return
    
    # 带重试的日志配置,处理OSError
    max_retries = 1
    for attempt in range(max_retries + 1):
        try:
            logging.basicConfig(
                filename=log_file_path,
                filemode='a',
                level=logging.INFO,
                format="%(levelname)s | %(asctime)s | %(message)s", 
                datefmt="%Y-%m-%d %H:%M:%S"
            )
            break
        except OSError as e:
            if attempt == max_retries:
                raise  # 重试失败后抛出异常
            sleep(10)

步骤2:修改业务函数,按需初始化日志

在需要记录日志的分支(platform == 'DRD'或异常捕获块)中调用init_logging,确保只有当有日志要输出时才创建文件:

from json import dumps
from traceback import format_exc

def create_target_file(logs_file_path: str, platform: str) -> str:
    data = {}
    try:
        if platform == 'DRD':
            init_logging(logs_file_path)
            logging.info("Logging some important stuff")
    except Exception as e:
        init_logging(logs_file_path)
        logging.error(str(e))
        data['error_message'] = str(e)
        data['stack_trace'] = format_exc()
    finally:
        return dumps(data)

原理说明

  • logging.basicConfig仅在根日志器没有任何处理器时生效,且调用时会立即创建指定的日志文件。延迟调用该函数,就能保证只有在实际需要写日志时才触发文件创建。
  • 加入重复配置检查,避免多次调用init_logging导致日志重复输出。
  • 保留原有的OSError重试逻辑,确保文件创建失败时的容错性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:08:12