跳转到主要内容
LogBrew 是面向开发者和编程智能体的可观测性平台,提供充足的免费额度,无需绑卡。 本指南介绍如何用标准 logging 模块记录 Python 日志,并讲解 Python 的 5 个日志级别、Python 错误处理和常见的 Python 错误类型。最后几节使用 logbrew-sdk 0.1.29 把同样的日志和崩溃发送到 LogBrew。所有示例都在 Python 3.13 上运行过,每个输出块都是真实输出。 Flask 应用请改用 Flask 日志。它会在同一套日志配置中加入请求链路。

写出第一条 Python 日志

把这个文件保存为 app.py。在程序入口处调用一次 logging.basicConfig()。在每个模块中获取一个具名的记录器。
运行 python3 app.py。输出会写到标准错误。
级别是 INFO,所以 debug 记录不会出现。logger.exception() 以 ERROR 级别记录日志,并附上回溯信息。只在 except 块中调用它。 像 "payment retry %d of %d", 2, 3 这样把值作为参数传入。只有当处理器接受这条记录时,Python 才会构建消息。每次重试的消息模板都相同,因此可以按模板搜索。

Python 日志级别

只有当记录的级别等于或高于记录器的级别时,记录器才会发送这条记录。处理器还可以设置一个更高的第二级别。 根记录器的默认级别是 WARNING。新记录器的级别是 NOTSET(0),并沿用父记录器的级别。在生产环境中设置 INFO,只在开发或短时诊断时使用 DEBUG。
第 1 行代码显示一个模块的调试记录。第 2 行代码屏蔽某个库的噪声日志。

记录器、处理器和格式器

  • 记录器接收调用。使用 logging.getLogger(__name__),让记录器名称跟随模块路径。
  • 处理器把记录发送到目标位置,例如终端、文件或 LogBrew。
  • 格式器把记录转换为文本。
库不应配置日志。库只在自己的记录器上添加 logging.NullHandler()。应用只配置一次处理器和级别。配置较多时,使用 logging.config.dictConfig()。

Python 错误处理

捕获你能处理的最具体的异常。只在成功时运行的代码放在 else 中,始终要运行的代码放在 finally 中。用 raise ... from error 保留原始原因。 把这个文件保存为 orders.py。
输出显示了异常链中的两个异常。
对每个异常遵循以下规则。
  • 只在处理异常的地方记录一次。不要在每一层都记录后再重新抛出,因为每一层都会多出一条重复记录。
  • 不要写 except Exception: pass。如果要忽略某个错误,用 WARNING 或更高级别记录它,并写明原因。
  • 捕获 Exception,而不是 BaseException。BaseException 还会捕获 KeyboardInterrupt 和 SystemExit,而它们是有意停止程序的。
  • 为调用方必须处理的错误定义自己的异常类,就像 OrderError 这样。

报告多个错误

Python 3.11 及更高版本可以抛出 ExceptionGroup。当一次检查发现多个错误时使用它。用 except* 分别处理每种类型。

常见的 Python 错误类型

程序可以处理的内置错误都继承自 Exception。下表列出最常见的 Python 错误,以及每种错误应该先检查什么。 KeyboardInterrupt 和 SystemExit 继承自 BaseException,而不是 Exception。它们不是你代码中的错误。

把 Python 日志发送到 LogBrew

LogBrewLoggingHandler 是一个标准日志处理器。它会把接受的每条记录发送到 LogBrew。终端处理器保持不变。
1

创建项目密钥

使用 CLI 登录。创建一个项目,把它的接入密钥保存到仅所有者可访问的文件中。
CLI 不会输出密钥。在生产环境中,使用所在平台的密钥管理服务。
2

安装 SDK

激活应用的虚拟环境,然后安装这个包。它需要 Python 3.10 或更高版本。
3

配置密钥和部署标识

客户端会为每个信号加上服务、环境和版本。
4

添加处理器

把这个文件保存为 worker.py。在创建客户端之前调用 logging.basicConfig()。客户端会给根记录器添加一个处理器,而根记录器已有处理器时,basicConfig() 不会执行任何操作。
HttpTransport() 在后台发送信号,时机是第一个信号产生 1 秒后,或累计到 50 个信号时。client.shutdown() 会发送剩余的信号并关闭客户端。
5

运行程序

终端输出不变。LogBrew 为每条记录收到 1 条日志。下面是第一条日志,省略了共享的运行时上下文。
extra={...} 中的基本类型值会成为元数据。第二条日志的 exceptionName 为 KeyError,exceptionMessage 为 'seats'。要发送完整的回溯文本,创建处理器时传入 include_exception_text=True。
6

读回日志

读到匹配的结果,就说明 LogBrew 已存储这些日志。要从 CI 或编程智能体读取,使用项目只读密钥。参见验证接入。

选择发送到 LogBrew 的记录

给处理器设置单独的级别,可以减少发送的记录。终端仍会收到 INFO 及更高级别的记录。
Python 级别会映射为 LogBrew 级别。原始的级别名称和数值保留在元数据中。

把 Python 崩溃报告为问题

install_process_error_capture(client) 会报告脚本、worker 进程、启动代码和线程中未捕获的异常。每次崩溃都会成为 1 个问题,包含异常类型、消息、堆栈帧和异常链中的原因。Python 仍会像以前一样输出回溯信息并退出。 把这个文件保存为 startup.py 并运行。
LogBrew 会收到一个问题,标题为 FileNotFoundError,级别为 critical,机制为 python.excepthook。它的帧包含文件名、行号和函数,但不包含完整路径。线程中的崩溃级别为 error。Python 退出前,SDK 最多等待 2 秒完成发送。
问题中包含异常消息。不要在异常消息或日志消息中放入凭据或个人信息。参见日志脱敏。

故障排除

Web 应用参见 Flask 日志。要选择日志格式,参见结构化日志。其他运行时参见 SDK 接入。