Python 日志记录与管理全攻略:从入门到实践

在 Python 开发中,日志记录是一项不可或缺的重要功能。无论是排查程序运行时的错误,还是了解程序的执行流程和性能,日志都能为开发者提供关键线索。本文将从零开始,带你了解如何在 Python 中高效地记录和管理日志,即便你是编程新手也能轻松掌握。

一、为什么需要日志记录?

想象一下,你的 Python 程序在生产环境中突然出错,但没有任何提示信息。没有日志,你就像在黑暗中摸索,很难快速定位问题。而有了日志,程序运行时的关键信息,如变量的值、函数的调用顺序、错误发生的位置等都会被记录下来,大大提升调试效率。此外,日志还能用于统计程序的运行情况、分析用户行为等。

二、Python 内置的 logging 模块

Python 标准库中的logging模块为我们提供了强大且灵活的日志记录功能。它允许我们设置不同的日志级别,指定日志输出的位置(如控制台、文件等),并自定义日志的格式。

1. 基本使用

下面是一个简单的示例,展示了如何使用logging模块记录日志:

python

import logging

# 配置logging,设置日志级别为INFO,指定日志格式
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 记录不同级别的日志
logging.debug('这是一条调试信息')
logging.info('这是一条普通信息')
logging.warning('这是一条警告信息')
logging.error('这是一条错误信息')
logging.critical('这是一条严重错误信息')

在上述代码中:

  • basicConfig函数用于配置logging模块。level=logging.INFO表示只记录级别为INFO及以上的日志(INFO、WARNING、ERROR、CRITICAL),DEBUG级别的日志会被忽略。
  • %(asctime)s、%(levelname)s、%(message)s是日志格式的占位符,分别表示时间、日志级别和日志信息。

运行代码后,你会在控制台看到类似如下的输出:

展开过程

2. 日志级别

logging模块定义了 5 种日志级别,按严重程度从低到高依次为:

  • DEBUG:用于调试过程中的详细信息,通常在开发阶段使用。
  • INFO:用于记录程序正常运行的信息。
  • WARNING:表示可能会出现问题的情况。
  • ERROR:记录程序发生错误但仍能继续运行的情况。
  • CRITICAL:表示严重错误,程序可能无法继续运行。

你可以根据实际需求,通过设置不同的日志级别来控制记录哪些信息。

3. 输出到文件

除了在控制台输出日志,我们还可以将日志记录到文件中,方便后续查看和分析。示例代码如下:

python

import logging

# 配置logging,将日志输出到文件
logging.basicConfig(filename='app.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

logging.info('这是一条写入文件的普通信息')
logging.warning('这是一条写入文件的警告信息')

运行上述代码后,会在当前目录下生成一个app.log文件,打开文件就能看到记录的日志信息。

三、高级日志管理

1. 自定义日志格式

有时,默认的日志格式不能满足我们的需求,这时可以自定义更详细的格式。例如,我们希望在日志中包含模块名和函数名:

python

import logging

# 自定义日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(funcName)s - %(message)s')

# 创建一个FileHandler,用于将日志写入文件
file_handler = logging.FileHandler('custom.log')
file_handler.setFormatter(formatter)

# 获取一个logger实例
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.addHandler(file_handler)

# 记录日志
def some_function():
    logger.info('在函数中记录一条信息')

some_function()

在这个示例中:

  • 首先创建了一个Formatter对象,定义了新的日志格式。
  • 然后创建FileHandler并设置格式,将其添加到logger中。
  • 最后通过logger记录日志,日志中会包含模块名(__name__)和函数名(%(funcName)s)。

2. 按时间或大小分割日志文件

当程序运行时间较长或产生的日志量较大时,我们可能希望将日志文件按时间或大小进行分割,避免单个文件过大难以处理。可以使用logging.handlers模块中的相关类来实现。

按时间分割

python

import logging
from logging.handlers import TimedRotatingFileHandler

# 创建TimedRotatingFileHandler,按天分割日志文件
handler = TimedRotatingFileHandler('time_split.log', when='midnight', interval=1, backupCount=7)
handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.addHandler(handler)

# 记录日志
for _ in range(10):
    logger.info('这是一条按时间分割的日志信息')

在上述代码中,TimedRotatingFileHandler会在每天午夜(when='midnight')创建一个新的日志文件,并保留最近 7 天的日志文件(backupCount=7)。

按大小分割

python

import logging
from logging.handlers import RotatingFileHandler

# 创建RotatingFileHandler,按文件大小分割日志文件
handler = RotatingFileHandler('size_split.log', maxBytes=1024*100, backupCount=5)
handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.addHandler(handler)

# 记录大量日志,触发文件分割
for i in range(1000):
    logger.info(f'这是第{i}条按大小分割的日志信息')

这里RotatingFileHandler设置了每个日志文件最大为 100KB(maxBytes=1024*100),当文件大小超过这个值时,会自动创建新的日志文件,并保留 5 个备份文件(backupCount=5)。

四、总结

通过学习logging模块,我们掌握了 Python 中日志记录和管理的核心技能。从基本的日志输出,到自定义格式、按时间或大小分割日志文件,这些知识能帮助我们在开发过程中更好地监控和调试程序。合理使用日志,就像给程序配备了一位 “记录员”,让我们对程序的运行情况了如指掌。

希望本文能对你有所帮助,快在自己的 Python 项目中实践起来吧!

原文链接:,转发请注明来源!