Python日志记录(Logging)简介与应用¶
学习目标¶
- 理解日志记录的作用及其在程序开发中的重要性。
- 掌握Python
logging模块的基本用法。 - 学会通过示例配置日志级别、格式,并将日志存储到文件中。
- 在工程化项目中应用日志记录,追踪程序运行状态。
日志记录概述¶
日志(Logging)是程序运行时记录关键信息的一种方式,例如操作成功、错误发生或调试信息。它在开发和维护中非常重要,因为:
- 调试:帮助找到代码中的问题。
- 监控:记录程序的运行状态。
- 审计:追踪用户或系统的行为。
Python的logging模块是一个内置工具,提供灵活的日志记录功能,比简单的print语句更强大。
核心概念¶
- 日志级别:表示日志的重要性,常见级别从低到高:
DEBUG:调试信息(最低)。INFO:一般信息。WARNING:警告,可能有问题。ERROR:错误,已影响程序。CRITICAL:严重错误(最高)。
- 日志处理器(Handler):决定日志输出到哪里(如控制台或文件)。
- 日志格式(Formatter):定义日志的显示样式(如时间、级别、消息)。
示例1:基础日志记录¶
目标¶
通过简单示例展示如何记录日志到控制台。
代码¶
import logging
# 配置基本的日志设置
logging.basicConfig(level=logging.INFO)
# 获取日志记录器
logger = logging.getLogger("Example1")
# 记录不同级别的日志
logger.debug("这是调试信息,通常用于开发")
logger.info("程序运行正常")
logger.warning("注意,可能有小问题")
logger.error("发生错误")
logger.critical("严重错误,程序可能崩溃")
运行结果¶
2025-04-01 10:00:00,123 INFO Example1: 程序运行正常
2025-04-01 10:00:00,124 WARNING Example1: 注意,可能有小问题
2025-04-01 10:00:00,125 ERROR Example1: 发生错误
2025-04-01 10:00:00,126 CRITICAL Example1: 严重错误,程序可能崩溃
分析¶
basicConfig(level=logging.INFO)设置最低记录级别为INFO,因此DEBUG信息未显示。- 日志默认输出到控制台,格式为
时间 级别 名称: 消息。
示例2:自定义日志格式¶
目标¶
自定义日志输出格式,添加时间和级别。
代码¶
import logging
# 配置日志格式
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s'
)
# 获取日志记录器
logger = logging.getLogger("Example2")
# 记录日志
logger.debug("调试模式已开启")
logger.info("正在处理数据")
logger.error("数据处理失败")
运行结果¶
2025-04-01 10:00:00,123 - DEBUG - 调试模式已开启
2025-04-01 10:00:00,124 - INFO - 正在处理数据
2025-04-01 10:00:00,125 - ERROR - 数据处理失败
分析¶
format参数使用占位符:%(asctime)s:记录时间。%(levelname)s:日志级别。%(message)s:日志消息。
- 级别设为
DEBUG,所有日志都显示。
示例3:将日志存储到文件¶
目标¶
将日志保存到文件中,便于后续查看。
代码¶
import logging
# 配置日志,输出到文件
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
filename='app.log', # 日志文件路径
filemode='a' # 'a'表示追加,'w'表示覆盖
)
# 获取日志记录器
logger = logging.getLogger("Example3")
# 记录日志
logger.info("程序启动")
logger.warning("内存使用率较高")
logger.error("无法连接数据库")
运行结果¶
- 控制台无输出,日志写入
app.log文件:2025-04-01 10:00:00,123 - INFO - 程序启动 2025-04-01 10:00:00,124 - WARNING - 内存使用率较高 2025-04-01 10:00:00,125 - ERROR - 无法连接数据库
分析¶
filename指定日志文件路径。filemode='a'确保日志追加写入,不覆盖之前的内容。
示例4:同时输出到控制台和文件¶
目标¶
将日志同时记录到控制台和文件中。
代码¶
import logging
# 创建日志记录器
logger = logging.getLogger("Example4")
logger.setLevel(logging.DEBUG) # 设置记录器级别
# 创建控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO) # 控制台显示INFO及以上级别
# 创建文件处理器
file_handler = logging.FileHandler('app.log', mode='a')
file_handler.setLevel(logging.DEBUG) # 文件记录DEBUG及以上级别
# 定义日志格式
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
# 为处理器设置格式
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)
# 将处理器添加到记录器
logger.addHandler(console_handler)
logger.addHandler(file_handler)
# 记录日志
logger.debug("调试信息,仅写入文件")
logger.info("程序运行正常")
logger.error("发生错误")
运行结果¶
- 控制台输出:
2025-04-01 10:00:00,123 - INFO - 程序运行正常 2025-04-01 10:00:00,124 - ERROR - 发生错误 - app.log文件内容:
2025-04-01 10:00:00,123 - DEBUG - 调试信息,仅写入文件 2025-04-01 10:00:00,124 - INFO - 程序运行正常 2025-04-01 10:00:00,125 - ERROR - 发生错误
分析¶
- 使用
Handler分别控制输出目标:StreamHandler:输出到控制台。FileHandler:输出到文件。
- 不同处理器可设置不同级别,灵活性更高。
代码实现¶
整体结构¶
logging_lesson/
├── logs/
│ └── app.log # 日志文件
├── utils/
│ └── logger.py # 日志配置模块
├── main.py # 主程序入口
└── requirements.txt # 依赖文件(本例无需额外依赖)
日志配置模块 (utils/logger.py)¶
import logging
import os
def setup_logger(name, log_file='logs/app.log'):
# 确保日志目录存在
os.makedirs(os.path.dirname(log_file), exist_ok=True)
# 创建日志记录器
logger = logging.getLogger(name)
logger.setLevel(logging.DEBUG) # 设置最低级别
# 创建控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
# 创建文件处理器
file_handler = logging.FileHandler(log_file, mode='a')
file_handler.setLevel(logging.DEBUG)
# 定义日志格式
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s')
# 设置处理器格式
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)
# 添加处理器(避免重复添加)
if not logger.handlers:
logger.addHandler(console_handler)
logger.addHandler(file_handler)
return logger
主程序 (main.py)¶
from utils.logger import setup_logger
# 初始化日志记录器
logger = setup_logger("MainApp")
def process_data(data):
logger.debug(f"开始处理数据: {data}")
if not data:
logger.error("数据为空,无法处理")
return None
logger.info("数据处理完成")
return data.upper()
def main():
logger.info("程序启动")
result = process_data("hello")
if result:
logger.info(f"处理结果: {result}")
else:
logger.warning("处理失败")
logger.info("程序结束")
if __name__ == "__main__":
main()
运行结果¶
- 控制台输出:
2025-04-01 10:00:00,123 - INFO - MainApp - 程序启动 2025-04-01 10:00:00,124 - INFO - MainApp - 数据处理完成 2025-04-01 10:00:00,125 - INFO - MainApp - 处理结果: HELLO 2025-04-01 10:00:00,126 - INFO - MainApp - 程序结束 - logs/app.log 文件内容:
2025-04-01 10:00:00,123 - INFO - MainApp - 程序启动 2025-04-01 10:00:00,124 - DEBUG - MainApp - 开始处理数据: hello 2025-04-01 10:00:00,125 - INFO - MainApp - 数据处理完成 2025-04-01 10:00:00,126 - INFO - MainApp - 处理结果: HELLO 2025-04-01 10:00:00,127 - INFO - MainApp - 程序结束
总结¶
本课通过示例讲解了Python logging 模块的使用:
- 基础:使用
basicConfig快速配置日志。
- 自定义:设置格式、级别和输出目标。
- 存储:将日志保存到文件,同时支持控制台输出。
- 工程化:封装日志配置为模块,便于复用。
应用场景¶
- 在QA系统中,记录数据库连接、检索结果等状态。
- 调试时使用
DEBUG级别,生产环境调整为INFO或ERROR。