Python 实用技巧:如何使用 Python 进行日志记录和调试

时间:2025-02-19 11:42:53

在开发 Python 程序时,调试和日志记录是非常重要的环节。日志(Logging) 可以帮助我们追踪程序运行情况、记录关键事件、调试错误,并提高系统的可维护性。相比 print() 语句,日志系统更加灵活,可以支持不同的 日志级别日志存储日志格式化,还能方便地输出到控制台或文件中。

本篇博客将介绍 如何使用 Python 的 logging 模块进行日志记录,包括: ✅ 日志基础用法
日志级别(DEBUG、INFO、WARNING、ERROR、CRITICAL)
日志格式化
日志输出到文件
日志回滚(按时间/大小自动切割日志文件)
结合 try-except 进行错误日志记录

让我们开始吧!????


一、为什么使用 logging 而不是 print()

许多初学者在调试 Python 代码时,会使用 print() 进行输出,例如:

print("程序开始运行")
print("处理数据中...")
print("程序运行完成!")

print() 有以下缺点: ❌ 没有日志级别:无法区分普通信息和错误信息
难以维护:代码量大时,print() 可能遍布整个程序,难以查找
无法持久化print() 只能输出到终端,而 logging 可以存入文件
缺乏格式化:无法轻松设置时间、文件名等信息

使用 logging 可以解决这些问题,并提高程序的可维护性。


二、Python logging 的基本用法

Python 标准库自带 logging 模块,无需额外安装。我们来看一个 最简单的日志示例

import logging

# 设置日志级别
logging.basicConfig(level=logging.DEBUG)

# 记录不同级别的日志
logging.debug("这是 DEBUG 级别的日志")
logging.info("这是 INFO 级别的日志")
logging.warning("这是 WARNING 级别的日志")
logging.error("这是 ERROR 级别的日志")
logging.critical("这是 CRITICAL 级别的日志")

输出结果:

DEBUG:root:这是 DEBUG 级别的日志
INFO:root:这是 INFO 级别的日志
WARNING:root:这是 WARNING 级别的日志
ERROR:root:这是 ERROR 级别的日志
CRITICAL:root:这是 CRITICAL 级别的日志

1. logging 日志级别解释:

级别

说明

DEBUG

调试信息,通常用于开发阶段

INFO

重要事件的运行信息

WARNING

可能出现的问题

ERROR

发生错误,但程序仍可继续运行

CRITICAL

严重错误,可能导致程序终止

默认情况下,logging 只会输出 WARNING 及以上的日志。如果需要查看 DEBUGINFO,需要 logging.basicConfig(level=logging.DEBUG) 来设置级别。


三、自定义日志格式

如果你希望 添加时间、日志级别、文件名等信息,可以自定义日志格式:

logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s - %(levelname)s - %(filename)s - %(lineno)d - %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S"
)

logging.info("自定义日志格式测试")

输出结果:

2024-02-19 10:00:00 - INFO - my_script.py - 12 - 自定义日志格式测试

日志格式说明:

  • %(asctime)s → 记录时间
  • %(levelname)s → 日志级别
  • %(filename)s → 代码文件名
  • %(lineno)d → 代码所在行号
  • %(message)s → 日志信息

四、日志输出到文件

如果希望日志保存到文件,而不是只在终端打印,可以这样做:

logging.basicConfig(
    filename="app.log",  # 日志文件名
    level=logging.DEBUG,
    format="%(asctime)s - %(levelname)s - %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S"
)

logging.info("日志已写入文件!")

此时,日志会被写入 app.log 文件,而不会在终端显示。


五、日志回滚(按时间或文件大小切割日志)

如果日志文件过大(如 100MB),或每天生成一个新日志文件,可以使用 RotatingFileHandlerTimedRotatingFileHandler

1. 按 文件大小 分割日志文件

import logging
from logging.handlers import RotatingFileHandler

# 设定日志文件最大 1MB,最多保留 3 个旧日志
handler = RotatingFileHandler("app.log", maxBytes=1_000_000, backupCount=3)

# 配置日志格式
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)

# 添加日志处理器
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)

# 记录日志
logger.info("文件大小限制的日志示例")

app.log 超过 1MB 时,日志会自动切割,并保留 3 个旧日志文件(app.log.1app.log.2)。


2. 按 时间间隔 生成新日志文件

from logging.handlers import TimedRotatingFileHandler

# 每天生成一个新日志文件
handler = TimedRotatingFileHandler("timed.log", when="D", interval=1, backupCount=5)

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)

logger.info("基于时间的日志滚动示例")

每隔一天创建一个新日志文件,并最多保留 5 天的日志。


六、结合 try-except 记录错误日志

在处理异常时,可以用 logging 记录 错误信息,以便后续分析问题。

try:
    result = 10 / 0
except Exception as e:
    logging.error("发生异常:%s", e, exc_info=True)

使用 exc_info=True 可以记录完整的异常堆栈信息!


七、在多个文件中使用日志(getLogger

如果项目较大,涉及多个模块,建议使用 logging.getLogger() 创建独立的日志实例。

logger.py(日志配置文件)

import logging

def get_logger():
    logger = logging.getLogger("MyLogger")
    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler("my_app.log")
    formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
    handler.setFormatter(formatter)

    logger.addHandler(handler)
    return logger

main.py(主程序)

from logger import get_logger

logger = get_logger()
logger.info("这是一个跨模块日志示例")

这样,不同文件都能使用同一个日志系统!


八、总结

在本篇博客中,我们学习了 如何使用 Python logging 进行日志记录,包括:

日志基础用法(DEBUGINFOWARNINGERRORCRITICAL
自定义日志格式(时间、文件名、行号)
日志输出到文件
日志回滚(按大小/时间切割日志文件)
异常日志记录(try-except
多模块日志管理(getLogger()

???? 日志是调试和维护 Python 项目的重要工具,合理使用 logging,可以提高代码的可读性、可维护性,让程序更加健壮!

希望本篇博客对你有所帮助!???? ????