{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../src/instrumentation.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n isWrapped,\n} from '@opentelemetry/instrumentation';\nimport {\n trace,\n context,\n Link,\n SpanStatusCode,\n SpanKind,\n} from '@opentelemetry/api';\nimport { DataloaderInstrumentationConfig } from './types';\nimport { PACKAGE_NAME, PACKAGE_VERSION } from './version';\nimport type * as Dataloader from 'dataloader';\n\nconst MODULE_NAME = 'dataloader';\n\ntype DataloaderInternal = typeof Dataloader.prototype & {\n _batchLoadFn: Dataloader.BatchLoadFn;\n _batch: { spanLinks?: Link[] } | null;\n\n // TODO: Remove this once types on Dataloader get fixed https://github.com/graphql/dataloader/pull/334\n name?: string | null;\n};\n\ntype LoadFn = (typeof Dataloader.prototype)['load'];\ntype LoadManyFn = (typeof Dataloader.prototype)['loadMany'];\n\nexport class DataloaderInstrumentation extends InstrumentationBase {\n constructor(config: DataloaderInstrumentationConfig = {}) {\n super(PACKAGE_NAME, PACKAGE_VERSION, config);\n }\n\n protected init() {\n return [\n new InstrumentationNodeModuleDefinition(\n MODULE_NAME,\n ['>=2.0.0 <3'],\n dataloader => {\n this._patchLoad(dataloader.prototype);\n this._patchLoadMany(dataloader.prototype);\n\n return this._getPatchedConstructor(dataloader);\n },\n dataloader => {\n if (isWrapped(dataloader.prototype.load)) {\n this._unwrap(dataloader.prototype, 'load');\n }\n\n if (isWrapped(dataloader.prototype.loadMany)) {\n this._unwrap(dataloader.prototype, 'loadMany');\n }\n }\n ) as InstrumentationNodeModuleDefinition,\n ];\n }\n\n private shouldCreateSpans(): boolean {\n const config = this.getConfig();\n const hasParentSpan = trace.getSpan(context.active()) !== undefined;\n return hasParentSpan || !config.requireParentSpan;\n }\n\n private getSpanName(\n dataloader: DataloaderInternal,\n operation: 'load' | 'loadMany' | 'batch'\n ): string {\n const dataloaderName = dataloader.name;\n if (dataloaderName === undefined || dataloaderName === null) {\n return `${MODULE_NAME}.${operation}`;\n }\n\n return `${MODULE_NAME}.${operation} ${dataloaderName}`;\n }\n\n private _getPatchedConstructor(\n constructor: typeof Dataloader\n ): typeof Dataloader {\n const prototype = constructor.prototype;\n const instrumentation = this;\n\n function PatchedDataloader(\n ...args: ConstructorParameters\n ) {\n const inst = new constructor(...args) as DataloaderInternal;\n\n if (!instrumentation.isEnabled()) {\n return inst;\n }\n\n if (isWrapped(inst._batchLoadFn)) {\n instrumentation._unwrap(inst, '_batchLoadFn');\n }\n\n instrumentation._wrap(inst, '_batchLoadFn', original => {\n return function patchedBatchLoadFn(\n this: DataloaderInternal,\n ...args: Parameters>\n ) {\n if (\n !instrumentation.isEnabled() ||\n !instrumentation.shouldCreateSpans()\n ) {\n return original.call(this, ...args);\n }\n\n const parent = context.active();\n const span = instrumentation.tracer.startSpan(\n instrumentation.getSpanName(inst, 'batch'),\n { links: this._batch?.spanLinks as Link[] | undefined },\n parent\n );\n\n return context.with(trace.setSpan(parent, span), () => {\n return (original.apply(this, args) as Promise)\n .then(value => {\n span.end();\n return value;\n })\n .catch(err => {\n span.recordException(err);\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: err.message,\n });\n span.end();\n throw err;\n });\n });\n };\n });\n\n return inst;\n }\n\n PatchedDataloader.prototype = prototype;\n return PatchedDataloader as unknown as typeof Dataloader;\n }\n\n private _patchLoad(proto: typeof Dataloader.prototype) {\n if (isWrapped(proto.load)) {\n this._unwrap(proto, 'load');\n }\n\n this._wrap(proto, 'load', this._getPatchedLoad.bind(this));\n }\n\n private _getPatchedLoad(original: LoadFn): LoadFn {\n const instrumentation = this;\n\n return function patchedLoad(\n this: DataloaderInternal,\n ...args: Parameters\n ) {\n if (!instrumentation.shouldCreateSpans()) {\n return original.call(this, ...args);\n }\n\n const parent = context.active();\n const span = instrumentation.tracer.startSpan(\n instrumentation.getSpanName(this, 'load'),\n { kind: SpanKind.CLIENT },\n parent\n );\n\n return context.with(trace.setSpan(parent, span), () => {\n const result = original\n .call(this, ...args)\n .then(value => {\n span.end();\n return value;\n })\n .catch(err => {\n span.recordException(err);\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: err.message,\n });\n span.end();\n throw err;\n });\n\n const loader = this as DataloaderInternal;\n\n if (loader._batch) {\n if (!loader._batch.spanLinks) {\n loader._batch.spanLinks = [];\n }\n\n loader._batch.spanLinks.push({ context: span.spanContext() } as Link);\n }\n\n return result;\n });\n };\n }\n\n private _patchLoadMany(proto: typeof Dataloader.prototype) {\n if (isWrapped(proto.loadMany)) {\n this._unwrap(proto, 'loadMany');\n }\n\n this._wrap(proto, 'loadMany', this._getPatchedLoadMany.bind(this));\n }\n\n private _getPatchedLoadMany(original: LoadManyFn): LoadManyFn {\n const instrumentation = this;\n\n return function patchedLoadMany(\n this: DataloaderInternal,\n ...args: Parameters\n ) {\n if (!instrumentation.shouldCreateSpans()) {\n return original.call(this, ...args);\n }\n\n const parent = context.active();\n const span = instrumentation.tracer.startSpan(\n instrumentation.getSpanName(this, 'loadMany'),\n { kind: SpanKind.CLIENT },\n parent\n );\n\n return context.with(trace.setSpan(parent, span), () => {\n // .loadMany never rejects, as errors from internal .load\n // calls are caught by dataloader lib\n return original.call(this, ...args).then(value => {\n span.end();\n return value;\n });\n });\n };\n }\n}\n"]}