ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Plano 可观测性实战:为你的环境开启 OTEL 追踪并配置合理的采样策略

2026/9/17 15:03:53 拓冰建站 浏览量
Plano 可观测性实战:为你的环境开启 OTEL 追踪并配置合理的采样策略 Plano 可观测性实战为你的环境开启 OTEL 追踪并配置合理的采样策略【免费下载链接】planoPlano is an AI-native proxy server and data plane for agentic apps. Smart LLM routing, observability, agent orchestration, and guardrails so you stay focused on your agents core logic.项目地址: https://gitcode.com/GitHub_Trending/ar/planoPlano 是一个 AI 原生代理服务器AI-native proxy server / data plane面向 agentic 应用提供 LLM 智能路由、可观测性、Agent 编排与护栏能力。本文基于仓库中的 observe-tracing.md 规则文档完整讲解如何在 Plano 中开启 OpenTelemetryOTEL追踪、为不同环境选择合适的采样率、配置自定义 Span 属性如x-katanemo-*请求头映射并给出从源码角度理解追踪链路的依据。读完本文你将能独立完成 Plano 从零追踪盲跑到生产级采样可观测的完整配置。说明文档末尾引用了外部仓库链接根据规范此处不再输出外部链接Plano 相关的可观测性设计与源码实现均以本仓库为准。为什么追踪是 Plano 的首要可观测性手段Plano 对每一次请求都会发出 OTEL traces记录路由决策routing decisions、LLM provider 选择LLM provider selection、filter chain 执行filter chain execution与响应延迟response latency。追踪是理解某个请求为什么被路由到某个模型以及调试意外行为的最佳工具。没有追踪时调试路由决策、延迟问题和模型选择只能是瞎猜开启追踪后你可以看到完整的调用链从 inbound 入口、agent filter、routing 决策到最终的 LLM 调用。在源码层面Plano 的追踪基础设施集中在 crates/brightstaff/src/tracing/ 模块init.rs 负责初始化 TracerProvider、采样与导出器constants.rs 定义了所有 Span 属性键与操作命名Operation Name约定custom_attributes.rs 实现请求头到 Span 属性的映射service_name_exporter.rs 实现按服务名分组的 OTLP 导出。错误示范没有配置追踪等于在生产环境盲飞下面这个配置虽然能启动 Plano但由于没有tracing配置块路由、延迟、错误全部不可见version: v0.3.0 listeners: - type: model name: model_listener port: 12000 model_providers: - model: openai/gpt-4o access_key: $OPENAI_API_KEY default: true # No tracing block — no visibility into routing, latency, or errors从源码看追踪是否启用由两个条件同时决定见 init.rslet has_destination otel_endpoint.is_some() || !posthog_exporters.is_empty(); let tracing_enabled random_sampling 0 has_destination;也就是说只有random_sampling 0且存在至少一个导出目标OTLP collector 或 exporter时追踪才会真正生效。仅仅写上tracing:而没有采样率或导出地址追踪依然不会启动。CLI 启动时也会在控制台打印初始化信息initializing tracing: tracing_enabled..., otel_endpoint..., random_sampling..., posthog_exporters...正确示范开启追踪并选择与当前环境匹配的采样率开发/调试环境建议 100% 采样让内部路由 Span 完整呈现version: v0.3.0 listeners: - type: model name: model_listener port: 12000 model_providers: - model: openai/gpt-4o access_key: $OPENAI_API_KEY default: true tracing: random_sampling: 100 # 100% for development/debugging trace_arch_internal: true # Include Planos internal routing spansrandom_sampling采样率百分比整数0–100。0 表示关闭追踪100 表示全量采样。trace_arch_internal是否包含 Plano 内部路由 Span。置为true时会额外产生展示哪个路由偏好命中的 Span——这对调试偏好路由preference routing配置至关重要。生产环境配置通过采样控制数据量生产环境流量大需要按比例采样以控制 trace 体积同时借助 Span 属性为追踪数据打上环境与版本标签tracing: random_sampling: 10 # Sample 10% of requests in production trace_arch_internal: false # Skip internal spans to reduce noise span_attributes: header_prefixes: - x-katanemo- # Match all x-katanemo-* headers static: environment: production service.name: my-plano-service version: 1.0.0span_attributes支持两类配置对应源码中的 SpanAttributes 结构header_prefixes请求头前缀列表匹配的请求头会被转为 Span 属性static源码中通过#[serde(rename static)]映射为static_attributes静态键值对直接写入每个 Span。请求头到 Span 属性的映射规则配置了x-katanemo-前缀后Plano 会剥离前缀并将连字符-转换为点.。例如x-katanemo-user-id→user.idx-katanemo-session-id→session.idx-katanemo-request-id→request.id这条规则的实现位于 custom_attributes.rs遍历请求头找到匹配前缀的头部剥离前缀、去掉前导-、把剩余的-替换为.作为属性键写入。源码佐证头部属性与静态属性custom_attributes.rs 的逻辑顺序是先写入static_attributes再叠加header_prefixes命中的头部属性。测试用例header_attributes_override_static_attributes验证了头部属性会覆盖同名静态属性见 custom_attributes.rsstatic: tenant.id ten_static header: x-katanemo-tenant-id: ten_456 → 最终 Span 属性 tenant.id ten_456同时支持多个前缀同时匹配例如x-katanemo-与x-tenant-并存不匹配任何前缀的请求头如x-other-id会被忽略。启动内置 OTEL CollectorCLI 提供了--with-tracing开关用于启动 Plano 内置的 OTEL Collector# Start Plano with built-in OTEL collector planoai up config.yaml --with-tracing该开关的实现位于 native_runner.py当配置文件中没有设置random_sampling时CLI 会自动注入random_sampling: 100并渲染出带追踪配置的临时配置文件config_with_tracing.yaml随后配合--tracing-port启动本地 OTLP trace collector详见 main.py。也就是说开发环境下只需一个--with-tracing参数即可全量采样开跑无需手写tracing:配置块。采样率的推荐取值环境建议采样率说明开发 / 预发dev/staging100%全量采样便于完整还原问题现场高流量生产5–20%按比例采样控制存储与成本典型取 10%低流量生产100%流量小全量采样开销可接受信息最完整trace_arch_internal: true会额外增加展示哪个路由偏好匹配命中的 Span是调试 preference 配置的关键开关生产环境建议关闭以减少噪音。深入源码Span 结构与操作命名服务名覆盖per-span service.namePlano 的追踪有一个独特设计同一个 TracerProvider 下不同阶段的 Span 归属于不同的逻辑服务名。通过 service_name_exporter.rs 中的ServiceNameOverrideExporterSpan 会按service.name.override属性分组再分别用各自的 Resource 导出。已定义的服务名包括见 constants.rs常量服务名语义INBOUNDplano(inbound)入站请求处理ROUTINGplano(routing)LLM 路由选择编排ORCHESTRATORplano(orchestrator)Agent 选择编排HANDOFFplano(handoff)上游服务交接AGENT_FILTERplano(filter)Agent filter 执行AGENTplano(agent)Agent 执行LLMplano(llm)LLM 调用例如在路由服务中通过set_service_name(operation_component::ROUTING)标记见 routing_service.rs在 LLM 调用链路中标记为plano(llm)见 llm/mod.rs。这样在 Jaeger 等后端中追踪数据会按逻辑组件自然分组方便快速定位路由慢还是LLM 慢。操作命名规范Operation Nameconstants.rs 中的OperationNameBuilder按{method} {path} {target}可选的({operation})用于 MCP 操作生成标准化的操作名例如POST /v1/chat/completions gpt-4服务名plano(llm)POST /agents/v1/chat/completions hallucination-detector服务名plano(filter)POST /v1/chat/completions服务名plano(routing)对应测试用例见 constants.rs。常用 Span 属性速查追踪 Span 上携带的属性遵循 OTEL Semantic Conventions并扩展了 LLM/路由专属属性完整定义见 constants.rsHTTP 维度http.method、http.status_code、http.target、http.upstream_target、http.request_content_length、http.response_content_lengthLLM 维度llm.model、llm.provider、llm.is_streaming、llm.duration_ms、llm.time_to_first_token、llm.usage.prompt_tokens、llm.usage.completion_tokens、llm.usage.cached_input_tokens、llm.usage.input_cost_usd、llm.usage.output_cost_usd、llm.usage.total_cost_usd等路由维度routing.strategy、routing.upstream_endpoint、routing.determination_ms、routing.is_fallback、routing.selection_reasonPlano 专属plano.session_id来自x-model-affinity请求头、plano.route.name、plano.distinct_id、plano.cache.warm、plano.cache.idle_ms、plano.routing.skipped、plano.session.overhead_pct、plano.switch.decision等错误维度error、error.type、error.message、error.stack_traceAgent 信号维度signals.quality取值Excellent/Good/Neutral/Poor/Severe、signals.turn_count、signals.efficiency_score。以 demo_tracing.png 为例开启追踪后你会在 Jaeger 中看到类似plano(inbound):ingress根 Span 下挂载plano(agent)、plano(routing)、plano(llm)等子 Span 的完整瀑布图每个 Span 的耗时清晰可见——这正是本文配置的最终成果。扩展将 LLM 追踪导出到 PostHog除了 OTLP CollectorPlano 还支持把 LLM Span 转译为 PostHog 的$ai_generation事件并导出对应 Tracing 结构体 中的exporters字段以及 PosthogExporter 结构tracing: random_sampling: 10 exporters: - type: posthog url: https://us.i.posthog.com api_key: $POSTHOG_API_KEY distinct_id_header: x-katanemo-user-id # 可选用于 PostHog distinct_id capture_messages: false # 默认 false避免将提示词内容发往外部urlPostHog 主机地址/batch/采集路径会自动拼接api_key支持$ENV_VAR形式的环境变量展开distinct_id_header可选取该请求头的值作为 PostHogdistinct_id未配置或请求头缺失时按匿名事件采集capture_messages是否把截断后的用户消息预览写入$ai_input默认false避免敏感内容出站。多个导出目标OTLP PostHog会并行注册独立的 span processor所有 Span 会同时扇出到各个目标见 init.rs。配置自检清单检查项标准采样率与环境匹配开发 100%、高流量生产 5–20%、低流量生产 100%导出目标已配置至少一个 OTLP endpoint 或 exporter否则追踪不会启用trace_arch_internal按需开关调试路由偏好时开true生产降噪时关自定义属性需要时配置span_attributes.header_prefixes与span_attributes.static环境变量OTEL_SERVICE_NAME未设置时默认使用plano见 init.rs配置完成后重启 Plano 并在日志中确认initializing tracing: tracing_enabledtrue ...输出即可在 Jaeger / Grafana Tempo / PostHog 等后端中查看完整链路。本文涉及的源码均可继续深入tracing 模块、configuration.rs 中的 Tracing 定义、CLI 启动逻辑。【免费下载链接】planoPlano is an AI-native proxy server and data plane for agentic apps. Smart LLM routing, observability, agent orchestration, and guardrails so you stay focused on your agents core logic.项目地址: https://gitcode.com/GitHub_Trending/ar/plano创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考