mcpField
D
dt-setup-openinference-migration

dt-setup-openinference-migration

github.com/dynatrace云与 DevOps17112 次安装2 天前更新
代码仓库

关于 dt-setup-openinference-migration

这套迁移流程面向从 Traceloop/OpenLLMetry 转向启用 `gen_ai.*` 语义约定的 OpenInference 的 Python 应用,重点是替换埋点并识别需另行处理的数据缺口。

主要功能

  1. 01识别 Traceloop 数据接入方式
  2. 02将埋点器替换为 OpenInference
  3. 03启用 `gen_ai.*` 语义约定
  4. 04检查旧属性与调用参数
  5. 05比较指标与护栏信号缺口
  6. 06依据基线验证结果

适用场景

  1. 01迁移已使用 Traceloop 埋点的 Python 应用
  2. 02保留现有的跨度导出路径
  3. 03评估迁移后的旧属性

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dynatrace/dynatrace-for-ai --skill dt-setup-openinference-migration

安装后在 Claude Code 中输入/dt-setup-openinference-migration确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
baseline-and-rollback.md
derived-metrics.md
detect-traceloop.md
dual-write-cardinality.md
incomplete-attribute-mappings.md
ingestion-shape.md
openpipeline-safety.md

详细介绍

从 Traceloop/OpenLLMetry 迁移到 OpenInference

本迁移专用决策流程适用于已通过 Traceloop/OpenLLMetry 发送 spans,且必须启用其 gen_ai.* 语义约定选项迁移到 OpenInference 的应用。它与 dt-setup-genai 共用 Detect/Validate 流程——请加载该技能,了解四步式插桩/增强模型、dtctl 验证约定以及多 SDK 处理方式。本技能仅涵盖不同之处:识别 Traceloop 设置、替换插桩工具,以及 gen_ai.* 开始流转后仍存在的缺口——OpenInference 仍会发送的旧属性、未解析的调用参数,以及插桩从未捕获的护栏信号。

以下情况不要使用本技能

  • 没有现有的 Traceloop/OpenLLMetry 插桩需要迁移 → dt-setup-genai (从零开始搭建或增强现有插桩)。
  • 已在使用 OpenInference,但从未启用 semconv 选项,收到的 spans 仍为 llm.*/openinference.* → 加载 dt-setup-genai 技能,并使用其正规化器门控 (references/enrich-normalization.md);这不属于迁移。
  • TypeScript/Node 应用,或任何非 Python 语言 → 不在本技能范围内。本技能流程依赖的 semconv 选项目前仅存在于 Python OpenInference SDK 中——迁移掉 Traceloop 的 TypeScript 应用仍需在之后使用 dt-setup-genai 的正规化器门控,而不是本技能。

本技能必须停止并征求确认的情况

  • 任何对客户应用代码的修改——先展示差异并获得同意。
  • 是否移除旧的 llm.*/openinference.* 属性(步骤 4a)——这是权衡取舍,不能默认静默执行。
  • 向租户部署 OTel Collector transform 或 OpenPipeline pipeline——这与 dt-setup-genai 设定的界限相同;或部署 gen_ai_normalizer(collector processor 或 OpenPipeline pipeline),仅在 Validate 显示存在它能弥补的缺口后进行。OpenPipeline 需要格外谨慎:其路由配置是租户上所有 pipeline 共用的单个对象——请先阅读 references/openpipeline-safety.md。
  • 添加应用代码以捕获插桩不会发出的护栏信号(步骤 4c)。
  • 凭据——绝不打印、记录或存储令牌值。
  • 消息内容捕获——无论 semconv 标志如何,OpenInference 默认都会捕获提示词/响应内容(与 Traceloop 通过 TRACELOOP_TRACE_CONTENT 捕获内容的方式相同);插桩交接时,请确认用户仍希望捕获这些内容。

迁移流程

baseline ─▶ detect Traceloop ─▶ ingestion shape ─▶ swap instrumentor ─▶ close semconv gaps ─▶ validate
0. 记录基线和回滚状态

在编辑任何内容之前,记录服务当前发送的数据以及如何撤销更改——替换会重命名属性,并丢弃仪表板或警报可能读取的指标。基线查询、使用方清单和回滚检查清单见:references/baseline-and-rollback.md。

