Python 日志¶
核心构成¶
logging 主要由四个核心组件构成,共同完成日志的记录和输出。
-
Logger (记录器)
-
作用: 这是我们与日志系统交互的主要入口。代码中通过调用 Logger 的方法(如
logger.info(),logger.error())来产生日志记录。 - 获取方式:
logging.getLogger(name)。 -
层级关系: Logger 是有层级结构的,类似 Python 的包名。子 logger 会将日志消息传递给父 logger 的处理器(handler),可使用
logger.propagte=False关闭传递。 -
Handler (处理器)
-
作用: 决定日志记录最终被发送到哪里。它可以是控制台、文件、网络套接字等。
- 常见类型:
StreamHandler: 输出到控制台。FileHandler: 输出到文件。RotatingFileHandler: 输出到文件,并按大小自动分割旧日志。TimedRotatingFileHandler: 输出到文件,并按时间自动分割旧日志。
-
配置: 可以为 Handler 设置独立的日志级别(Level),只处理达到该级别的日志。
-
Formatter (格式化器)
-
作用: 定义最终输出的日志消息的格式、结构和内容。
- 配置: 通过一个格式字符串来定义,其中包含多个占位符。
-
常用占位符:
%(asctime)s: 日志记录的创建时间,如2025-09-19 03:17:37,123。%(levelname)s: 日志级别(DEBUG,INFO,WARNING,ERROR,CRITICAL)。%(name)s: Logger 的名字。%(message)s: 我们代码中实际传递的日志消息。%(filename)s: 文件名。%(lineno)d: 行号。
-
Level (级别)
-
作用: 用于标记日志消息的重要性或严重程度。只有当日志消息的级别 大于或等于 Logger 和 Handler 设置的级别时,才会被处理。
- 级别从低到高:
- DEBUG: 调试:最详细的日志
- INFO: 信息:非报错,记录有用的信息,如关键条件分支等(如:开始调用外部厂商接口)
- WARN/WARNING: 警告:应关注并适时解决,并不会导致业务故障(如:缓存应当存在,但是程序也可以创建新的缓存)
- ERROR: 错误:业务故障,程序知道怎么回事,可处理(中断/容错)
- FATAL: 致命错误:业务故障,程序不知道怎么处理,错误原因不明,导致中断
- CRITICAL: 关键故障:业务故障,应当优先人工干预
代码示例¶
import logging
import os
# 1. 设置日志级别
# 从环境变量 "LOG_LEVEL" 获取级别,如果不存在,则默认为 "DEBUG"
LOG_LEVEL = os.getenv("LOG_LEVEL") or "DEBUG"
def setup_logger(name="default") -> logging.Logger:
"""初始化logger"""
# 2. 获取 Logger 实例
# logging.getLogger(name) 会获取一个指定名称的 logger
# 如果多次用同一个名字调用,会返回同一个实例
logger = logging.getLogger(name)
# 3. 设置 Logger 的级别
# logger.setLevel() 设置了这个 logger 会处理的最低级别
logger.setLevel(LOG_LEVEL.upper())
# 4. 防止重复添加 Handler
# logger.handlers 是一个列表,存储了所有关联的 handler
# 这个判断确保了即使多次调用 setup_logger(),也只会添加一次 handler
if not logger.handlers:
# 5. 创建 Handler
# StreamHandler() 会将日志输出到控制台
handler = logging.StreamHandler()
# 6. 创建 Formatter
# 定义了日志的输出格式:时间 [级别] logger名: 消息
formatter = logging.Formatter(
"%(asctime)s [%(levelname)s] %(name)s: %(message)s"
)
# 7. 将 Formatter 关联到 Handler
handler.setFormatter(formatter)
# 8. 将 Handler 关联到 Logger
# 一个 logger 可以有多个 handler,比如同时输出到控制台和文件
logger.addHandler(handler)
return logger
if __name__ == "__main__":
# 9. 使用配置好的 Logger
# 调用函数获取一个名为 "default" 的 logger 实例
logger = setup_logger()
# 10. 产生不同级别的日志
# 因为 LOG_LEVEL 默认为 "DEBUG",所以所有级别的日志都会被显示
logger.debug("debug")
logger.info("info")
logger.warning("warning")
logger.error("error")
运行结果:
如果直接运行这个脚本,由于 LOG_LEVEL 默认为 DEBUG,会看到所有级别的日志:
2025-09-19 03:17:37,123 [DEBUG] default: debug
2025-09-19 03:17:37,123 [INFO] default: info
2025-09-19 03:17:37,123 [WARNING] default: warning
2025-09-19 03:17:37,123 [ERROR] default: error
如果在终端中设置环境变量,比如LOG_LEVEL=WARN python test.py,或在WINDOWS的POWERSHELL中$env:LOG_LEVEL="WARN"; python test.py, 那么只有 WARN 及以上级别的日志才会被显示:
2025-09-19 03:17:37,456 [WARNING] default: warning
2025-09-19 03:17:37,456 [ERROR] default: error