basant307/AI_Governance_Project
048
1# OpenTelemetry Instrumentation for web and node2 3[![NPM Published Version][npm-img]][npm-url]4[![Apache License][license-image]][license-image]5 6**Note: This is an experimental package under active development. New releases may include breaking changes.**7 8## Installation9 10**Note: Much of OpenTelemetry JS documentation is written assuming the compiled application is run as CommonJS.**11For more details on ECMAScript Modules vs CommonJS, refer to [esm-support](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md).12 13```bash14npm install --save @opentelemetry/instrumentation15```16 17## Usage in Node18 19```typescript20import {21 InstrumentationBase,22 InstrumentationConfig,23 InstrumentationNodeModuleDefinition,24 InstrumentationNodeModuleFile,25} from '@opentelemetry/instrumentation';26 27import type * as module_name_to_be_patched from 'module_name_to_be_patched';28 29export class MyInstrumentation extends InstrumentationBase {30 constructor(config: InstrumentationConfig = {}) {31 super('MyInstrumentation', VERSION, config);32 }33 34 /**35 * Init method will be called when the plugin is constructed.36 * It returns an `InstrumentationNodeModuleDefinition` which describes37 * the node module to be instrumented and patched.38 * It may also return a list of `InstrumentationNodeModuleDefinition`s if39 * the plugin should patch multiple modules or versions.40 */41 protected init() {42 const module = new InstrumentationNodeModuleDefinition(43 'module_name_to_be_patched',44 ['1.*'],45 this._onPatchMain,46 this._onUnPatchMain,47 );48 // in case you need to patch additional files - this is optional49 module.files.push(this._addPatchingMethod());50 51 return module;52 // you can also define more modules then just return an array of modules53 // return [module1, module2, ....]54 }55 56 private _onPatchMain(moduleExports: typeof module_name_to_be_patched) {57 this._wrap(58 moduleExports,59 'mainMethodName',60 this._patchMainMethodName()61 );62 return moduleExports;63 }64 65 private _onUnPatchMain(moduleExports: typeof module_name_to_be_patched) {66 this._unwrap(moduleExports, 'mainMethodName');67 }68 69 private _addPatchingMethod(): InstrumentationNodeModuleFile {70 const file = new InstrumentationNodeModuleFile(71 'module_name_to_be_patched/src/some_file.js',72 this._onPatchMethodName,73 this._onUnPatchMethodName,74 );75 return file;76 }77 78 private _onPatchMethodName(moduleExports: typeof module_name_to_be_patched) {79 this._wrap(80 moduleExports,81 'methodName',82 this._patchMethodName()83 );84 return moduleExports;85 }86 87 private _onUnPatchMethodName(moduleExports: typeof module_name_to_be_patched) {88 this._unwrap(moduleExports, 'methodName');89 }90 91 private _patchMethodName(): (original) => any {92 const plugin = this;93 return function methodName(original) {94 return function patchMethodName(this: any): PromiseOrValue<module_name_to_be_patched.methodName> {95 console.log('methodName', arguments);96 return original.apply(this, arguments);97 };98 };99 }100 101 private _patchMainMethodName(): (original) => any {102 const plugin = this;103 return function mainMethodName(original) {104 return function patchMainMethodName(this: any): PromiseOrValue<module_name_to_be_patched.mainMethodName> {105 console.log('mainMethodName', arguments);106 return original.apply(this, arguments);107 };108 };109 }110}111 112// Later, but before the module to instrument is required113 114const myInstrumentation = new MyInstrumentation();115myInstrumentation.setTracerProvider(provider); // this is optional, only if global TracerProvider shouldn't be used116myInstrumentation.setMeterProvider(meterProvider); // this is optional117myInstrumentation.enable();118// or use Auto Loader119```120 121## Usage in Web122 123```typescript124import {125 InstrumentationBase,126 InstrumentationConfig,127} from '@opentelemetry/instrumentation';128 129import { Instrumentation } from '@opentelemetry/instrumentation';130 131export class MyInstrumentation extends InstrumentationBase {132 constructor(config: InstrumentationConfig = {}) {133 super('MyInstrumentation', VERSION, config);134 }135 136 private _patchOpen() {137 return (original: OpenFunction): OpenFunction => {138 const plugin = this;139 return function patchOpen(this: XMLHttpRequest, ...args): void {140 console.log('open', arguments);141 return original.apply(this, args);142 };143 };144 }145 146 public enable() {147 this._wrap(XMLHttpRequest.prototype, 'open', this._patchOpen());148 }149 public disable() {150 this._unwrap(XMLHttpRequest.prototype, 'open');151 }152}153 154// Later155 156const myInstrumentation = new MyInstrumentation();157myInstrumentation.setTracerProvider(provider); // this is optional, only if global TracerProvider shouldn't be used158myInstrumentation.setMeterProvider(meterProvider); // this is optional, only if global MeterProvider shouldn't be used159myInstrumentation.enable();160// or use Auto Loader161```162 163## AutoLoader164 165### NODE - Auto Loader166 167```javascript168const { B3Propagator } = require('@opentelemetry/propagator-b3');169const { registerInstrumentations } = require('@opentelemetry/instrumentation');170const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');171const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');172 173const tracerProvider = new NodeTracerProvider();174 175tracerProvider.register({176 propagator: new B3Propagator(),177});178 179registerInstrumentations({180 instrumentations: [181 new HttpInstrumentation(),182 ],183 //tracerProvider: tracerProvider, // optional, only if global TracerProvider shouldn't be used184 //meterProvider: meterProvider, // optional, only if global MeterProvider shouldn't be used185});186 187```188 189### WEB - Auto Loader190 191```javascript192const { B3Propagator } = require('@opentelemetry/propagator-b3');193const { registerInstrumentations } = require('@opentelemetry/instrumentation');194const { XMLHttpRequestInstrumentation } = require('@opentelemetry/instrumentation-xml-http-request');195const { WebTracerProvider } = require('@opentelemetry/sdk-trace-web');196 197const tracerProvider = new WebTracerProvider();198 199tracerProvider.register({200 propagator: new B3Propagator(),201});202 203registerInstrumentations({204 instrumentations: [205 new XMLHttpRequestInstrumentation({206 ignoreUrls: [/localhost/],207 propagateTraceHeaderCorsUrls: [208 'http://localhost:8090',209 ],210 }),211 ],212 //tracerProvider: tracerProvider, // optional, only if global TracerProvider shouldn't be used213 //meterProvider: meterProvider, // optional, only if global MeterProvider shouldn't be used214});215```216 217## Selection of the used TracerProvider/MeterProvider218 219The `registerInstrumentations()` API allows to specify which `TracerProvider` and/or `MeterProvider` to use by the given options object.220If nothing is specified the global registered provider is used. Usually this is what most users want therefore it's recommended to keep this default.221 222There 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 setups223to 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.224 225## Instrumentation for ECMAScript Modules (ESM) in Node.js (experimental)226 227Node.js uses a different module loader for ECMAScript Modules (ESM) vs. CommonJS (CJS).228A `require()` call will cause Node.js to use the CommonJS module loader.229An `import ...` statement or `import()` call will cause Node.js to use the ECMAScript module loader.230 231If 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.232The custom hook for ESM instrumentation is `--experimental-loader=@opentelemetry/instrumentation/hook.mjs`.233This flag must be passed to the `node` binary, which is often done as a startup command and/or in the `NODE_OPTIONS` environment variable.234 235For more details on ECMAScript Modules vs CommonJS, refer to [esm-support](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md).236 237## Limitations238 239Instrumentations 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:240 241- Instrumentations are registered **before** the module to instrument is `require`ed (CJS only)242- modules are not included in a bundle. Tools like `esbuild`, `webpack`, ... usually have some mechanism to exclude specific modules from bundling243 244## License245 246Apache 2.0 - See [LICENSE][license-url] for more information.247 248Third-party licenses and copyright notices can be found in the [LICENSES directory](./LICENSES).249 250## Useful links251 252- For more information on OpenTelemetry, visit: <https://opentelemetry.io/>253- For help or feedback on this project, join us in [GitHub Discussions][discussions-url]254 255[discussions-url]: https://github.com/open-telemetry/opentelemetry-js/discussions256[license-url]: https://github.com/open-telemetry/opentelemetry-js/blob/main/LICENSE257[license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat258[npm-url]: https://www.npmjs.com/package/@opentelemetry/instrumentation259[npm-img]: https://badge.fury.io/js/%40opentelemetry%2Finstrumentation.svg260 