Python 中如何使用 logging 模块记录错误?

在 Python 编程中,错误日志(Error Logging)是调试和维护程序的重要手段。当代码发生异常时,记录日志可以帮助我们快速定位问题,避免程序直接崩溃。Python 内置的 logging 模块提供了强大的日志记录功能,可以方便地记录错误信息,并输出到控制台、文件、远程服务器等多个目标。本文将介绍 logging 模块的基本用法,并深入探讨如何使用 logging 记录错误信息,包括日志级别、日志格式、文件存储和异常日志捕获等。


1. 为什么要使用 logging 记录错误?

相较于 print(),使用 logging 记录错误有以下优势
更灵活 —— 可以控制日志级别(DEBUGINFOWARNINGERRORCRITICAL)。

更持久 —— 日志可以写入文件,方便以后分析错误。

更专业 —— 支持日志格式化、时间戳、多线程、多进程等功能。

更高效 —— 可以根据日志级别进行筛选,避免无用信息干扰。

示例:

import logging

# 设置日志级别和格式
logging.basicConfig(level=logging.ERROR, format="%(asctime)s - %(levelname)s - %(message)s")

# 记录错误
logging.error("发生错误: 数据库连接失败")

输出示例(带时间戳):

2024-02-04 12:30:15,678 - ERROR - 发生错误: 数据库连接失败

2. logging 模块的基本概念

Python logging 模块提供了多个日志级别,每个级别代表不同的严重程度:

级别(Level) 数值 说明
DEBUG 10 调试信息,最详细
INFO 20 普通信息,如程序运行状态
WARNING 30 警告信息,表示可能会有问题
ERROR 40 错误信息,代码执行失败
CRITICAL 50 严重错误,可能导致程序终止

3. 记录错误日志的基本方法

3.1 直接使用 logging 记录错误

import logging

logging.basicConfig(level=logging.ERROR)

logging.error("这是一个错误日志")

输出:

ERROR:root:这是一个错误日志

3.2 记录错误并捕获异常

在异常 try-except 代码块中,可以使用 logging.error() 记录异常信息。

import logging

logging.basicConfig(level=logging.ERROR, format="%(asctime)s - %(levelname)s - %(message)s")

try:
    1 / 0  # 触发 ZeroDivisionError
except ZeroDivisionError:
    logging.error("发生除零错误", exc_info=True)

输出(包含 Traceback):

2024-02-04 12:35:20,123 - ERROR - 发生除零错误
Traceback (most recent call last):
  File "example.py", line 6, in 
    1 / 0
ZeroDivisionError: division by zero

exc_info=True 作用

  • 会自动捕获当前异常的 Traceback 信息,类似 traceback.print_exc()

3.3 记录错误到日志文件

使用 filename 参数,将错误日志写入文件,而不是控制台

import logging

logging.basicConfig(
    filename="error.log",
    level=logging.ERROR,
    format="%(asctime)s - %(levelname)s - %(message)s"
)

try:
    open("non_existent_file.txt")
except FileNotFoundError:
    logging.error("文件未找到", exc_info=True)

运行后,错误信息会写入 error.log 文件:

2024-02-04 12:40:30,456 - ERROR - 文件未找到
Traceback (most recent call last):
  File "example.py", line 8, in 
    open("non_existent_file.txt")
FileNotFoundError: [Errno 2] No such file or directory: 'non_existent_file.txt'

4. 进阶用法:使用 logging 记录错误

4.1 使用 Logger 对象

import logging

# 创建 logger
logger = logging.getLogger("my_logger")
logger.setLevel(logging.ERROR)

# 配置日志格式和文件处理器
file_handler = logging.FileHandler("app.log")
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
file_handler.setFormatter(formatter)

# 添加处理器到 logger
logger.addHandler(file_handler)

# 记录错误
try:
    1 / 0
except ZeroDivisionError:
    logger.error("除零错误", exc_info=True)

优势:

  • 可复用logger 可以在多个模块中共享。
  • 可扩展:可以添加多个处理器(如控制台、文件、远程服务器)。

4.2 同时输出日志到控制台和文件

import logging

# 创建 logger
logger = logging.getLogger("dual_logger")
logger.setLevel(logging.ERROR)

# 创建文件处理器
file_handler = logging.FileHandler("error.log")
console_handler = logging.StreamHandler()

# 设置格式
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)

# 添加处理器到 logger
logger.addHandler(file_handler)
logger.addHandler(console_handler)

# 记录错误
logger.error("发生错误,写入文件并打印到控制台")

效果:

  1. 控制台输出

    2024-02-04 12:45:00,789 - ERROR - 发生错误,写入文件并打印到控制台
    
  2. 文件 error.log 记录相同内容


5. logging 记录错误的最佳实践

使用 getLogger() 创建全局 Logger,避免 basicConfig() 影响全局日志配置。

使用 exc_info=True 捕获异常信息,代替 traceback.print_exc()

日志输出到多个目标(文件 + 控制台),提升可读性。

设置合适的日志级别,避免记录过多不必要的信息。

使用 Formatter 统一日志格式,包含时间、日志级别、错误详情。


6. 结论

方法 适用场景
logging.error(msg) 记录普通错误
logging.error(msg, exc_info=True) 记录异常信息(含 Traceback)
filename="error.log" 记录错误到文件
getLogger("my_logger") 创建可复用的 Logger
addHandler(FileHandler/StreamHandler) 同时输出到文件 & 控制台

Python logging 模块提供了强大灵活的日志管理功能,合理使用 logging.error(),可以有效捕获错误信息,帮助我们更快定位问题,提升代码的可维护性。


有什么问题和经验想分享?欢迎在评论区交流、点赞、收藏、关注!

你可能感兴趣的:(技术#Python,技术#编程基础,python,开发语言,编程基础,日志记录)