Python 项目日志管理指南:从 print 告别到专业日志

不少新手习惯使用 print() 调试自己的 Python 项目吗。在本地测试时,print("执行到第3步")这种 似乎很方便,但一旦项目上线,这些信息就会丢失在控制台中。当错误发生时,将无法回溯"什么时候错了、错在哪",项目如同缺少了"黑匣子"。

专业的日志管理能记录项目运行的"台账",不仅能分级(如普通信息、错误警告),还能持久化存储,让我们在问题发生时能按时间、按模块快速定位。

本文将入门 Python 日志管理:从为什么需要日志开始,介绍 2 个主流库(loggingloguru)的代码实例,并总结 5 条项目级的日志规范。


一、为什么日志(Logging)远胜于打印(Print)?

print 是一个"临时便利贴",而日志是项目的"正式台账"。对于任何非临时脚本的项目,日志管理都是必需的。

对比项 print() 调试 日志管理工具 (Logging)
信息分级 没有分级(所有输出都一样) (DEBUG, INFO, ERROR 等)
持久化存储 只在控制台显示,关闭即丢失 (存到文件、数据库等)
配置灵活性 格式固定(只能打印内容) (添加时间、模块名、行号)
线上可用性 几乎为零(无法追溯历史) (快速排查线上问题)

二、新手入门:2 个主流日志库

Python 日志库分为自带的标准库和功能更简洁的第三方库。掌握这两个,足以应对 90% 的项目场景。

2.1 选项 1:自带库 logging (功能全面,无需安装)

logging 是 Python 的标准库,功能强大且高度可定制,但配置相对繁琐。

1. 基础用法:3 行代码输出到控制台

logging 默认只显示 WARNING 及以上级别的日志,可以通过 basicConfig 调整。

python 复制代码
# 1. 导入自带的 logging 库
import logging

# 2. 配置日志级别(关键!低于这个级别的日志不会输出)
# 级别从低到高:DEBUG < INFO < WARNING < ERROR < CRITICAL
logging.basicConfig(level=logging.DEBUG)  # 这里设为DEBUG,所有级别都能输出

# 3. 输出不同级别的日志
logging.debug("这是DEBUG级日志:开发时调试用,比如「变量a=10」")
logging.info("这是INFO级日志:正常运行信息,比如「服务启动成功」")
logging.warning("这是WARNING级日志:潜在问题,比如「内存快满了」")
logging.error("这是ERROR级日志:功能出错,比如「数据库连接失败」")
logging.critical("这是CRITICAL级日志:致命错误,比如「服务崩溃」")
  • 优点:简单,一行代码就能用。

  • 缺点(也是实际项目的痛点)

    • 默认把所有日志都混在一起

    • 通常只能输出到一个地方(要么控制台,要么文件,很难同时兼顾)

    • 无法处理日志文件过大的问题(日志轮转)

2. 进阶用法:存到文件 + 自定义格式 + 日志轮转

在实际项目中,不会使用 basicConfig,而是通过配置 LoggerHandlerFormatter 来实现专业日志。

  • Logger (日志器): 产生日志的对象,在代码中主要与它交互(如 logger.info())。

  • Handler (处理器): 决定日志的去向,比如输出到控制台 (StreamHandler) 或文件 (FileHandler)。

  • Formatter (格式器): 定义日志的输出格式(如时间、级别、模块名等)。

python 复制代码
import logging
# TimedRotatingFileHandler 用于按时间自动切割日志文件
# RotatingFileHandler 用于按大小自动切割日志文件
from logging.handlers import TimedRotatingFileHandler, RotatingFileHandler

# 1. 创建一个日志"器"(logger对象)
# __name__ 会使用当前模块的 Python 名称(例如 'my_module')
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)  # 设置日志器的总级别

# 2. 定义日志格式
formatter = logging.Formatter(
    # asctime:时间;levelname:级别;module:模块名;lineno:行号;message:内容
    "%(asctime)s - %(levelname)s - %(module)s:%(lineno)d - %(message)s"
)

# 3. 配置"控制台输出"处理器
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)  # 应用格式
logger.addHandler(console_handler)  # 添加到日志器

