OTel JS SDK 2.x 迁移笔记:真正留神的是 NodeTracerProvider 那处“静默”变化
@opentelemetry/opentelemetry-js 的 stable 包在 2025 年 2 月发布了 2.0.0,experimental 包随之进到 0.200.0。官方对“JS SDK 2.x”的界定是:仅指 opentelemetry-js 仓库内的 stable 包(1.x→2.0.0)与实验包(0.x→0.200.0);@opentelemetry/api 和 semantic-conventions 不在此列,它们的版本策略照旧。
先看升级门槛
- Node:最低
^18.19.0 || >=20.6.0。Node 14/16 被丢弃,原因是要覆盖--import与module.register()两种加载路径。 - TypeScript:最低 5.0.4。后续 minor 版本会直接丢弃超过 2 年旧的 TS。
- 编译 target:ES2017 → ES2022。浏览器侧会丢掉不支持 ES2022 的老版本;Node 侧本身已隐含 ES2022。
@opentelemetry/api仍支持 Node v8,semantic-conventions仍支持 Node v14。
Resource:类变成了函数
@opentelemetry/resources 不再导出 Resource 类,构造函数和静态方法全部改为独立函数:
// 1.x
import { Resource } from '@opentelemetry/resources';
const res = new Resource(attributes);
const def = Resource.default();
const empty = Resource.empty();
// 2.x
import { resourceFromAttributes, defaultResource, emptyResource } from '@opentelemetry/resources';
const res = resourceFromAttributes(attributes);
const def = defaultResource();
const empty = emptyResource();
sync/async detector 合并,不再区分 *Sync 后缀:
| 1.x | 2.x |
|---|---|
envDetectorSync | envDetector |
hostDetectorSync | hostDetector |
osDetectorSync | osDetector |
processDetectorSync | processDetector |
serviceInstanceIdDetectorSync | serviceInstanceIdDetector |
detectResourcesSync() | detectResources() |
browserDetector / browserDetectorSync 从本包导出中删除,改用独立包 @opentelemetry/opentelemetry-browser-detector。
类型层的变化:ResourceAttributes 被 @opentelemetry/api 的 Attributes 取代,@opentelemetry/api 的 peerDependency 从 1.0.0 提到 1.3.0。
浏览器 window.OTEL_* 配置被移除
浏览器端不再从 window.OTEL_* 读配置,bootstrap 逻辑需要改为代码显式配置。
core.getEnv() 拆了
@opentelemetry/core 的 getEnv() 不再一次性 load+parse 全部 OTEL_* 变量,改成按需读取单个变量的函数族:
getStringFromEnv()getNumberFromEnv()getBooleanFromEnv()getStringListFromEnv()diagLogLevelFromString()
默认值语义有变化:原 getEnv() 返回带默认值,getEnvWithoutDefaults() 不带默认值;现在调用侧自己用 ?? defaultValue 兜底。
// 1.x
const { OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT } = getEnv();
// 2.x
const limit = getNumberFromEnv('OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT') ?? Infinity;
删除项:
DEFAULT_ENVIRONMENT/ENVIRONMENT/RAW_ENVIRONMENT/parseEnvironment- 各种
DEFAULT_*_LIMIT常量:属性值长度默认改为字面量Infinity,count 类默认改为128
另外:IdGenerator / RandomIdGenerator 删除;AlwaysOnSampler / AlwaysOffSampler / ParentBasedSampler / TraceIdRatioSampler 移到 @opentelemetry/sdk-trace-base;isWrapped / ShimWrapped 移到 instrumentation 包。
这个改动的动机是:原来每新增一个 OTEL_* 变量都要更新 core 发版,按需单读把耦合拆掉了。
NodeTracerProvider 不再消费 env 创建 exporter/propagator
影响最大的是第 4 节,迁移时容易“不报错但数据不出门”。
BasicTracerProvider 与 NodeTracerProvider 不再读 OTEL_TRACES_EXPORTER 创建 exporter,也不再读 OTEL_PROPAGATORS 创建 propagator。这套逻辑挪到了 @opentelemetry/sdk-node 的 NodeSDK。
后果很直接:裸用 NodeTracerProvider 且依赖环境变量配 exporter 的代码,升级后不会有任何报错,但 trace 不会被导出。
// 1.x:环境变量驱动的裸 provider
const provider = new NodeTracerProvider();
provider.register();
// 2.x:要交给 NodeSDK,或代码显式注入
import { NodeSDK } from '@opentelemetry/sdk-node';
const sdk = new NodeSDK();
sdk.start();
BasicTracerProvider 相关删除:
addSpanProcessor()删除,改为构造参数传入getActiveSpanProcessor()与resource改为私有register()删除,改用NodeTracerProvider#register()或手动trace.setGlobalTracerProvider()EXPORTER_FACTORY/PROPAGATOR_FACTORY/ForceFlushState删除Tracerclass 误导出删除,改用provider.getTracer(),类型层面用@opentelemetry/api的Tracer
Span:parentSpanId 改名,sampler 回退策略调整
Span / ReadableSpan 的 parentSpanId 改为 parentSpanContext,对齐 spec:
// 1.x
span.parentSpanId
// 2.x
span.parentSpanContext?.spanId
ReadableSpan.instrumentationLibrary 改为 instrumentationScope。new Span() 不再可用,统一走 tracer.startSpan()。
OTEL_TRACES_SAMPLER 配置非法值时的回退行为有变:之前回退 AlwaysOnSampler,现在回退 ParentBasedAlwaysOnSampler。
sdk-metrics:View class 移除
@opentelemetry/sdk-metrics 的 View class 和各个 *Aggregation class 被移除,改为传 ViewOptions 对象 + AggregationType 枚举。
attributeKeys 改为 attributesProcessors,搭配 createAllowListAttributesProcessor / createDenyListAttributesProcessor。
// 1.x
new View({ meterName, attributeKeys: ['http.*'] })
// 2.x
// ViewOptions + AggregationType 枚举/attributesProcessors
迁移优先级判断
如果你的接入层基本只依赖 NodeSDK,主要工作量就是升 Node/TS 最低版本;Resource / getEnv() / parentSpanId / Metrics class 这些改动都是编译期可抓的,按编译错误逐个改即可。
真正需要留神的是第 4 节:NodeSDK 之外的裸 NodeTracerProvider 不再读 env,属于“不报错但数据不出门”的静默变化。手动拼过 Provider、自己读过 env、或者持久化过 span 对象的代码,要按上面几节逐一排查。
参考资料
- 官方迁移文档:https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/upgrade-to-2.x.md
- stable CHANGELOG:https://github.com/open-telemetry/opentelemetry-js/blob/main/CHANGELOG.md
- experimental CHANGELOG:https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/CHANGELOG.md
按 OTel 版本策略,1.x stable 在 2.0.0 发布后仍支持一年,不急于一次切完的可以先排期。