1. 检测现有的 Traceloop/OpenLLMetry 设置

确认这确实是一次迁移——grep 模式和包名称陷阱(有些 Traceloop 包名为 opentelemetry-instrumentation-<sdk>,与真正的 OTel 包相同)见 references/detect-traceloop.md。记录其封装的 SDK——每个 SDK 在步骤 3 中都需要各自对应的 openinference-instrumentation-<sdk> 替代项。

2. 确认接入形态

这决定了第 4 步中哪些问题确实可以修复,因此请在修改代码前先确定。针对基数问题,有以下三种情况,不能互换:

  • 应用自有的跟踪导出器——应用创建自己的 TracerProvider,附加 BatchSpanProcessor 和 OTLP 导出器,并在检测器运行前调用 set_tracer_provider(...)。导出器由应用控制,因此可以在其前面部署收集器。
  • 仅启用检测,由 OneAgent 获取——代码只调用检测器的 .instrument(...),不设置 TracerProvider/导出器;在受 OneAgent 监控的主机上,OneAgent 通过注入进程捕获 span。应用无法控制线上传输链路,因此后续无法使用收集器转换——只有 OpenPipeline 能在接入后处理这些 span。
  • 由 Traceloop 管理的导出器——应用调用 Traceloop.init(),且以上符号均未出现,但 Traceloop 自身会创建 TracerProvider 和默认的 OTLP 导出器(目标地址通过 TRACELOOP_BASE_URL/TRACELOOP_HEADERS/TRACELOOP_API_KEY 配置)。如果只用 OpenInference 检测器替换它,会悄无声息地丢失导出路径——先添加目标地址相同的显式 provider 和导出器,再移除 init。init_instrumentations(...) 则不同:它只负责检测,与第二种形态相同。

完整的检测方法以及每种形态的示例: references/ingestion-shape.md。

3. 替换检测器
  • 切勿在同一进程中对同一 SDK 同时运行 Traceloop/OpenLLMetry 和 OpenInference 检测——每次调用都会被包装两次(产生重复或嵌套的 span)。在添加 OpenInference 检测的同一次改动中,移除(或排除)该 SDK 的 Traceloop 检测。
  • 将 Traceloop 软件包替换为对应的 openinference-instrumentation-<sdk> 软件包。请查看示例仓库中的 <sdk>/openinference/ 配方文件夹,了解当前的调用方式——不要自行编写(参见 dt-setup-genai 技能中的 examples-index.md——加载该文件以阅读内容)。
  • 从配方中获取检测器调用方式,而不是其收集器/OpenPipeline 配置。 这些配置包含 gen_ai_normalizer(llm.*/openinference.* → gen_ai.* 映射),适用于未启用语义约定选项的 span。启用该选项后,gen_ai.* 已直接生成——请勿预先添加 normalizer,也不要复制包含它的配置。
  • 启用语义约定选项——将 TraceConfig(enable_genai_semconv=True) 传给 .instrument(config=...),或在检测器从环境变量读取配置时设置 OPENINFERENCE_ENABLE_GENAI_SEMCONV=true。这两种方式都仅适用于 Python(参见上文“何时不应使用此技能”)。若未启用,检测器只会生成 llm.*/openinference.*,于是又会受限于 dt-setup-genai 的 normalizer 门槛。
  • 多 SDK 应用 → 对每个 SDK 重复上述步骤;加载 dt-setup-genai 并遵循其 references/multi-sdk-apps.md。
  • 删除 Traceloop 初始化前,请检查是否仍有其他组件(自定义 span 处理器、日志关联)读取 Traceloop 专属属性(traceloop.*)。
4. 弥补语义约定选项留下的缺口

语义约定选项可以传递核心 gen_ai.* 合约字段,但仍有四个已知缺口,各自需要不同的处理方式。请在第 3 步后立即运行 Validate,并根据结果执行此步骤。normalizer(gen_ai_normalizer)是按缺口启用的备用方案,而不是默认配置:只有当 L3 检查显示,仍缺少语义约定选项无法填充的特定合约字段时,才添加它。请向用户说明这些字段并事先征得同意(这是收集器/租户变更)。如果唯一的缺口是调用参数或防护栏,请使用 4b/4c。 4a. 双写基数。 semconv 选项是附加项,而非替代项。 启用后,OpenInference 会在同一个 Span 上同时发出 gen_ai.* 和 llm.*/openinference.*,而不是用前者替代后者(dt-setup-genai 的验证约定也有此要求)。在迁移后的应用上验证:发送一个请求,用 dtctl/DQL 列出 Span 的属性,确认两组属性都存在。

