{"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 { context, Span, SpanOptions } from '@opentelemetry/api';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport type { HandleFunction, NextFunction, Server } from 'connect';\nimport type { ServerResponse } from 'http';\nimport {\n AttributeNames,\n ConnectNames,\n ConnectTypes,\n} from './enums/AttributeNames';\nimport { PatchedRequest, Use, UseArgs, UseArgs2 } from './internal-types';\n/** @knipignore */\nimport { PACKAGE_NAME, PACKAGE_VERSION } from './version';\nimport {\n InstrumentationBase,\n InstrumentationConfig,\n InstrumentationNodeModuleDefinition,\n isWrapped,\n} from '@opentelemetry/instrumentation';\nimport { SEMATTRS_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport {\n replaceCurrentStackRoute,\n addNewStackLayer,\n generateRoute,\n} from './utils';\n\nexport const ANONYMOUS_NAME = 'anonymous';\n\n/** Connect instrumentation for OpenTelemetry */\nexport class ConnectInstrumentation extends InstrumentationBase {\n constructor(config: InstrumentationConfig = {}) {\n super(PACKAGE_NAME, PACKAGE_VERSION, config);\n }\n\n init() {\n return [\n new InstrumentationNodeModuleDefinition(\n 'connect',\n ['>=3.0.0 <4'],\n moduleExports => {\n return this._patchConstructor(moduleExports);\n }\n ),\n ];\n }\n\n private _patchApp(patchedApp: Server) {\n if (!isWrapped(patchedApp.use)) {\n this._wrap(patchedApp, 'use', this._patchUse.bind(this));\n }\n if (!isWrapped(patchedApp.handle)) {\n this._wrap(patchedApp, 'handle', this._patchHandle.bind(this));\n }\n }\n\n private _patchConstructor(original: () => Server): () => Server {\n const instrumentation = this;\n return function (this: Server, ...args) {\n const app = original.apply(this, args) as Server;\n instrumentation._patchApp(app);\n return app;\n };\n }\n\n public _patchNext(next: NextFunction, finishSpan: () => void): NextFunction {\n return function nextFunction(this: NextFunction, err?: any): void {\n const result = next.apply(this, [err]);\n finishSpan();\n return result;\n };\n }\n\n public _startSpan(routeName: string, middleWare: HandleFunction): Span {\n let connectType: ConnectTypes;\n let connectName: string;\n let connectTypeName: string;\n if (routeName) {\n connectType = ConnectTypes.REQUEST_HANDLER;\n connectTypeName = ConnectNames.REQUEST_HANDLER;\n connectName = routeName;\n } else {\n connectType = ConnectTypes.MIDDLEWARE;\n connectTypeName = ConnectNames.MIDDLEWARE;\n connectName = middleWare.name || ANONYMOUS_NAME;\n }\n const spanName = `${connectTypeName} - ${connectName}`;\n const options: SpanOptions = {\n attributes: {\n [SEMATTRS_HTTP_ROUTE]: routeName.length > 0 ? routeName : '/',\n [AttributeNames.CONNECT_TYPE]: connectType,\n [AttributeNames.CONNECT_NAME]: connectName,\n },\n };\n\n return this.tracer.startSpan(spanName, options);\n }\n\n public _patchMiddleware(\n routeName: string,\n middleWare: HandleFunction\n ): HandleFunction {\n const instrumentation = this;\n const isErrorMiddleware = middleWare.length === 4;\n\n function patchedMiddleware(this: Use): void {\n if (!instrumentation.isEnabled()) {\n return (middleWare as any).apply(this, arguments);\n }\n const [reqArgIdx, resArgIdx, nextArgIdx] = isErrorMiddleware\n ? [1, 2, 3]\n : [0, 1, 2];\n const req = arguments[reqArgIdx] as PatchedRequest;\n const res = arguments[resArgIdx] as ServerResponse;\n const next = arguments[nextArgIdx] as NextFunction;\n\n replaceCurrentStackRoute(req, routeName);\n\n const rpcMetadata = getRPCMetadata(context.active());\n if (routeName && rpcMetadata?.type === RPCType.HTTP) {\n rpcMetadata.route = generateRoute(req);\n }\n\n let spanName = '';\n if (routeName) {\n spanName = `request handler - ${routeName}`;\n } else {\n spanName = `middleware - ${middleWare.name || ANONYMOUS_NAME}`;\n }\n const span = instrumentation._startSpan(routeName, middleWare);\n instrumentation._diag.debug('start span', spanName);\n let spanFinished = false;\n\n function finishSpan() {\n if (!spanFinished) {\n spanFinished = true;\n instrumentation._diag.debug(`finishing span ${(span as any).name}`);\n span.end();\n } else {\n instrumentation._diag.debug(\n `span ${(span as any).name} - already finished`\n );\n }\n res.removeListener('close', finishSpan);\n }\n\n res.addListener('close', finishSpan);\n arguments[nextArgIdx] = instrumentation._patchNext(next, finishSpan);\n\n return (middleWare as any).apply(this, arguments);\n }\n\n Object.defineProperty(patchedMiddleware, 'length', {\n value: middleWare.length,\n writable: false,\n configurable: true,\n });\n\n return patchedMiddleware;\n }\n\n public _patchUse(original: Server['use']): Use {\n const instrumentation = this;\n return function (this: Server, ...args: UseArgs): Server {\n const middleWare = args[args.length - 1] as HandleFunction;\n const routeName = (args[args.length - 2] || '') as string;\n\n args[args.length - 1] = instrumentation._patchMiddleware(\n routeName,\n middleWare\n );\n\n return original.apply(this, args as UseArgs2);\n };\n }\n\n public _patchHandle(original: Server['handle']): Server['handle'] {\n const instrumentation = this;\n return function (this: Server): ReturnType {\n const [reqIdx, outIdx] = [0, 2];\n const req = arguments[reqIdx] as PatchedRequest;\n const out = arguments[outIdx];\n const completeStack = addNewStackLayer(req);\n\n if (typeof out === 'function') {\n arguments[outIdx] = instrumentation._patchOut(\n out as NextFunction,\n completeStack\n );\n }\n\n return (original as any).apply(this, arguments);\n };\n }\n\n public _patchOut(out: NextFunction, completeStack: () => void): NextFunction {\n return function nextFunction(this: NextFunction, ...args: any[]): void {\n completeStack();\n return Reflect.apply(out, this, args);\n };\n }\n}\n"]}