网络和节点的 OpenTeleometry 仪器
注:这是正在积极开发的实验包. 新的发布可能包括突破变化.
安装
注:OpenTeleometry JS的许多文件都是在假设编译的应用程序作为CommonJS运行的情况下编写的. 关于ECMAScript模块对普通JS的更详细信息,请参见: esm 支持系统。 。 。 .
npm install --save @opentelemetry/instrumentation
节点使用
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
网络使用
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
自动记录器
NODE - 自动装入器
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 - 自动装入器
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
});
选择已使用的追踪器/测量器
这个 registerInstrumentations() API 允许指定哪个 TracerProvider 和(或) MeterProvider 用于给定选项对象.
如果没有具体说明,则使用全球注册供应商。 通常这是大多数用户想要的,因此建议保留这个默认.
如果有人需要在应用程序中增加供应商,则可能存在这种情况。 请注意,在这种设置中必须特别小心
以避免信息从一个提供者泄露到另一个提供者,因为有许多地方,例如全球 ContextManager 或者说 Propagator 已使用.
ECMAScript模块(ESM)在Node.js(实验)的仪器
Node.js在ECMAScript Modules (ESM) vs. CommunityJS (CJS)中使用了不同的模块加载器.
A 类 require() 调用将使 Node.js 使用 CommunityJS 模块加载器.
一个 import ... 声明或 import() 调用会导致Node.js使用ECMAScript模块加载器.
如果您的应用程序被写入JavaScript中作为无害环境管理,或者它必须从TypeScript中编译到无害环境管理,那么需要装入器钩来适当补补仪器.
无害环境管理仪器的自定义钩 --experimental-loader=@opentelemetry/instrumentation/hook.mjs。 。 。 .
这面旗帜必须传递给 node 二进制,通常作为启动命令和/或在 NODE_OPTIONS 环境变量.
关于ECMAScript模块对普通JS的更详细信息,请参见: esm 支持系统。 。 。 .
限制
用于外部模块(如快取、mongodb、.)的仪器将 require 调用或 import 语句。 因此,需要满足以下条件,使该机制能够发挥作用:
- 登记了仪器 在此之前 到仪器的模块是
require编 (仅CJS) - 模块不包含在捆绑中。 工具类
esbuild, (中文(简体) ),webpack,.通常有一些机制将特定模块排除在捆绑之外
许可证
Apache 2. 0 - 见 自由主义 更多信息.
第三方许可和版权通知可在 属性目录。 。 。 .
有用链接
- 关于OpenTeleometry的更多信息,请访问: https://opentelemetry.io/ 互联网档案馆的存檔,存档日期2013-12-02
- 如欲获得该项目的帮助或反馈,请加入 GitHub 讨论