关于 otel-migration
otel-migration 指导为尚无 OpenTelemetry 埋点或需兼容现有日志、指标模式的应用补充观测能力。它将迁移划分为六个可验证阶段,涵盖 SDK、上下文传播、桥接与验证。
主要功能
- 01六阶段迁移顺序
- 02SDK 初始化与关闭指导
- 03HTTP 中间件与上下文传播
- 04自定义 Span 建议
- 05日志和指标桥接指导
- 06逐阶段验证
适用场景
- 01为现有服务添加 OpenTelemetry
- 02在应用代码中传播跟踪上下文
- 03迁移期间保留 Prometheus 指标
- 04将现有日志与跟踪关联
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ honeycombio/ agent-skill --skill otel-migration安装后在 Claude Code 中输入/otel-migration确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/bridge-libraries.mdcontext-propagation-patterns.mdframework-middleware.mdmigration-pitfalls.mdverification-checklist.md详细介绍
为现有应用迁移 OpenTelemetry
为现有且尚未添加插桩的应用引入 OpenTelemetry 的指南。本指南涵盖分阶段迁移方法、上下文传播重构、日志和指标桥接,以及验证。这与全新项目的 OTel 设置(参见 otel-instrumentation skill)和 Beeline 专属迁移(参见 beeline-migration skill)不同。
何时使用此技能
当用户有一个现有应用,且满足以下条件时,使用此技能:
- 尚未添加 OpenTelemetry 插桩,需要引入插桩
- 已有日志记录、指标或上下文模式需要与 OTel 共存
- 需要重构函数签名,以便在整个调用栈中传递跟踪上下文
- 使用的框架存在 OTel 中间件注意事项(例如 Fiber、Gin、Express)
对于全新项目的 OTel 设置,请改用 otel-instrumentation skill。
对于从 Beeline 迁移到 OTel,请改用 beeline-migration skill。
如需了解为何要添加插桩,请参阅 observability-fundamentals skill。
迁移阶段
迁移按顺序分为六个阶段。每个阶段都可以独立部署和验证。 上下文传播(阶段 3)通常占总工作量的约 60%。
阶段 1:SDK 初始化和关闭
使用 OTLP 导出器设置 TracerProvider、MeterProvider 和 LoggerProvider。在应用入口点尽早接入初始化,并在信号处理程序中接入关闭逻辑。
关键指导:
- SDK 初始化必须在任何可能创建 span 的应用代码运行之前完成——应在入口点最先执行的操作之一,早于配置加载或存储初始化
- 关闭顺序很重要:先刷新跟踪数据,再刷新指标,最后刷新日志。设置超时时间(10-30s)
- 如果初始化失败,应用仍应正常运行——记录错误并在不启用遥测的情况下继续
- 有关特定语言的 SDK 设置,请参阅
${CLAUDE_PLUGIN_ROOT}/skills/otel-instrumentation/references/sdk-setup-by-language.md
阶段 2:HTTP 中间件(自动插桩)
为 HTTP 框架添加 OTel 中间件。这样无需更改处理程序代码,即可为每个入站请求自动创建 span。这是投入产出比最高的一步。
重要: 不同框架公开 OTel 增强上下文的方式各不相同。这是导致跟踪静默中断的首要原因。请参阅
${CLAUDE_PLUGIN_ROOT}/skills/otel-migration/references/framework-middleware.md 了解特定框架的详细信息。
| 框架 | 如何获取 OTel 上下文 | 常见错误 |
|---|---|---|
| Go net/http | r.Context() | 不适用(标准方式) |
| Go Fiber v2 | c.UserContext() | 使用 c.Context()(返回不包含 OTel span 的 fasthttp 上下文) |
| Go Gin | c.Request.Context() | 直接使用 c |
| Go Echo | c.Request().Context() | 不适用 |
| Python Flask | 自动(线程本地) | 使用插桩库时不适用 |
| Python Django | 自动(线程本地) | 使用插桩库时不适用 |
| Node.js Express | 自动(AsyncLocalStorage) | 使用插桩库时不适用 |
| Java Spring | 自动(线程本地) | 线程池上下文丢失 |
| .NET ASP.NET Core | 自动(AsyncLocal) | 不适用 |
| Ruby Rails | 自动(线程本地) | 使用插桩库时不适用 |
阶段 3:上下文传播重构
在调用链中,将跟踪上下文从 HTTP 处理程序(或入口点)一路传递到 I/O 操作。这是最难的阶段——通常约占迁移工作量的 60%。
此阶段的难度因语言而有很大差异:
- Go:最难。需要为调用链中的每个函数添加
context.Context参数。 - Java:中等。线程局部上下文会在线程内自动传播,但跨线程池、CompletableFuture 和响应式流时会中断。
- Python:较容易。
contextvars会在线程内自动传播。难点在于线程池和多进程处理。 - Node.js:较容易。
AsyncLocalStorage会通过 async/await 自动传播。难点在于旧式基于回调的代码。 - .NET:最容易。
Activity会通过AsyncLocal<T>在 async/await 中自动传播。 - Ruby:较容易。线程局部上下文会自动传播。手动创建线程时会遇到问题。
语言特定的模式和代码示例,请参阅
${CLAUDE_PLUGIN_ROOT}/skills/otel-migration/references/context-propagation-patterns.md。
阶段 4:自定义 Span
为自动插桩无法覆盖的业务逻辑操作添加 Span。Span 的创建方法请参阅
otel-instrumentation 技能。迁移相关指南:
- 从 I/O 边界开始——数据库调用、外部 HTTP 调用、缓存操作
- 然后添加业务逻辑——能够说明时间为何花费在此处的操作
- 尽可能多地添加属性——每一条上下文信息都有助于在调查期间使用 BubbleUp
- 在 Span 上记录结果——将结果状态、错误数量、持续时间作为属性
属性命名和 Span 创建模式,请参阅
${CLAUDE_PLUGIN_ROOT}/skills/otel-instrumentation/references/custom-instrumentation.md。
阶段 5:日志迁移
将现有日志库替换为 OTel,或将其桥接到 OTel,使日志与跟踪相关联。
关键指南:
- 几乎可以肯定,你需要同时将日志输出到 stderr(用于本地调试)和 OTel(用于跟踪关联)。 这需要采用多处理器/扇出模式。
- OTel 日志桥接适用于结构化日志(键值对)。如果现有日志使用 printf 风格的格式字符串,请先转换为结构化格式。
- 从 printf 风格转换为结构化日志虽然繁琐,但有章可循——很适合使用自动化重构。
语言特定的日志桥接和多处理器模式,请参阅
${CLAUDE_PLUGIN_ROOT}/skills/otel-migration/references/bridge-libraries.md。
阶段 6:指标桥接
如果你已经有 Prometheus 指标(或其他指标库),请将其桥接到 OTel,而不是重写。
关键指南:
- Prometheus 桥接会读取现有注册表并生成 OTel 指标——现有的
prometheus.NewCounterVec(...)调用无需更改 - 如果已有抓取器,请保留 Prometheus
/metrics端点。桥接会在抓取之外额外添加 OTLP 导出。 - 如果最终想移除 Prometheus 依赖,请另行规划后续迁移。桥接能为你争取时间。
语言特定的指标桥接,请参阅
${CLAUDE_PLUGIN_ROOT}/skills/otel-migration/references/bridge-libraries.md。
验证
每个阶段结束后,请验证插桩是否正确且完整。完整清单和查询模式,请参阅
${CLAUDE_PLUGIN_ROOT}/skills/otel-migration/references/verification-checklist.md。
如需在本地验证而不使用 Honeycomb 账户,可使用捆绑的收集器脚本,将 Span 捕获为调试输出和 NDJSON。用法请参阅
${CLAUDE_PLUGIN_ROOT}/skills/otel-instrumentation/references/local-collector-debug-test.md,完整脚本请参阅
${CLAUDE_PLUGIN_ROOT}/scripts/start-collector.sh。
Honeycomb 专用的验证查询也请参阅 query-patterns 技能。
常见陷阱
如需查看常见错误及其避免方法,请参阅
${CLAUDE_PLUGIN_ROOT}/skills/otel-migration/references/migration-pitfalls.md。
实际迁移参考
以下是 Gatus 的一次真实迁移,供参考(约 30k 行 Go 代码,Fiber v2,SQLite/Postgres,Prometheus):
- **更改的文件:**约 45 个,代码行数:+840/-645
- **工作量分布:**上下文传播约 60%,自定义跨度约 15%,日志迁移约 15%,其他所有内容约 10%
- **遇到的问题:**Fiber 的
c.Context()与c.UserContext()、printf 风格的 slog 格式字符串、遗漏span.End()调用、复用 goroutine 上下文