跳至内容
快速入门 logging 模块

快速入门 logging 模块

2026年03月05日·竹子是不秋草
竹子是不秋草

日志-项目的黑匣子,是排查问题的利器。logging 模块的核心包括记录器、处理器、格式器,初步掌握它们等于入门。

记录器

记录器是日志记录的入口点,开发者可以通过它发送日志信息。

创建记录器

创建记录器时,最佳实践是模块级命名 logger,按模块划分:

module_a.py
1
2
3
4
5
import logging

# 获取当前模块的logger
# `__name__`是 Python 内置变量,代表当前模块的完整路径名,这种方式会创建 / 获取模块级别的 logger。
logger = logging.getLogger(__name__)

也可以自定义命名 logger,它的特定是可以按业务逻辑划分:

module_a.py
1
2
3
4
5
import logging

# 获取当前模块的logger
# `__name__`是 Python 内置变量,代表当前模块的完整路径名,这种方式会创建 / 获取模块级别的 logger。
db_logger = logging.getLogger("run.db")

通过记录器发送日志信息

可以通过 logger.debug()logger.info()logger.warning()logger.error()logger.critical() 方法,发送日志消息。它们对应不同的日志级别。

日志记录级别定义,可以查看logging-日志级别。不过我觉得官方文档的解释有点让人不理解,我这里再解释一下:

级别 核心定义 场景示例
debug 细粒度的调试信息,用于开发、测试阶段定位代码执行细节、验证逻辑正确性 1. “计算商品总价:单价 ={price},数量 ={count}结果 ={total}"
2. “数据库查询结果:{data}"
3. “请求参数:{request_params}”
info 记录系统 / 程序正常运行的关键事件,反映核心流程完成状态 1. “服务启动成功,监听地址:http://0.0.0.0:5000”
2. “用户 {user_id} 成功上传文件:{file_name}"
3. “数据批量导入完成,共导入 {num} 条数据”
warning 非致命的异常 / 潜在风险(不影响程序运行,但可能引发后续问题) 1. “配置文件中未找到超时参数,使用默认值:30s”
2. “连接 Redis 超时,已自动重试(第 1 次)"
3. “用户输入的邮箱格式不合法:{email},已忽略该字段”
error 单个功能 / 操作执行失败(程序整体仍可运行,但需排查修复) 1. “调用第三方接口 {api_url} 失败,错误信息:{e}"
2. “写入、读取文件 {file_path} 失败,原因:路径错误”
3. “数据库更新操作失败,SQL:{sql},错误:{e}”
critical 系统级致命错误,导致程序 / 核心模块无法运行,必须立即处理 1. “无法连接核心数据库,数据库地址:{db_host},服务即将退出”"
2. “核心配置文件 {config_path} 缺失或损坏,无法初始化程序”

下述代码,发送日志消息后,由于没有添加处理器,运行后,在终端只能看到 warning 及以上级别的日志消息(默认处理器):

module_a.py
1
2
3
4
5
6
7
8
9
import logging

logger = logging.getLogger(__name__)

logger.debug("这是一条 debug 消息.")
logger.info("这是一条 info 消息.")
logger.warning("这是一条 warning 消息.")
logger.error("这是一条 error 消息.")
logger.critical("这是一条 critical 消息.")

运行后,控制台输出信息:

这是一条 warning 消息.
这是一条 error 消息.
这是一条 critical 消息.

配置记录最低级别日志消息

Logger.setLevel() 可以指定记录器将处理的最低等级日志信息,低于设置级别的日志信息将不被处理,最低等级及更高级别的日志信息会被处理。级别排序:DEBUG<INFO<WARNING<ERROR<CRITICAL

下述代码中,只处理 error 及以上级别的日志消息:

module_a.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.ERROR)

logger.debug("这是一条 debug 消息.")
logger.info("这是一条 info 消息.")
logger.warning("这是一条 warning 消息.")
logger.error("这是一条 error 消息.")
logger.critical("这是一条 critical 消息.")

