Node.js ESM应用使用OpenTelemetry自动插装无追踪生成的问题咨询
Node.js ESM环境下OpenTelemetry自动插装问题解答
这不属于正常现象,但ESM环境下OpenTelemetry的自动插装确实需要特殊配置——默认的CommonJS插装逻辑无法直接适配ESM模块加载机制。以下是可行的自动插装方案,无需直接切换到手动插装:
核心前提:依赖版本与基础配置
- 确保
@opentelemetry/sdk-node、@opentelemetry/auto-instrumentations-node为最新稳定版,早期版本对ESM的支持存在缺陷。 - 项目
package.json中已设置"type": "module",明确启用ESM规范。
正确的自动插装启动方式
ESM环境下不能使用CommonJS常用的node -r预加载方式,需通过OpenTelemetry提供的ESM loader来实现插装:
方式1:直接通过loader启动
执行启动命令时指定experimental loader:
node --experimental-loader=@opentelemetry/instrumentation/hook.mjs your-app-entry.mjs
方式2:单独初始化插装配置
创建独立的OpenTelemetry初始化文件(如otel-init.mjs),确保在业务代码加载前执行:
import { NodeSDK } from '@opentelemetry/sdk-node'; import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-node'; import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'; const sdk = new NodeSDK({ traceExporter: new ConsoleSpanExporter(), spanProcessor: new SimpleSpanProcessor(new ConsoleSpanExporter()), instrumentations: [getNodeAutoInstrumentations()] }); // 捕获进程退出信号,确保SDK正确关闭 process.on('SIGTERM', () => { sdk.shutdown() .then(() => console.log('OpenTelemetry SDK shutdown successfully')) .catch((err) => console.error('Error shutting down SDK', err)) .finally(() => process.exit(0)); }); sdk.start();
启动时同时指定loader和预加载初始化文件:
node --experimental-loader=@opentelemetry/instrumentation/hook.mjs -r ./otel-init.mjs your-app-entry.mjs
关键注意事项
- 确保所有需要插装的依赖(如express、axios)支持ESM加载,部分老旧CommonJS包可能无法被自动插装,可单独启用对应instrumentation排查。
- 避免在业务代码中使用
import()动态加载需要插装的模块——自动插装无法捕获动态加载的模块,这种场景可手动初始化对应instrumentation或调整加载顺序。 - 若使用ts-node等其他loader,需确保OpenTelemetry的loader优先级最高,避免插装逻辑被覆盖。
排查步骤
如果仍无追踪数据,可逐步缩小范围排查:
- 先禁用自动插装集合,单独启用某一个instrumentation(如
@opentelemetry/instrumentation-express),验证是否能生成数据。 - 检查ConsoleSpanExporter是否输出日志,确认SDK是否正常初始化。
- 验证业务代码中的请求/操作是否触发了被插装的方法(如express路由、HTTP请求)。
内容的提问来源于stack exchange,提问作者parv bhardwaj
相关产品推荐
相关产品推荐