现在每个 Span 携带的属性数量大约翻倍(增加负载/存储开销);只有在选择旧字段作为维度时,指标基数才会增加——除非经过测量,否则不要把移除旧字段说成是解决基数问题。确认 gen_ai.* 已存在后,询问用户是否要移除旧字段集——不要自行决定。 如果用户希望移除,具体机制取决于步骤 2 中的摄取方式:

摄取方式移除机制
应用自有的导出器,且已使用 CollectorOTel Collector transform 处理器
应用自有的导出器,目前未使用 Collector这是需要权衡的选择,而非默认方案:引入 Collector 属于基础设施变更(dt-setup-genai 的暂停并询问清单也划定了同样的界限),因此应同时提供“部署 Collector”和“改用 OpenPipeline”两个选项,由用户选择
OneAgent 获取这些 Span仅使用 OpenPipeline——OneAgent 与 Dynatrace 之间没有可运行 Collector transform 的组件

提出任一方案前,先检查是否可用;代码片段和可用性检查见: references/dual-write-cardinality.md。

4b. 调用参数——可在 Collector 或 OpenPipeline 配置中修复。 OpenInference 会将模型参数(temperature、top_p 等)打包成一个 JSON 字符串,放在 llm.invocation_parameters 中;请明确检查各个 gen_ai.request.* 字段是否已填充(参考文档中有查询语句),因为曾发现 semconv 选项仍会将它们打包在一起。如果是这样,就要根据步骤 2 允许的方式修复流水线;代码片段见: references/incomplete-attribute-mappings.md。

4c. 防护栏属性——可能需要自定义埋点代码,而非流水线修复。 OpenInference 没有标准化的防护栏属性——openinference.span.kind = "GUARDRAIL" 只会标记 Span 类型;防护栏是否触发,则因提供方/库而异,可能以不同方式指示,也可能完全未捕获(按提供方划分的表格见 references/incomplete-attribute-mappings.md)。如果从未捕获该信号,Collector 或 OpenPipeline transform 都无法将其恢复——必须由应用捕获。这需要修改应用代码:先暂停并获得明确批准;如果不需要查看防护栏状态,将其记录为已知缺口即可。

4d. 派生指标——切换后会消失。 OpenInference 只生成 Span。Traceloop 发出的 gen_ai.client.token.usage 和 gen_ai.client.operation.duration 指标会消失,AI Observability 应用中基于指标的成本和延迟图表也会失去该服务。与步骤 0 的基线进行比较;如果指标消失,则根据摄取方式从 Span 派生——使用 Collector 连接器或 OpenPipeline 指标提取。先询问,并检查 Collector 发行版中是否包含这些连接器(Bindplane 是备用方案):references/derived-metrics.md。

缺口报告——必须提供,不得默默跳过。 完成前,用一张简短表格向用户展示全部四项缺口:观察到的情况、建议的修复方案或明确的“保持现状”,以及需要哪些批准。“未检查”不算结果。如果仓库中有多个服务或 Collector 配置,请逐一检查,一次性询问,并在所有位置应用同一决定——绝不要在某个服务的流水线中移除或解包字段,却不处理其他服务。

5. 验证

相同的契约,相同的循环——加载 dt-setup-genai 技能,并将全部工作委托给其验证步骤(SKILL.md,步骤 4)以及 references/validate-contract.md 中完整的 dtctl L1–L4 循环,并与步骤 0 的基线进行比较。此处发现的差距是添加 gen_ai_normalizer 的唯一触发条件。迁移专属的 L3 补充:如果 4a 移除了旧属性,请断言它们已不存在(isNull(llm.system),……);如果选择保留,则预期它们会共存。如果 4b 展开了调用参数,请确认服务商配置文件要求的字段现在都已填充。L4 涵盖 4d。4c 没有门槛——该属性存在是因为用户批准了添加,或者这是已接受并记录的差距。

参考资料

评论

支持 Markdown