日志编写(python)——Logging

🌟 第一步:先认识 logging 能做什么

想象你在写一个程序,你想知道:

  • 程序什么时候启动/结束?
  • 用户做了什么操作?
  • 哪里出错了?为什么出错?

日志(logging)就是用来记录这些信息的工具,比 print() 更专业、更强大。


🔧 第二步:最最基础的用法(3 行代码)

import logging logging.warning("这是一个警告信息")

运行结果(在终端):

WARNING:root:这是一个警告信息

✅ 你看,不用配置,直接就能用!

但注意:

  • 默认只显示 WARNING 及以上级别 的日志(INFO 和 DEBUG 不会显示)
  • 默认输出到 控制台
  • 日志格式是固定的:级别:logger名:消息

📚 第三步:五大核心函数(按严重程度排序)

函数

用途

示例

logging.debug()

调试细节(开发时用)

logging.debug("变量 x = %d", x)

logging.info()

一般信息

logging.info("服务已启动")

logging.warning()

警告(可能有问题)

logging.warning("磁盘空间不足")

logging.error()

错误(功能异常)

logging.error("数据库连接失败")

logging.critical()

严重错误(程序可能崩溃)

logging.critical("配置文件丢失!")

💡 记住口诀:D-I-W-E-C(Debug → Critical,严重性递增)


⚙️ 第四步:如何让 INFO 和 DEBUG 也显示出来?

默认不显示它们,因为 logging 有一个 “最低级别” 设置。

方法:使用 basicConfig()

import logging # 必须在第一次调用 logging 之前配置! logging.basicConfig(level=logging.DEBUG) logging.debug("调试信息") # 会显示 logging.info("普通信息") # 会显示 logging.warning("警告") # 会显示

输出:

DEBUG:root:调试信息 INFO:root:普通信息 WARNING:root:警告

level=logging.DEBUG 表示:显示 DEBUG 及以上所有级别

可选值:DEBUG, INFO, WARNING, ERROR, CRITICAL


🎨 第五步:自定义日志格式(Formatter)

默认格式太简单,我们想加上 时间、行号、函数名 等。

使用 format 参数:

import logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) logging.info("程序开始运行")

输出:

2026-01-14 13:30:45,123 - INFO - 程序开始运行

常用格式占位符:

占位符

含义

%(asctime)s

时间(如 2026-01-14 13:30:45,123)

%(levelname)s

日志级别(INFO/WARNING等)

%(message)s

你写的日志内容

%(name)s

logger 名称(默认是 "root")

%(filename)s

文件名

%(funcName)s

函数名

%(lineno)d

行号

更详细的例子:
format='%(asctime)s - %(name)s - %(funcName)s:%(lineno)d - %(levelname)s - %(message)s'

输出:

2026-01-14 13:35:01,456 - root - <module>:10 - INFO - 用户登录

💾 第六步:把日志写入文件(Handler)

光在控制台看不够,我们要保存到文件!

方法1:用 filename 参数(最简单)

import logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(message)s', filename='my_app.log' # ← 关键!日志写入文件 ) logging.info("这条日志会写入文件,不会显示在控制台")

⚠️ 注意:加了 filename 后,默认不再输出到控制台


方法2:同时输出到文件 + 控制台(推荐)

这时候就要用到 Handler 了(前面提过的四大组件之一)。

import logging # 创建 logger logger = logging.getLogger('my_logger') logger.setLevel(logging.DEBUG) # 创建两个 Handler console_handler = logging.StreamHandler() # 控制台 file_handler = logging.FileHandler('app.log') # 文件 # 设置格式 formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') console_handler.setFormatter(formatter) file_handler.setFormatter(formatter) # 把 Handler 加到 logger logger.addHandler(console_handler) logger.addHandler(file_handler) # 使用 logger.info("这条日志会同时出现在控制台和文件中!")

✅ 这是企业项目中最常见的做法!


🔄 第七步:防止日志文件太大(日志轮转)

如果程序一直运行,日志文件会越来越大,最后撑爆硬盘!

解决方案:使用 RotatingFileHandler

import logging from logging.handlers import RotatingFileHandler logger = logging.getLogger('my_app') logger.setLevel(logging.INFO) # 创建轮转 handler:单个文件最大 1MB,保留 3 个备份 handler = RotatingFileHandler( 'app.log', maxBytes=1_000_000, # 1MB backupCount=3 # app.log.1, app.log.2, app.log.3 ) handler.setFormatter(logging.Formatter('%(asctime)s - %(message)s')) logger.addHandler(handler) # 测试:写很多日志 for i in range(10000): logger.info(f"这是第 {i} 条日志")

app.log 超过 1MB,系统会自动:

  1. app.log 改名为 app.log.1
  2. 新建一个空的 app.log
  3. 如果已有 app.log.3,就删除它(只保留3个)

🛠️ 第八步:记录异常(非常重要!)

当程序出错时,光说“出错了”没用,要看到 完整的错误堆栈

错误做法:

try: 1 / 0 except Exception as e: logging.error("出错了:" + str(e)) # ❌ 只有错误信息,没有堆栈!

正确做法(两种):

方法1:exc_info=True
try: 1 / 0 except Exception: logging.error("发生异常", exc_info=True) # ✅ 自动附带完整 traceback
方法2:logger.exception()(仅在 except 块中用)
try: 1 / 0 except Exception: logging.exception("发生异常") # ✅ 等价于 error(..., exc_info=True)

输出会包含:

ERROR:root:发生异常 Traceback (most recent call last): File "...", line 3, in <module> 1 / 0 ZeroDivisionError: division by zero

🧩 第九步:每个模块用独立的 Logger(最佳实践)

在大项目中,不同模块(如数据库、API、任务调度)应该有独立的日志命名空间

utils/db.py

import logging # 使用 __name__ 自动获得模块名:'utils.db' logger = logging.getLogger(__name__) def connect(): logger.info("正在连接数据库") # ...

main.py

import logging from utils.db import connect # 配置一次即可 logging.basicConfig(level=logging.INFO) connect()

输出:

INFO:utils.db:正在连接数据库

✅ 好处:你可以单独控制某个模块的日志级别!比如只让 utils.db 显示 DEBUG,其他保持 INFO。


📝 总结:新手必须记住的 6 个要点

内容

说明

1. 用 logging

,别用 print

更专业、可配置、线程安全

2. 五大函数:debug/info/warning/error/critical

按严重程度选择

3. 用 basicConfig()

快速配置

但只能调用一次!

4. 格式用 format

参数或 Formatter

推荐包含时间、级别、消息

5. 写文件用 FileHandler

filename

生产环境必须持久化日志

6. 记录异常用 exc_info=True

exception()

否则看不到错误原因!