Python logging 模块基础详解

1 日志系统核心概念

1.1 日志级别(Level)

日志级别决定了日志信息的重要性,Python logging 定义了5个标准级别:

import logging

# 日志级别从低到高排列
logging.debug("调试信息 - 最详细的日志")         # 10
logging.info("程序运行信息 - 常规操作日志")       # 20
logging.warning("警告信息 - 潜在问题")           # 30
logging.error("错误信息 - 功能故障")             # 40
logging.critical("严重错误 - 可能导致程序崩溃")  # 50

1.2 日志记录器(Logger)

Logger 是日志系统的入口点,负责捕获日志信息:

# 创建日志记录器
logger = logging.getLogger("my_app")

# 设置日志级别(只记录该级别及以上的日志)
logger.setLevel(logging.DEBUG)

# 使用日志记录器
logger.info("应用程序已启动")

1.3 处理器(Handler)

Handler 决定日志的输出位置:

# 控制台处理器
console_handler = logging.StreamHandler()

# 文件处理器
file_handler = logging.FileHandler("app.log")

# 将处理器添加到日志记录器
logger.addHandler(console_handler)
logger.addHandler(file_handler)

1.4 格式化器(Formatter)

Formatter 定义日志的显示格式:

# 创建格式化器
formatter = logging.Formatter(
    "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S"
)

# 将格式化器应用到处理器
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)

2 完整基础示例

import logging

def setup_logger():
    """配置基础日志系统"""
    # 1. 创建日志记录器
    logger = logging.getLogger("my_app")
    logger.setLevel(logging.DEBUG)  # 捕获所有级别日志
    
    # 2. 创建处理器
    # 控制台处理器 - 只显示INFO及以上级别
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)
    
    # 文件处理器 - 记录所有级别日志
    file_handler = logging.FileHandler("app.log")
    file_handler.setLevel(logging.DEBUG)
    
    # 3. 创建格式化器
    formatter = logging.Formatter(
        "%(asctime)s [%(levelname)s] %(message)s",
        datefmt="%Y-%m-%d %H:%M:%S"
    )
    
    # 4. 将格式化器应用到处理器
    console_handler.setFormatter(formatter)
    file_handler.setFormatter(formatter)
    
    # 5. 将处理器添加到日志记录器
    logger.addHandler(console_handler)
    logger.addHandler(file_handler)
    
    return logger

def main():
    logger = setup_logger()
    
    # 记录不同级别的日志
    logger.debug("调试信息 - 通常包含变量值")
    logger.info("程序启动信息")
    logger.warning("磁盘空间不足警告")
    
    try:
        # 模拟一个错误
        result = 10 / 0
    except Exception as e:
        logger.error(f"发生错误: {e}", exc_info=True)
    
    logger.info("程序结束")

if __name__ == "__main__":
    main()

3 代码解析

3.1 日志记录器创建

logger = logging.getLogger("my_app")

  • 创建名为"my_app"的日志记录器
  • 相同名称的日志记录器是同一个实例(单例模式)

3.2 日志级别设置

logger.setLevel(logging.DEBUG)

  • 设置记录器的最低日志级别
  • DEBUG级别会记录所有日志信息

3.3 处理器配置

控制台处理器:

console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
  • 输出到控制台
  • 只显示INFO及以上级别日志

文件处理器:

file_handler = logging.FileHandler("app.log")
file_handler.setLevel(logging.DEBUG)
  • 输出到文件app.log
  • 记录所有级别日志

3.4 格式化器详解

formatter = logging.Formatter(
    "%(asctime)s [%(levelname)s] %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S"
)
  • %(asctime)s: 日志时间
  • %(levelname)s: 日志级别名称
  • %(message)s: 日志内容
  • datefmt: 自定义日期格式

3.5 异常记录

try:
    result = 10 / 0
except Exception as e:
    logger.error(f"发生错误: {e}", exc_info=True)
  • exc_info=True 参数会记录完整的异常堆栈信息
  • 在日志文件中可以看到详细的错误位置和调用栈

4 运行结果

4.1 控制台输出

2023-08-15 10:30:45 [INFO] 程序启动信息
2023-08-15 10:30:45 [WARNING] 磁盘空间不足警告
2023-08-15 10:30:45 [ERROR] 发生错误: division by zero
2023-08-15 10:30:45 [INFO] 程序结束

4.2 文件输出 (app.log)

2023-08-15 10:30:45 [DEBUG] 调试信息 - 通常包含变量值
2023-08-15 10:30:45 [INFO] 程序启动信息
2023-08-15 10:30:45 [WARNING] 磁盘空间不足警告
2023-08-15 10:30:45 [ERROR] 发生错误: division by zero
Traceback (most recent call last):
  File "demo.py", line 30, in main
    result = 10 / 0
ZeroDivisionError: division by zero
2023-08-15 10:30:45 [INFO] 程序结束

5 关键要点总结

  1. 日志级别重要性:合理设置级别可过滤无关信息

    • DEBUG:开发调试阶段使用
    • INFO:生产环境常规信息
    • WARNING:需要关注但非错误的问题
    • ERROR:功能错误
    • CRITICAL:严重系统错误
  2. 日志记录器层级

    # 创建层级化日志记录器
    main_logger = logging.getLogger("my_app")
    module_logger = logging.getLogger("my_app.database")
    
    • 子记录器会继承父记录器的配置
    • 可通过层级管理不同模块的日志
  3. 最佳实践

    • 避免直接使用 root logger (logging.info())
    • 为不同模块创建独立的日志记录器
    • 在程序入口处配置日志系统
    • 生产环境中使用文件轮换(RotatingFileHandler)
  4. 格式化占位符

    • %(name)s: 日志记录器名称
    • %(filename)s: 文件名
    • %(funcName)s: 函数名
    • %(lineno)d: 行号
    • %(process)d: 进程ID
    • %(thread)d: 线程ID

掌握这些基础知识后,你可以为任何Python项目配置有效的日志系统,帮助开发和调试过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@MMiL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值