资讯动态

Mastra 与 Hono 多服务分布式链路追踪实战:基于 OtelBridge 与 Arize Phoenix 打通三服务调用链

发布时间:2026/9/13 14:19:13 来源:尧图企业网站定制
Mastra 与 Hono 多服务分布式链路追踪实战基于 OtelBridge 与 Arize Phoenix 打通三服务调用链【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra本指南以 Mastra 仓库中的hono-multi示例为蓝本讲解如何用 Mastra 的OtelBridge将 Agent 产生的内部 Span 无缝接入 OpenTelemetryOTEL生态让跨三个 Hono 服务的 HTTP 调用、Mastra Agent 运行与 LLM 调用共享同一条 trace ID并在 Arize Phoenix 中可视化。读完本文你将掌握 OtelBridge 的工作原理、共享 OTEL 插桩的搭建方式以及一套可复制、可验证的多服务分布式追踪落地流程。示例概览一条贯穿三个服务的调用链示例位于 observability/_examples/otel-bridge/hono-multi包含三个独立服务与一个共享插桩包整体调用拓扑如下service-one (port 3000) ↓ HTTP request service-two (port 3001) ↓ HTTP request service-mastra (port 4000) → Mastra agent with OtelBridge注意README 中标注 service-mastra 端口为 4000但实际源码service-mastra/src/index.ts中监听端口为3002集成测试src/integration.test.ts也按 3000/3001/3002 三端口验证。部署时以实际源码为准。所有服务统一使用 OpenTelemetry 插桩trace 数据最终汇入 Arize Phoenix 可视化。其核心价值在于演示trace context 的正确传播如果没有 OtelBridgeMastra 会为 Agent 运行创建新的 trace ID导致与其他服务的 trace 断链接入后Mastra 的 Span 与上游 HTTP Span 共享同一个 trace ID形成完整的链路。OtelBridge 原理Mastra 可观测性与 OTEL 的桥梁OtelBridge 是mastra/otel-bridge包导出的核心类其实现位于 observability/otel-bridge/src/bridge.ts。从源码结构看它通过三种机制完成双向打通读取 trace context从传入 HTTP 请求的traceparent头中解析 W3C 上下文让 Mastra 的根 Span 挂接到外部链路之下创建真实 OTEL Span当 Mastra 创建内部 SpancreateSpan时同步调用全局 TracerProvider 的startSpan生成真正的 OTEL Span而非 Mastra 内部私有的 Span维护层级关系通过otelSpanMap缓存「Mastra spanId ↔ OTEL span/context」的映射在 Span 结束时用 SpanConverter来自mastra/otel-exporter将 Mastra 属性转换为符合 OTEL 语义约定的属性并end()该 Span。值得注意的两个细节若当前进程没有注册 OTEL SDK全局 Tracer 返回的 non-recording span 上下文无效全零 IDcreateSpan会提前返回undefined让 Mastra 回退到自有的 ID 生成逻辑避免 ID 碰撞见 bridge.ts#L229-L238executeInContext/executeInContextSync会把函数放进已存储的 OTEL context 中执行从而让 Mastra Span 内部的任何 OTEL 插桩代码HTTP 客户端、数据库驱动等都能以正确的父子关系挂到当前 Span 下。在 service-mastra 中接入方式非常简洁service-mastra/src/index.tsimport { Mastra } from mastra/core; import { Observability, SensitiveDataFilter } from mastra/observability; import { OtelBridge } from mastra/otel-bridge; export const mastra: Mastra new Mastra({ observability: new Observability({ configs: { default: { serviceName: tracing-exp, spanOutputProcessors: [new SensitiveDataFilter()], bridge: new OtelBridge(), }, }, }), agents: { test-agent: testAgent }, });其中serviceName用于标识服务SensitiveDataFilter会在 Span 输出前过滤敏感数据bridge: new OtelBridge()即打通 OTEL 的关键配置。环境准备与三步搭建运行本示例需要以下环境Docker用于启动 Arize Phoenix本地开源、免费的可观测性后端Node.js 22.13.0 及以上pnpm 10Monorepo 包管理OpenAI API Keyservice-mastra 通过openai/gpt-4o-mini调用大模型第一步启动 Arize Phoenix在示例根目录执行pnpm docker:up该命令读取 docker-compose.yml拉起arizephoenix/phoenix:latest镜像UI 地址http://localhost:6006OTLP 接收端点http://localhost:6006/v1/traces同时暴露 4317 端口可选的 gRPC OTLP 接收器第二步配置 OpenAI API Key在示例根目录创建.env文件echo OPENAI_API_KEYyour-key-here .env第三步安装依赖并构建pnpm install pnpm buildpnpm build会依次构建共享插桩包mastra/hono-multi-instrumentation和service-mastra见根 package.json。必须先构建再启动因为 service-mastra 以 workspace 依赖引用共享插桩包。启动三个服务需要开启三个终端窗口分别启动服务终端 1 - service-one端口 3000cd observability/_examples/otel-bridge/hono-multi/service-one pnpm start终端 2 - service-two端口 3001cd observability/_examples/otel-bridge/hono-multi/service-two pnpm start终端 3 - service-mastra端口 3002cd observability/_examples/otel-bridge/hono-multi/service-mastra pnpm start每个服务的start脚本都会先通过--import./src/instrumentation.ts预加载遥测初始化以 service-mastra 为例见 service-mastra/package.json确保telemetry 在任何 HTTP 请求处理之前完成初始化——这是 trace context 正确传播的前提之一。验证链路发一次请求看全链路向入口服务发请求curl http://localhost:3000/service-one期望返回{ message: service-one → service-two → service-mastra (agent: Hello there friend!) }调用链实际流向对应各服务源码service-one 的/service-one路由通过 service-two-client.ts 用fetch请求http://localhost:3001/service-twoservice-two 再通过 service-mastra-client.ts 请求http://localhost:3002/service-mastra最终 service-mastra 路由调用mastra.getAgent(test-agent)执行生成见 service-mastra/src/index.ts#L42-L47并把traceId一并返回。在 Phoenix 中查看 Trace打开 http://localhost:6006应能看到一条包含三个服务全部 Span 的 trace包含service-one、service-two 的 HTTP Spanservice-mastra 的 Agent 运行 SpanLLM generation Span所有 Span 共享同一个 trace ID架构细节与源码剖析service-one入口服务使用 Hono hono/otel的httpInstrumentationMiddleware做自动插桩service-one/src/index.ts通过fetch调用下游UndiciInstrumentation自动捕获该调用产生的 client span响应中包含从下游逐层透传的traceId。service-two中间服务接收 service-one 请求并转发给 service-mastra是验证HTTP trace context 传播的关键一跳同样使用httpInstrumentationMiddleware插桩中间不加任何额外处理依靠 W3Ctraceparent头完成上下文延续service-two/src/index.ts。service-mastraMastra OtelBridge通过MastraServermastra/hono的 HonoServerAdapter注册 Agent 路由并附加openapi.json、Swagger UIservice-mastra/src/index.ts#L33-L50Agent 定义见 service-mastra/src/agent.ts使用openai/gpt-4o-mini关键点httpInstrumentationMiddleware()在 Mastra 路由注册之前通过app.use(*, ...)挂载确保每个入站请求先进入 OTEL 上下文再进入 Mastra 逻辑。共享插桩包统一的 OTEL 配置所有服务共用mastra/hono-multi-instrumentation源码在 instrumentation/src/index.ts它负责用NodeSDK配置 resource服务名默认tracing-exp可用环境变量ARIZE_PROJECT_NAME覆盖注册HttpInstrumentation与UndiciInstrumentation自动插桩 HTTP 服务端与fetch客户端使用W3CTraceContextPropagator作为传播器解析/注入traceparent头通过BatchSpanProcessorArizeOpenInferenceOTLPTraceExporter批量导出 trace 到 Phoenix端点默认http://localhost:6006/v1/traces可用OTEL_EXPORTER_OTLP_ENDPOINT覆盖。导出器源码在 instrumentation/src/arize-exporter.ts它基于 OTLP proto exporter 扩展额外做了两项工作将 Mastra 的gen_ai.prompt/gen_ai.completion属性转换为 OpenInference 的gen_ai.input.messages/gen_ai.output.messages结构convertMastraMessagesToGenAIMessagesbest-effort 转换失败时原样返回将属性转为gen_ai语义约定供 Phoenix 以 AI 应用视图渲染支持 Arize AX云端与 Phoenix本地两种模式传入spaceId时走 Arize AX 头与https://otlp.arize.com/v1/traces端点只传apiKey时走标准Authorization: Bearer头。用集成测试自动验证传播正确性示例还提供了完整的集成测试src/integration.test.ts可自动化验证「三服务 Phoenix」整条链路。其运行前提与 README 中的说明一致Phoenix 已在运行pnpm docker:up已配置 OpenAI API Key两种方式任选推荐在示例根目录创建.env文件或运行测试前设置环境变量。已完成构建pnpm build# 使用 .env 文件推荐 pnpm test # 或使用内联环境变量 OPENAI_API_KEYyour-key pnpm test测试的行为从源码可以确认模块加载时先探测 Phoenix 的/graphql端点可用性以及OPENAI_API_KEY是否存在任一不满足则整组测试标记为 skip 并打印原因integration.test.ts#L38-L47beforeAll依次以子进程启动三个服务等待日志中出现 Server listening 判定就绪通过http://localhost:3000/service-one发起请求用正则traceId:([a-f0-9]{32})从响应中提取 32 位 hex trace ID通过 Phoenix 的 GraphQLgetTraceByOtelId查询该 trace轮询等待最长 15 秒断言要点存在mastra.span.type agent_run的 Span存在model_generation的 LLM Span所有 Span 共享唯一 trace IDtraceIds.length 1agent_runSpan 有父 Span 且父 Span 存在于同一 trace 中LLM Span 的parentId等于 Agent Span 的spanId父子关系正确afterAll按逆序优雅停止三个服务SIGTERM5 秒超时后强制 SIGKILL。常见问题排查出现断链trace ID 不一致这通常说明 trace context 传播失败按顺序检查三个服务是否都使用了共享插桩包——检查各自instrumentation.ts是否调用了startTelemetry()service-mastra 是否配置了 OtelBridge——缺失bridge: new OtelBridge()时 Mastra 会生成新的 trace IDtelemetry 是否在创建 Hono app 之前初始化——注意start脚本中的--import./src/instrumentation.ts预加载顺序这是插桩能够捕获 HTTP 请求的前提。Agent 调用报错确认.env示例根目录中存在OPENAI_API_KEY确认 OpenAI API 网络可达确认账号余额/额度充足。清理与关闭# 停止 Phoenix pnpm docker:down # 停止三个服务在每个终端按 CtrlC三个服务都实现了SIGTERM/SIGINT优雅退出先关闭 HTTP server再调用stopTelemetry()触发 SDKshutdown()冲刷剩余 Span确保进程退出前数据完整导出参考 service-one/src/index.ts#L37-L57 等实现。与上游示例的对比与启示该示例基于社区的 Hono tracing 示例改造而来核心改进有四方面改用本地开源的 Arize Phoenix替代云端 Arize引入 OtelBridge 修复 trace 传播断链问题通过 workspace 依赖融入 Mastra Monorepo 直接复用最新包并最终用集成测试证明了「trace 能正确贯穿所有服务」这一修复成果。对于在生产环境接入 Mastra 可观测性的开发者本示例给出了一条清晰的落地路径共享插桩包统一 OTEL 配置 → 中间服务靠 W3C 传播器自然透传 → 末端服务用 OtelBridge 把 Mastra 内部 Span 变为真实 OTEL Span → 集成测试保障链路不回归。这套模式同样适用于任何基于 OTEL 的后端如 Jaeger、Tempo、OTLP Collector 等只需替换导出器端点即可。【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价