# 4. 配置"文件输出"处理器(核心)
# TimedRotatingFileHandler:按时间轮转
file_handler = TimedRotatingFileHandler(
    filename="app.log",  # 日志文件名
    when="D",  # 轮转频率:D=天, H=小时, M=分钟
    backupCount=7,  # 保留7天的日志文件
    encoding="utf-8"  # 避免中文乱码
)
# file_handler = RotatingFileHandler(
#     filename="app.log",
#     # maxBytes: 单个日志文件的最大大小(字节)
#     # 1024 * 1024 * 10 = 10MB (这里设置为 10MB 切割一次)
#     maxBytes=10 * 1024 * 1024,  
#     backupCount=5,     # 保留最近的 5 个文件
#     encoding="utf-8"
# )

file_handler.setFormatter(formatter)  # 应用格式
logger.addHandler(file_handler)  # 添加到日志器

# 5. 测试日志输出
if __name__ == "__main__":
    logger.info("服务启动成功,端口8000")
    try:
        1 / 0  # 故意制造错误
    except Exception as e:
        # exc_info=True 会自动打印完整的错误堆栈信息
        logger.error(f"计算出错:{str(e)}", exc_info=True)

运行效果 (app.log 文件内容):

2.2 选项 2:第三方库 loguru (配置极简,开箱即用)

如果觉得 logging 配置太麻烦,强烈推荐使用 loguru。它 API 极简,一行代码就能实现文件输出、轮转和彩色日志。

1. 安装 loguru

bash 复制代码
pip install loguru

2. 基础用法:一行配置搞定

loguru 的设计理念是"开箱即用",导入后直接使用 logger 对象。

python 复制代码
# 1. 导入 loguru(不用复杂配置,直接用 logger 对象)
from loguru import logger

# 2. 配置日志存到文件(一行搞定!)
# sink:日志文件路径
# rotation:轮转规则(这里是按大小,500MB一个文件)
# retention:保留策略(保留10个文件)
logger.add(sink="app_loguru.log", rotation="500 MB", retention=10, encoding="utf-8")

# 3. 输出日志(用法和 logging 类似,但更直观)
logger.debug("调试信息:用户请求参数为{'name':'张三'}")
logger.info("正常信息:用户登录成功,ID=123")
logger.error("错误信息:数据库连接超时,地址=localhost:3306")

运行效果:

  • 控制台 会显示彩色日志(DEBUG 蓝色、INFO 绿色、ERROR 红色)。

  • app_loguru.log 文件内容格式清晰:

3. 进阶用法:自定义格式 + 自动捕获异常

loguru 在捕获异常时也极其简单。

python 复制代码
from loguru import logger

# 自定义日志格式(加模块名、行号)
logger.add(
    sink="app_loguru2.log",
    format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {module}:{line} | {message}",
    rotation="1 day",  # 按天轮转
    retention=7,       # 保留7天
    encoding="utf-8"
)

# 捕获异常(不用写 exc_info=True,直接用 exception 方法)
try:
    1 / 0
except Exception as e:
    # exception() 方法会自动打印完整的堆栈信息
    logger.exception(f"计算错误:{str(e)}")

三、项目必守!5 条企业级日志规范

学会工具只是第一步,在项目中使用规范的日志才是关键。

规范 1:日志级别别乱用,按场景选对级别

不要所有日志都用 INFOERROR,这会导致关键错误被淹没。

级别 适用场景 例子
DEBUG 本地开发调试,上线后应关闭 "变量 x 的值为 10","请求 URL:/api/login"
INFO 项目正常运行的关键节点 "服务启动成功","用户注册:手机号 138xxxx"
WARNING 有潜在问题,但不影响当前功能 "缓存过期,已自动刷新","内存使用率达 80%"
ERROR 某个功能出错,但服务还能跑 "用户张三登录失败:密码错误","订单创建失败"
CRITICAL 致命错误,服务无法运行 "数据库连接失败","端口 8000 被占用,服务启动失败"

反面教材: 把"用户输入错误密码"标为 CRITICAL。------ 这是 ERRORWARNING 级别的事件,服务并未崩溃。

规范 2:日志内容要含"三要素",拒绝模糊表述

糟糕的日志:"连接失败"、"登录出错"。

好的日志必须包含:时间(工具自动加)+ 具体场景 + 关键信息。

反面例子 正面例子(好的日志)
"连接失败" "连接 MySQL 数据库失败,地址:localhost:3306,错误:超时"
"用户登录出错" "用户登录失败,手机号:138xxxx,原因:密码错误"
"循环执行错了" "处理订单循环出错,订单 ID:1001,错误:索引越界"

