Python 可观测性
日志、指标与追踪三支柱协同定位故障;在服务边界注入相关 ID 与关键指标。
#concept
#growing
#dev
#python
#python
[!info] related notes
Python 可观测性
这个概念为什么出现
系统变复杂后,“加日志”不够。需要:
- 指标:RED/USE
- 追踪:跨服务因果
- 日志:事件细节
日志与 trace 可通过 trace/span ID 或业务 correlation ID 关联;指标通常按低基数维度聚合,可用 exemplars 关联具体 trace,而不是把每个请求 ID 当作指标标签。
[!abstract] 一句话理解 可观测性让系统外部推断内部状态;日志+指标+追踪分工,统一在请求上下文中关联。
最小可运行示例
场景:为请求生成 correlation id 并打点
# correlation_id_demo.py
# 业务意图:模拟请求上下文 ID。
# 教学点:关联字段;计数指标雏形。
from uuid import uuid4
def handle_request(path: str, metrics: dict[str, int]) -> str:
cid = str(uuid4())
metrics["requests"] = metrics.get("requests", 0) + 1
return f"cid={cid} path={path} requests={metrics['requests']}"
def main() -> None:
metrics: dict[str, int] = {}
print(handle_request("/pay", metrics))
print(handle_request("/pay", metrics))
if __name__ == "__main__":
main()
建议运行:
python correlation_id_demo.py
期望输出:两行包含随机 UUID,requests 依次为 1、2。本例是单线程、单进程的字段演示,没有真正接入指标 SDK、导出器或跨服务追踪。
结合场景再看三个关注点
- 此例每次调用生成新 ID,只表示本地请求。跨服务 trace 需提取并传播上下文;只生成 UUID 不会自动连接上下游 span。
- 此字典的读改写不构成线程安全计数器,也不跨进程聚合;生产用具有相应并发与聚合语义的指标 SDK。
- OpenTelemetry 等提供标准导出。
核心概念与准确模型
| 支柱 | 问题 |
|---|---|
| Logs | 发生了什么 |
| Metrics | 多少/多快 |
| Traces | 请求路径 |
边界情况与反直觉行为
- 用户 ID、原始 URL、请求 ID 等高基数维度会增加时序数;HTTP 指标优先用规范化路由模板、状态类别等有限维度。
- PII 进日志
- 采样 丢稀有错误
常见误区
[!warning] 常见误区:指标越多越好 错误理解:全埋点。
正确模型:先 SLO 相关指标。
工程实践
- 统一中间件埋点
- 错误率/延迟直方图
- 结构化日志
本节总结
可观测性是运营接口。设计信号,而不是堆文本。
自测题
- 三支柱各回答什么?
- 为何避免用户 ID 当 metric label 无限制?
参考答案
- 事件细节、聚合量、因果路径。
- 高基数导致存储与查询爆炸。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| OpenTelemetry Python | 文档 | 标准可观测 |