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

Python中无法使用不同日志级别怎么办?日志文件为空问题排查

问题分析与解决方案

你的代码出现日志文件为空的核心原因是每次调用日志方法都会重复创建并添加FileHandler到同一个Logger实例,同时缺少单例控制导致配置冲突,另外可能存在日志文件路径未定义、无写入权限等问题。以下是修正后的实现方案:

方案一:分实例处理不同级别日志

通过单例模式确保每个级别对应的Logger只初始化一次,避免重复添加Handler:

import logging as log
import inspect

class Logger:
    _info_logger = None
    _warning_logger = None

    @staticmethod
    def get_info_logger():
        if Logger._info_logger is None:
            # 生成唯一的Logger名称,避免与其他Logger冲突
            caller_name = inspect.stack()[1][3]
            logger = log.getLogger(f"{caller_name}_info")
            logger.setLevel(log.INFO)
            # 禁止日志向上传播到根Logger,避免重复输出
            logger.propagate = False
            
            # 替换为你的实际日志文件路径
            log_file = "info.log"
            fh = log.FileHandler(log_file, encoding='utf-8')
            formatter = log.Formatter(
                "%(asctime)s - %(levelname)s - %(message)s",
                datefmt='%m/%d/%Y %I:%M:%S %p'
            )
            fh.setFormatter(formatter)
            logger.addHandler(fh)
            Logger._info_logger = logger
        return Logger._info_logger

    @staticmethod
    def get_warning_logger():
        if Logger._warning_logger is None:
            caller_name = inspect.stack()[1][3]
            logger = log.getLogger(f"{caller_name}_warning")
            logger.setLevel(log.WARNING)
            logger.propagate = False
            
            error_log_file = "warning.log"
            fh = log.FileHandler(error_log_file, encoding='utf-8')
            formatter = log.Formatter(
                "%(asctime)s - %(levelname)s - %(message)s",
                datefmt='%m/%d/%Y %I:%M:%S %p'
            )
            fh.setFormatter(formatter)
            logger.addHandler(fh)
            Logger._warning_logger = logger
        return Logger._warning_logger

使用示例

def business_operation():
    # 记录正常操作
    info_log = Logger.get_info_logger()
    info_log.info("用户登录成功")
    
    # 记录异常操作
    warn_log = Logger.get_warning_logger()
    warn_log.warning("用户密码输入错误3次")

business_operation()

方案二:单Logger多Handler(更简洁)

用同一个Logger实例,配置两个Handler分别过滤不同级别日志,实现分离存储:

import logging as log
import inspect

class Logger:
    _logger = None

    @staticmethod
    def get_logger():
        if Logger._logger is None:
            caller_name = inspect.stack()[1][3]
            logger = log.getLogger(caller_name)
            # 设置最低日志级别为INFO,确保能捕获所有需要的日志
            logger.setLevel(log.INFO)
            logger.propagate = False

            # 处理INFO级别日志的Handler
            info_fh = log.FileHandler("info.log", encoding='utf-8')
            info_fh.setLevel(log.INFO)
            # 添加过滤器,只保留INFO级别日志
            info_filter = log.Filter()
            info_filter.filter = lambda record: record.levelno == log.INFO
            info_fh.addFilter(info_filter)
            
            # 处理WARNING及以上级别日志的Handler
            warn_fh = log.FileHandler("warning.log", encoding='utf-8')
            warn_fh.setLevel(log.WARNING)
            
            # 统一日志格式
            formatter = log.Formatter(
                "%(asctime)s - %(levelname)s - %(message)s",
                datefmt='%m/%d/%Y %I:%M:%S %p'
            )
            info_fh.setFormatter(formatter)
            warn_fh.setFormatter(formatter)
            
            logger.addHandler(info_fh)
            logger.addHandler(warn_fh)
            Logger._logger = logger
        return Logger._logger

使用示例

def business_operation():
    logger = Logger.get_logger()
    logger.info("数据备份完成")
    logger.warning("备份文件大小超过阈值")

business_operation()

关键修正点

  • 单例控制:避免重复创建Handler,防止日志配置冲突或重复输出
  • Logger隔离:通过命名后缀或禁用传播,避免与全局Logger混淆
  • 明确路径与权限:确保log_file和error_log_file指向的路径存在且有写入权限
  • 编码设置:指定encoding='utf-8'避免中文日志乱码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 09:06:19