秘诀: 日志应该能回答"什么时候、谁、做了什么、结果如何(或出了什么问题)"。

规范 3:日志文件"按规则命名 + 自动轮转"

不要把所有日志都堆在一个 log.txt 里,这会导致单个文件过大(几十 GB),难以打开和分析。

  • 命名格式: 建议使用 项目名_日期.log (如 shop_app_20240520.log)。

  • 自动轮转: 必须配置日志轮转,避免占满磁盘。

    • 按时间: 每天一个新文件 (如 rotation="1 day")。

    • 按大小: 每个文件不超过 500MB (如 rotation="500 MB")。

  • 日志清理: 必须配置保留策略,如保留 30 天内的日志 (如 retention=30)。

规范 4:敏感信息绝对不写进日志!

这是安全红线! 日志文件也可能被泄露,绝对不能包含:

  • 密码、Token、API 密钥

  • 用户手机号、身份证号、银行卡号

  • 完整的数据库连接字符串

正确做法: 必须记录时,一定要用"*"脱敏。

  • 错误: logger.info(f"用户登录,用户名=admin,密码={password}")

  • 正确: logger.info(f"用户登录,用户名=admin,密码=******")

规范 5:项目里统一配置日志,不要重复写

不要在每个 .py 文件里都写一遍日志配置。正确的做法是:

  1. 单独创建一个 logger_config.py 文件,在里面完成所有 loggingloguru 的配置。

  2. 在其他模块中(如 main.py, db.py),只导入 这个配置好的 logger 对象来使用。

项目结构实例:

复制代码
my_project/
├─ logger_config.py   # 统一日志配置文件
├─ main.py            # 主程序
└─ db.py              # 数据库操作

logger_config.py (用 loguru 举例):

python 复制代码
from loguru import logger

# 1. 移除 loguru 默认的控制台输出
logger.remove()

# 2. 统一配置"控制台"输出
logger.add(
    sink=sys.stderr,  # 输出到控制台
    level="INFO",     # 控制台只显示 INFO 及以上级别
    format="{time:HH:mm:ss} | {level} | {message}"
)

# 3. 统一配置"文件"输出
logger.add(
    sink="logs/shop_app_{time:YYYYMMDD}.log", # 日志文件路径
    level="DEBUG",    # 文件中记录 DEBUG 及以上所有级别
    format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {module}:{line} | {message}",
    rotation="1 day",
    retention=7,
    encoding="utf-8"
)

# 4. 把 logger 导出,供其他模块使用
# (在 loguru 中,导入即可,无需显式导出)

main.py (导入使用):

python 复制代码
# 从配置文件导入 logger,不用再配置
from logger_config import logger

def start_server():
    logger.info("服务启动成功,端口8000")  # 直接用
    logger.debug("这是一个调试信息,只会出现在文件里")

if __name__ == "__main__":
    start_server()

四、总结:新手该选哪个日志库?

  • 想快速上手,功能够用:loguru。配置简单,API 直观,彩色日志和异常捕获非常方便。

  • 需要深度定制,或在严格限制第三方库的环境中:logging。它是官方标准,功能最全,虽然配置复杂,但扩展性最强。

相关推荐
许泽宇的技术分享5 小时前
当AI学会“说人话“:Azure语音合成技术的魔法世界
后端·python·flask
光泽雨5 小时前
python学习基础
开发语言·数据库·python
裤裤兔5 小时前
python爬取pdf文件并保存至本地
chrome·爬虫·python·pdf·网络爬虫
Solyn_HAN6 小时前
非编码 RNA(ceRNA/lncRNA/circRNA)分析完整流程:从数据下载到功能验证(含代码模板)
python·bash·生物信息学·r
CesareCheung6 小时前
JMeter 进行 WebSocket 接口压测
python·websocket·jmeter
beijingliushao6 小时前
95-Python爬虫-正则表达式
爬虫·python·正则表达式
百***06016 小时前
python爬虫——爬取全年天气数据并做可视化分析
开发语言·爬虫·python
吃个糖糖6 小时前
pytorch 卷积操作
人工智能·pytorch·python
麦麦麦造6 小时前
比 pip 快 100 倍!更现代的 python 包管理工具,替代 pip、venv、poetry!
后端·python
AndrewHZ6 小时前
【图像处理基石】图像去雾算法入门(2025年版)
图像处理·人工智能·python·算法·transformer·cv·图像去雾