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

Python logging模块日志级别解析及函数内配置问题咨询

Python Logging模块问题解答

一、日志级别(Levels)说明

Python Logging模块定义了5个从低到高的日志级别,用于区分日志的重要程度:

  • DEBUG:最详细的调试信息,多用于开发阶段记录变量值、函数执行流程等细节
  • INFO:确认程序按预期运行的常规信息,比如服务启动完成、数据加载成功
  • WARNING:提示潜在问题,但程序仍可正常运行,比如内存占用过高、使用已废弃API
  • ERROR:程序功能异常,部分逻辑无法执行,比如文件读取失败、数据库连接错误
  • CRITICAL:严重错误,程序可能无法继续运行,比如系统资源耗尽、核心组件崩溃

默认情况下,日志系统只会输出WARNING级别及以上的日志。

二、能否通过自定义函数配置Logging?

完全可以。自定义配置函数是Logging模块的常用实践,能把日志配置逻辑封装复用,还可灵活设置日志级别、处理器(Handler)、输出格式(Formatter)等。你写的setuplogging()就是典型的自定义配置函数,通过它可以创建日志器、添加控制台/文件处理器、定义输出格式。

三、测试代码相关疑问

a. 为何调用配置函数后需添加logging = logging.getLogger(__name__),主脚本末尾的日志语句才生效?

你一开始导入的logging是Python的logging模块本身,直接调用logging.info()这类方法时,实际使用的是根日志器(root logger)。而setuplogging()函数里配置的是__name__对应的子日志器(当前脚本专属的日志器)。

根日志器默认级别为WARNING,且没有添加你自定义的控制台和文件处理器——如果不重新赋值logging = logging.getLogger(__name__),主脚本末尾的logging.info()会因级别不够被过滤,logging.warning()也只会用根日志器的默认处理器输出,不会走你配置的格式和处理器。重新赋值后,后续日志调用才会使用你配置好的子日志器,语句才能按预期生效。

b. 日志输出重复的原因是什么?

主要源于日志传播机制:子日志器默认会把日志传播给父日志器(根日志器)。当你第一次调用logging.warning('This is a trial of basic logging')时,根日志器会自动创建一个默认的控制台处理器(StreamHandler)。之后你的子日志器输出日志时,会先通过自己添加的c_handler输出一次,再把日志传播给根日志器,根日志器的默认处理器会再输出一次,最终导致重复。

另外如果setuplogging()函数被多次调用,每次都会给同一个子日志器添加新处理器,也会引发重复输出,但你的代码里只调用了一次,所以核心原因是日志传播。


你的测试代码

def setuplogging():
    # logging_example

    #import logging

    # When setting up logging, define the level using capitals because logging.debug is seen as a function, logging.DEBUG is the level id.
    
    # Create a custom logger
    logger = logging.getLogger(__name__) #The variable __name__ contains the dotted name of the current module.
    logger.setLevel(logging.DEBUG) #WARM is default

    # Create handlers
    c_handler = logging.StreamHandler()
    f_handler = logging.FileHandler('E:\data\computing\software\programming\scripts\LOGFILE.log')
    c_handler.setLevel(logging.DEBUG)
    f_handler.setLevel(logging.DEBUG)

    # Create formatters and add it to handlers
    c_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
    f_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    c_handler.setFormatter(c_format)
    f_handler.setFormatter(f_format)

    # Add handlers to the logger
    logger.addHandler(c_handler)
    logger.addHandler(f_handler)

    logger.info('def This is a test of an info message')
    logger.warning('def This is a warning')
    logger.error('def This is an error')

import logging
logging.warning('This is a trial of basic logging')
setuplogging()
logging = logging.getLogger(__name__)

logging.info('Script This is a test of an info message')
logging.warning('Script This is a warning')
logging.error('Script This is an error')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 01:00:17