{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../src/instrumentation.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport * as api from '@opentelemetry/api';\nimport {\n  isWrapped,\n  InstrumentationBase,\n  InstrumentationNodeModuleDefinition,\n  safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\n\nimport type * as koa from 'koa';\nimport { KoaLayerType, KoaInstrumentationConfig } from './types';\n/** @knipignore */\nimport { PACKAGE_NAME, PACKAGE_VERSION } from './version';\nimport { getMiddlewareMetadata, isLayerIgnored } from './utils';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport {\n  kLayerPatched,\n  KoaContext,\n  KoaMiddleware,\n  KoaPatchedMiddleware,\n} from './internal-types';\n\n/** Koa instrumentation for OpenTelemetry */\nexport class KoaInstrumentation extends InstrumentationBase<KoaInstrumentationConfig> {\n  constructor(config: KoaInstrumentationConfig = {}) {\n    super(PACKAGE_NAME, PACKAGE_VERSION, config);\n  }\n\n  protected init() {\n    return new InstrumentationNodeModuleDefinition(\n      'koa',\n      ['>=2.0.0 <4'],\n      (module: any) => {\n        const moduleExports: typeof koa =\n          module[Symbol.toStringTag] === 'Module'\n            ? module.default // ESM\n            : module; // CommonJS\n        if (moduleExports == null) {\n          return moduleExports;\n        }\n        if (isWrapped(moduleExports.prototype.use)) {\n          this._unwrap(moduleExports.prototype, 'use');\n        }\n        this._wrap(\n          moduleExports.prototype,\n          'use',\n          this._getKoaUsePatch.bind(this)\n        );\n        return module;\n      },\n      (module: any) => {\n        const moduleExports: typeof koa =\n          module[Symbol.toStringTag] === 'Module'\n            ? module.default // ESM\n            : module; // CommonJS\n        if (isWrapped(moduleExports.prototype.use)) {\n          this._unwrap(moduleExports.prototype, 'use');\n        }\n      }\n    );\n  }\n\n  /**\n   * Patches the Koa.use function in order to instrument each original\n   * middleware layer which is introduced\n   * @param {KoaMiddleware} middleware - the original middleware function\n   */\n  private _getKoaUsePatch(original: (middleware: KoaMiddleware) => koa) {\n    const plugin = this;\n    return function use(this: koa, middlewareFunction: KoaMiddleware) {\n      let patchedFunction: KoaMiddleware;\n      if (middlewareFunction.router) {\n        patchedFunction = plugin._patchRouterDispatch(middlewareFunction);\n      } else {\n        patchedFunction = plugin._patchLayer(middlewareFunction, false);\n      }\n      return original.apply(this, [patchedFunction]);\n    };\n  }\n\n  /**\n   * Patches the dispatch function used by @koa/router. This function\n   * goes through each routed middleware and adds instrumentation via a call\n   * to the @function _patchLayer function.\n   * @param {KoaMiddleware} dispatchLayer - the original dispatch function which dispatches\n   * routed middleware\n   */\n  private _patchRouterDispatch(dispatchLayer: KoaMiddleware): KoaMiddleware {\n    api.diag.debug('Patching @koa/router dispatch');\n\n    const router = dispatchLayer.router;\n\n    const routesStack = router?.stack ?? [];\n    for (const pathLayer of routesStack) {\n      const path = pathLayer.path;\n      // Type cast needed: router.stack comes from @types/koa@2.x but we use @types/koa@3.x\n      // See internal-types.ts for full explanation\n      const pathStack = pathLayer.stack as any;\n      for (let j = 0; j < pathStack.length; j++) {\n        const routedMiddleware: KoaMiddleware = pathStack[j];\n        pathStack[j] = this._patchLayer(routedMiddleware, true, path);\n      }\n    }\n\n    return dispatchLayer;\n  }\n\n  /**\n   * Patches each individual @param middlewareLayer function in order to create the\n   * span and propagate context. It does not create spans when there is no parent span.\n   * @param {KoaMiddleware} middlewareLayer - the original middleware function.\n   * @param {boolean} isRouter - tracks whether the original middleware function\n   * was dispatched by the router originally\n   * @param {string?} layerPath - if present, provides additional data from the\n   * router about the routed path which the middleware is attached to\n   */\n  private _patchLayer(\n    middlewareLayer: KoaPatchedMiddleware,\n    isRouter: boolean,\n    layerPath?: string | RegExp\n  ): KoaMiddleware {\n    const layerType = isRouter ? KoaLayerType.ROUTER : KoaLayerType.MIDDLEWARE;\n    // Skip patching layer if its ignored in the config\n    if (\n      middlewareLayer[kLayerPatched] === true ||\n      isLayerIgnored(layerType, this.getConfig())\n    )\n      return middlewareLayer;\n\n    if (\n      middlewareLayer.constructor.name === 'GeneratorFunction' ||\n      middlewareLayer.constructor.name === 'AsyncGeneratorFunction'\n    ) {\n      api.diag.debug('ignoring generator-based Koa middleware layer');\n      return middlewareLayer;\n    }\n\n    middlewareLayer[kLayerPatched] = true;\n\n    api.diag.debug('patching Koa middleware layer');\n    return async (context: KoaContext, next: koa.Next) => {\n      const parent = api.trace.getSpan(api.context.active());\n      if (parent === undefined) {\n        return middlewareLayer(context, next);\n      }\n      const metadata = getMiddlewareMetadata(\n        context,\n        middlewareLayer,\n        isRouter,\n        layerPath\n      );\n      const span = this.tracer.startSpan(metadata.name, {\n        attributes: metadata.attributes,\n      });\n\n      const rpcMetadata = getRPCMetadata(api.context.active());\n\n      if (rpcMetadata?.type === RPCType.HTTP && context._matchedRoute) {\n        rpcMetadata.route = context._matchedRoute.toString();\n      }\n\n      const { requestHook } = this.getConfig();\n      if (requestHook) {\n        safeExecuteInTheMiddle(\n          () =>\n            requestHook(span, {\n              context,\n              middlewareLayer,\n              layerType,\n            }),\n          e => {\n            if (e) {\n              api.diag.error('koa instrumentation: request hook failed', e);\n            }\n          },\n          true\n        );\n      }\n\n      const newContext = api.trace.setSpan(api.context.active(), span);\n      return api.context.with(newContext, async () => {\n        try {\n          return await middlewareLayer(context, next);\n        } catch (err: any) {\n          span.recordException(err);\n          throw err;\n        } finally {\n          span.end();\n        }\n      });\n    };\n  }\n}\n"]}