@opentelemetry/instrumentation

中文文档
0.301.0发布于 2026/11/06Apache-2.0TypeScriptESM + CJS构建来源已验证近 30 天下载 4.4亿

Base class for node which OpenTelemetry instrumentation modules extend

原始使用文档
文档目录11 节
  1. Installation
  2. Usage in Node
  3. Usage in Web
  4. AutoLoader
  5. NODE - Auto Loader
  6. WEB - Auto Loader
  7. Selection of the used TracerProvider/MeterProvider
  8. Instrumentation for ECMAScript Modules (ESM) in Node.js (ex…
  9. Limitations
  10. License
  11. Useful links

OpenTelemetry Instrumentation for web and node

NPM Published Version Apache License

Note: This is an experimental package under active development. New releases may include breaking changes.

Installation

Note: Much of OpenTelemetry JS documentation is written assuming the compiled application is run as CommonJS. For more details on ECMAScript Modules vs CommonJS, refer to esm-support.

npm install --save @opentelemetry/instrumentation

Usage in Node

import {
  InstrumentationBase,
  InstrumentationConfig,
  InstrumentationNodeModuleDefinition,
  InstrumentationNodeModuleFile,
} from '@opentelemetry/instrumentation';

import type * as module_name_to_be_patched from 'module_name_to_be_patched';

export class MyInstrumentation extends InstrumentationBase {
  constructor(config: InstrumentationConfig = {}) {
    super('MyInstrumentation', VERSION, config);
  }

  /**
   * Init method will be called when the plugin is constructed.
   * It returns an `InstrumentationNodeModuleDefinition` which describes
   *   the node module to be instrumented and patched.
   * It may also return a list of `InstrumentationNodeModuleDefinition`s if
   *   the plugin should patch multiple modules or versions.
   */
  protected init() {
    const module = new InstrumentationNodeModuleDefinition(
      'module_name_to_be_patched',
      ['1.*'],
       this._onPatchMain,
       this._onUnPatchMain,
    );
    // in case you need to patch additional files - this is optional
    module.files.push(this._addPatchingMethod());

    return module;
    // you can also define more modules then just return an array of modules
    // return [module1, module2, ....]
  }

  private _onPatchMain(moduleExports: typeof module_name_to_be_patched) {
    this._wrap(
      moduleExports,
      'mainMethodName',
      this._patchMainMethodName()
    );
    return moduleExports;
  }

  private _onUnPatchMain(moduleExports: typeof module_name_to_be_patched) {
    this._unwrap(moduleExports, 'mainMethodName');
  }

  private _addPatchingMethod(): InstrumentationNodeModuleFile {
    const file = new InstrumentationNodeModuleFile(
      'module_name_to_be_patched/src/some_file.js',
      this._onPatchMethodName,
      this._onUnPatchMethodName,
    );
    return file;
  }

  private _onPatchMethodName(moduleExports: typeof module_name_to_be_patched) {
    this._wrap(
      moduleExports,
      'methodName',
      this._patchMethodName()
    );
    return moduleExports;
  }

  private _onUnPatchMethodName(moduleExports: typeof module_name_to_be_patched) {
    this._unwrap(moduleExports, 'methodName');
  }

  private _patchMethodName(): (original) => any {
    const plugin = this;
    return function methodName(original) {
      return function patchMethodName(this: any): PromiseOrValue<module_name_to_be_patched.methodName> {
        console.log('methodName', arguments);
        return original.apply(this, arguments);
      };
    };
  }

  private _patchMainMethodName(): (original) => any {
    const plugin = this;
    return function mainMethodName(original) {
      return function patchMainMethodName(this: any): PromiseOrValue<module_name_to_be_patched.mainMethodName> {
        console.log('mainMethodName', arguments);
        return original.apply(this, arguments);
      };
    };
  }
}

// Later, but before the module to instrument is required

const myInstrumentation = new MyInstrumentation();
myInstrumentation.setTracerProvider(provider); // this is optional, only if global TracerProvider shouldn't be used
myInstrumentation.setMeterProvider(meterProvider); // this is optional
myInstrumentation.enable();
// or use Auto Loader

Usage in Web

import {
  InstrumentationBase,
  InstrumentationConfig,
} from '@opentelemetry/instrumentation';

import { Instrumentation } from '@opentelemetry/instrumentation';

export class MyInstrumentation extends InstrumentationBase {
  constructor(config: InstrumentationConfig = {}) {
    super('MyInstrumentation', VERSION, config);
  }

  private _patchOpen() {
    return (original: OpenFunction): OpenFunction => {
      const plugin = this;
      return function patchOpen(this: XMLHttpRequest, ...args): void {
        console.log('open', arguments);
        return original.apply(this, args);
      };
    };
  }

  public enable() {
    this._wrap(XMLHttpRequest.prototype, 'open', this._patchOpen());
  }
  public disable() {
    this._unwrap(XMLHttpRequest.prototype, 'open');
  }
}

// Later

const myInstrumentation = new MyInstrumentation();
myInstrumentation.setTracerProvider(provider); // this is optional, only if global TracerProvider shouldn't be used
myInstrumentation.setMeterProvider(meterProvider); // this is optional, only if global MeterProvider shouldn't be used
myInstrumentation.enable();
// or use Auto Loader

AutoLoader

NODE - Auto Loader

const { trace } = require('@opentelemetry/api');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
const { TracerProvider } = require('@opentelemetry/sdk-trace');

const tracerProvider = new TracerProvider();
trace.setGlobalTracerProvider(tracerProvider);
// See https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-trace/
// for a more complete example setting up a *context manager* and *propagators*.

registerInstrumentations({
  instrumentations: [
    new HttpInstrumentation(),
  ],
  //tracerProvider: tracerProvider, // optional, only if global TracerProvider shouldn't be used
  //meterProvider: meterProvider, // optional, only if global MeterProvider shouldn't be used
});

WEB - Auto Loader


const { propagation, trace } = require('@opentelemetry/api');
const { TracerProvider } = require('@opentelemetry/sdk-trace');
const { B3Propagator } = require('@opentelemetry/propagator-b3');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const { XMLHttpRequestInstrumentation } = require('@opentelemetry/instrumentation-xml-http-request');
const { TracerProvider } = require('@opentelemetry/sdk-trace');

const tracerProvider = new TracerProvider();

propagation.setGlobalPropagator(new B3Propagator());
trace.setGlobalTracerProvider(provider);

registerInstrumentations({
  instrumentations: [
    new XMLHttpRequestInstrumentation({
      ignoreUrls: [/localhost/],
      propagateTraceHeaderCorsUrls: [
        'http://localhost:8090',
      ],
    }),
  ],
  //tracerProvider: tracerProvider, // optional, only if global TracerProvider shouldn't be used
  //meterProvider: meterProvider, // optional, only if global MeterProvider shouldn't be used
});

Selection of the used TracerProvider/MeterProvider

The registerInstrumentations() API allows to specify which TracerProvider and/or MeterProvider to use by the given options object. If nothing is specified the global registered provider is used. Usually this is what most users want therefore it's recommended to keep this default.

There might be use case where someone has the need for more providers within an application. Please note that special care must be takes in such setups to avoid leaking information from one provider to the other because there are a lot places where e.g. the global ContextManager or Propagator is used.

Instrumentation for ECMAScript Modules (ESM) in Node.js (experimental)

Node.js uses a different module loader for ECMAScript Modules (ESM) vs. CommonJS (CJS). A require() call will cause Node.js to use the CommonJS module loader. An import ... statement or import() call will cause Node.js to use the ECMAScript module loader.

If your application is written in JavaScript as ESM, or it must compile to ESM from TypeScript, then a loader hook is required to properly patch instrumentation. The custom hook for ESM instrumentation is --experimental-loader=@opentelemetry/instrumentation/hook.mjs. This flag must be passed to the node binary, which is often done as a startup command and/or in the NODE_OPTIONS environment variable.

For more details on ECMAScript Modules vs CommonJS, refer to esm-support.

Limitations

Instrumentations for external modules (e.g. express, mongodb,...) hooks the require call or import statement. Therefore following conditions need to be met that this mechanism can work:

  • Instrumentations are registered before the module to instrument is requireed (CJS only)
  • modules are not included in a bundle. Tools like esbuild, webpack, ... usually have some mechanism to exclude specific modules from bundling

License

Apache 2.0 - See LICENSE for more information.

Third-party licenses and copyright notices can be found in the LICENSES directory.

版本与发布记录

@opentelemetry/instrumentation 共发布 167 个版本,首次发布于 2020/09/30;过去 12 个月发布了 22 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.301.0latest2026/11/06今天
0.300.02026/10/2116 天前
0.300.0-rc.0canary2026/10/1423 天前
0.223.02026/10/0630 天前
0.300.0-development.12026/10/051 个月前
0.300.0-development.02026/09/211 个月前

其他发布通道:next → 0.34.0,canary → 0.300.0-rc.0。

关于 @opentelemetry/instrumentation 的常见问题

@opentelemetry/instrumentation 是什么?

Base class for node which OpenTelemetry instrumentation modules extend

如何安装 @opentelemetry/instrumentation?

在项目目录运行 npm install @opentelemetry/instrumentation,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@opentelemetry/api(>=1.10.0 <1.11.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@opentelemetry/instrumentation 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@opentelemetry/instrumentation 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@opentelemetry/instrumentation 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.15.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@opentelemetry/instrumentation 可以商用吗?

@opentelemetry/instrumentation 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@opentelemetry/instrumentation 的下载量有多少?

根据 npm 官方下载统计,@opentelemetry/instrumentation 在 2026/10/05 – 2026/11/03 这 30 天内被下载 435,530,209 次,日均约 14,517,674 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@opentelemetry/instrumentation 还在维护吗?

最新版本 0.301.0 发布于 2026/11/06(今天);至今共发布 167 个版本,其中过去 12 个月发布了 22 个;首次发布于 2020/09/30。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。