运行后,控制台输出信息:

这是一条 error 消息.
这是一条 critical 消息.

处理器

处理器负责将日志记录(LogRecord)输出到指定目标。除了本文示例,更多处理器,读者可查看有用的处理器

输出到控制台

处理器 StreamHandler 可以将日志消息输出到控制台:

module_a.py
import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)


# 创建控制台处理器
console_handler = logging.StreamHandler()
# 将控制台处理器绑定到记录器
logger.addHandler(console_handle)

logger.debug("这是一条 debug 消息.")
logger.info("这是一条 info 消息.")
logger.warning("这是一条 warning 消息.")
logger.error("这是一条 error 消息.")
logger.critical("这是一条 critical 消息.")

运行后,控制台输出信息:

这是一条 debug 消息.
这是一条 info 消息.
这是一条 warning 消息.
这是一条 error 消息.
这是一条 critical 消息.

输出到文件

处理器 FileHandler 可以将日志消息输出文件:

module_a.py
import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)


# 创建控制台处理器
flie_handler = logging.FileHandler("all.log")
# 将控制台处理器绑定到记录器
logger.addHandler(flie_handle)

logger.debug("这是一条 debug 消息.")
logger.info("这是一条 info 消息.")
logger.warning("这是一条 warning 消息.")
logger.error("这是一条 error 消息.")
logger.critical("这是一条 critical 消息.")

运行后,会输出日志信息到 all.log 文件:

这是一条 debug 消息.
这是一条 info 消息.
这是一条 warning 消息.
这是一条 error 消息.
这是一条 critical 消息.

配置输出最低级别日志消息

处理器同样可以指定记录器将输出的最低等级日志信息。实践中,记录器设置的日志信息等级最好等于或小于处理器设置的日志信息等级(不然日志消息会被屏蔽,无意义):

module_a.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

console_handler = logging.StreamHandler()
# 配置控制台处理器的最低日志等级。其他处理器相同。
console_handler.setLevel(logging.ERROR)

logger.addHandler(console_handle)

logger.debug("这是一条 debug 消息.")
logger.info("这是一条 info 消息.")
logger.warning("这是一条 warning 消息.")
logger.error("这是一条 error 消息.")
logger.critical("这是一条 critical 消息.")

运行后,控制台输出信息:

这是一条 error 消息.
这是一条 critical 消息.

格式器

格式化器用于配置日志消息的最终顺序、结构和内容:

module_a.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
# 自定义控制台日志格式
console_formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(funcName)s:%(lineno)d - %(message)s'
)
# 将格式器绑定到控制台处理器
console_handler.setFormatter(console_formatter)

logger.addHandler(console_handle)

logger.debug("这是一条 debug 消息.")
logger.info("这是一条 info 消息.")
logger.warning("这是一条 warning 消息.")
logger.error("这是一条 error 消息.")
logger.critical("这是一条 critical 消息.")

运行后,控制台输出信息:

2026-03-09 11:26:36,867 - __main__ - DEBUG - <module>:17 - 这是一条 debug 消息.
2026-03-09 11:26:36,867 - __main__ - INFO - <module>:18 - 这是一条 info 消息.
2026-03-09 11:26:36,867 - __main__ - WARNING - <module>:19 - 这是一条 warning 消息.
2026-03-09 11:26:36,867 - __main__ - ERROR - <module>:20 - 这是一条 error 消息.
2026-03-09 11:26:36,867 - __main__ - CRITICAL - <module>:21 - 这是一条 critical 消息.

消息格式字符串将使用 %(<dictionary key>)s 样式的字符串替换,可用的键值记录可以在 LogRecord 属性中查看。

下一步

本篇主旨是帮助读者快速入门 logging 模块,想要详细掌握需要阅读logging — Python 的日志记录工具

最后更新于