文档/通用观测平台设计

通用观测平台设计#

Luma Observe 接收标准遥测,应用拥有埋点、业务字段、面板和告警定义。部署管理与观测接入是两种独立能力。Python SDK 是官方 OpenTelemetry 的可选薄封装;其他语言或已有 OTel SDK 可以直接接入。

本文区分本分支源码与后续方案,不代表生产部署或容量验收已经完成。接入参数见标准应用观测接入,Python API 见SDK 指南。

接入身份与外部应用#

任务执行与采样#

每次框架执行建立独立 Trace,用标准 SpanLink 连接投递上下文。重新投递保留旧上下文的 Link;它表达因果关系,不把两次执行合成一次。消息准备 Span 不代表 Broker 已接收。没有 exporter 的生产者仍可写排队时间戳;显式禁用 SDK 时不改投递标签。

独立执行 Trace 避免排队时间提前消耗 Collector 的采样等待窗口。运行中较早结束的子 Span 仍可能触发决定,因此 Collector 对没有父 Span、带 task.name / task.framework 的 CONSUMER 根 Span 使用单独的完成摘要采样分支:在完成时按错误、耗时和基础比例决定保留。普通子 Span 保持现有采样。存储采样前,每个接收的 Span 在默认 RED 与主动开启的服务级 RED connector 中只走一个、生成一次。开启模式的应用额外生成执行根 Span 专用的 task_span_* 指标族,见按服务聚合 Span 指标。任务量不能把 RED calls、任务根计数和原生任务计数相加,RED 还包含生产者与子 Span。

这个设计保留已接收的失败/慢任务根摘要;它不保证长任务所有子 Span 都完整,也不覆盖强杀、进程崩溃、SDK 头采样或导出丢失。需要完整长 Trace 时,应为指定服务安排有配额的全收集或一致的 Trace ID 采样方案,不能无限增大 decision_wait。

执行状态由 SDK 执行上下文持有;消息中只携带可序列化的传播标签。Taskiq 使用正常完成钩子和 asyncio Task 完成兜底结束尝试,并在 Broker shutdown 限时 flush;flush 不关闭同进程共享 Provider。Celery 使用公开任务及进程信号。业务异常、返回值、重试、结果保存和 ACK 仍由框架负责。

高频负载与可靠性#

层级 当前机制 边界
SDK Trace 内存队列 512、批次 64;Metrics 本地聚合、默认每 30 秒导出;有界超时和 flush 不阻塞业务等待平台恢复;溢出、硬退出和导出失败可能丢失
Collector 内存限制、批处理、有界采样状态;Tempo exporter 128 请求队列与重试;PRW 128 OTLP metrics batch 队列 当前没有持久导出队列或 PRW WAL;Collector 重启会丢内存数据
存储 Tempo、VictoriaMetrics、VictoriaLogs 的现有磁盘存储和保留期 仅保护已到达该存储的数据;当前单 Manager、单副本部署不是 HA
业务可靠性 业务自己的事务、outbox、消息队列及结果存储 计费、审计、任务交付不能依赖可采样、可丢失的遥测

高频调用优先使用本地 Counter / Histogram 聚合,避免每次调用发一个网络请求。标签必须有限;任务参数、用户 ID、执行 ID、异常全文不进入通用指标标签。

进程心跳时间戳表示指标采集/导出路径仍在工作,最老活跃执行时长按任务名、队列和框架表示尚未结束的尝试已经运行多久。面板须按完整任务与进程身份匹配 task_active > 0,并检查心跳新鲜度及 tracking overflow,排除已结束任务的旧时长。心跳新鲜且活跃数明确为零才能解释为本进程空闲;活跃时间持续增长需要结合任务预算判断。指标线程存活不证明事件循环或业务有进展,缺失数据也不等于零。Broker 积压数、最老未消费消息年龄和业务进度需要由应用或 Broker 的标准指标提供。

service.instance.id 必须区分并发写入累计指标的进程。简单移除该维度会把独立计数器和直方图混为一条序列,破坏 Single Writer 语义。频繁轮换的 Celery child 确实会增加序列创建速率;上线验收需要测量进程轮换率、任务/队列/结果维度和 VictoriaMetrics 实际新增序列。若达到预算,再评估稳定的聚合 Agent 或经验证的 delta 聚合路径;不能仅靠重写标签合并累计序列。

下一阶段可靠性方案(本轮未实施):

  1. Tempo exporter 使用官方 file_storage 持久发送队列;Prometheus Remote Write 使用该 exporter 专用 WAL。配置独立持久挂载、磁盘容量/剩余空间预算、重试上限和故障恢复操作。
  2. 监控接收拒绝、SDK/Collector 丢弃、队列占用与导出失败、磁盘增长、信号新鲜度,并测量积压后的恢复速率。写入网关按预算限流;客户端保持有界退避,不能无限重试挤占业务资源。
  3. 用代表性 payload、spans/s、活跃 trace 数、series 数和进程轮换率验收;覆盖下游不可用、Collector 重启、磁盘不足和超载。仅队列大小不能推导吞吐承诺。
  4. 有跨节点持久性、长时间回放或多消费者的实测需求时再引入 Kafka 等消息系统;Collector 扩容尾采样时同时保证 Trace ID 路由一致性,存储也需要对应的 HA 方案。

持久 exporter 队列仍不覆盖入队前的 batch / tail sampling 内存状态,也不能保护 SDK 进程崩溃前尚未导出的数据。服务返回成功的时点及持久化边界必须随实现记录,不能称为端到端零丢失。

应用详情中的面板#

当前已有 Grafana 标准 JSON 的扩展目录、离线配置工具和应用详情的 Grafana 嵌入。自定义面板可以沿用这些能力。以下注册和 UI 方案尚未实施:

SDK 面板编译器是可选离线工具。已有标准 Grafana JSON 的应用可以直接交付,不需要转成另一份格式。

版本与发布#

SDK 版本与 luma-infra 独立。observe-sdk-v* 发布流程完成检查后将同次构建的 wheel、源码包及校验和发布到 GitHub Releases,可作为稳定依赖来源。PyPI OIDC 发布需先建立独立 Trusted Publisher 并启用仓库发布变量;工作流源码不代表包已经在 PyPI 可用。消费方锁定发布 wheel 的校验和或完整 Git SHA,不使用会过期的 CI 工件 URL 作为长期依赖。参见发布指南。

Collector 固定版本为 contrib 0.122.1,实际 PRW 组件为 0.122.0。该版本 DELTA 限制、专用 WAL、队列单位和 Alpha 多 worker 开关见 PRW README 与发行清单。升级组件时重新验证这些合同。