{"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 { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport {\n  trace,\n  context,\n  diag,\n  Attributes,\n  SpanStatusCode,\n} from '@opentelemetry/api';\nimport type * as express from 'express';\nimport { ExpressInstrumentationConfig, ExpressRequestInfo } from './types';\nimport { ExpressLayerType } from './enums/ExpressLayerType';\nimport { AttributeNames } from './enums/AttributeNames';\nimport {\n  asErrorAndMessage,\n  getLayerMetadata,\n  getLayerPath,\n  isLayerIgnored,\n  storeLayerPath,\n  getActualMatchedRoute,\n  getConstructedRoute,\n} from './utils';\n/** @knipignore */\nimport { PACKAGE_NAME, PACKAGE_VERSION } from './version';\nimport {\n  InstrumentationBase,\n  InstrumentationNodeModuleDefinition,\n  isWrapped,\n  safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\nimport { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport {\n  ExpressLayer,\n  ExpressRouter,\n  kLayerPatched,\n  PatchedRequest,\n  _LAYERS_STORE_PROPERTY,\n} from './internal-types';\n\n/** Express instrumentation for OpenTelemetry */\nexport class ExpressInstrumentation extends InstrumentationBase<ExpressInstrumentationConfig> {\n  constructor(config: ExpressInstrumentationConfig = {}) {\n    super(PACKAGE_NAME, PACKAGE_VERSION, config);\n  }\n\n  init() {\n    return [\n      new InstrumentationNodeModuleDefinition(\n        'express',\n        ['>=4.0.0 <6'],\n        moduleExports => {\n          const isExpressWithRouterPrototype =\n            typeof moduleExports?.Router?.prototype?.route === 'function';\n          const routerProto = isExpressWithRouterPrototype\n            ? moduleExports.Router.prototype // Express v5\n            : moduleExports.Router; // Express v4\n          // patch express.Router.route\n          if (isWrapped(routerProto.route)) {\n            this._unwrap(routerProto, 'route');\n          }\n          this._wrap(routerProto, 'route', this._getRoutePatch());\n          // patch express.Router.use\n          if (isWrapped(routerProto.use)) {\n            this._unwrap(routerProto, 'use');\n          }\n          // eslint-disable-next-line @typescript-eslint/no-explicit-any\n          this._wrap(routerProto, 'use', this._getRouterUsePatch() as any);\n          // patch express.Application.use\n          if (isWrapped(moduleExports.application.use)) {\n            this._unwrap(moduleExports.application, 'use');\n          }\n          this._wrap(\n            moduleExports.application,\n            'use',\n            // eslint-disable-next-line @typescript-eslint/no-explicit-any\n            this._getAppUsePatch(isExpressWithRouterPrototype) as any\n          );\n          return moduleExports;\n        },\n        moduleExports => {\n          if (moduleExports === undefined) return;\n          const isExpressWithRouterPrototype =\n            typeof moduleExports?.Router?.prototype?.route === 'function';\n          const routerProto = isExpressWithRouterPrototype\n            ? moduleExports.Router.prototype\n            : moduleExports.Router;\n          this._unwrap(routerProto, 'route');\n          this._unwrap(routerProto, 'use');\n          this._unwrap(moduleExports.application, 'use');\n        }\n      ),\n    ];\n  }\n\n  /**\n   * Get the patch for Router.route function\n   */\n  private _getRoutePatch() {\n    const instrumentation = this;\n    return function (original: express.Router['route']) {\n      return function route_trace(\n        this: ExpressRouter,\n        ...args: Parameters<typeof original>\n      ) {\n        const route = original.apply(this, args);\n        const layer = this.stack[this.stack.length - 1] as ExpressLayer;\n        instrumentation._applyPatch(layer, getLayerPath(args));\n        return route;\n      };\n    };\n  }\n\n  /**\n   * Get the patch for Router.use function\n   */\n  private _getRouterUsePatch() {\n    const instrumentation = this;\n    return function (original: express.Router['use']) {\n      return function use(\n        this: express.Application,\n        ...args: Parameters<typeof original>\n      ) {\n        const route = original.apply(this, args);\n        const layer = this.stack[this.stack.length - 1] as ExpressLayer;\n        instrumentation._applyPatch(layer, getLayerPath(args));\n        return route;\n      };\n    };\n  }\n\n  /**\n   * Get the patch for Application.use function\n   */\n  private _getAppUsePatch(isExpressWithRouterPrototype: boolean) {\n    const instrumentation = this;\n    return function (original: express.Application['use']) {\n      return function use(\n        // `router` in express@5, `_router` in express@4.\n        this: { _router?: ExpressRouter; router?: ExpressRouter },\n        ...args: Parameters<typeof original>\n      ) {\n        // If we access app.router in express 4.x we trigger an assertion error.\n        // This property existed in v3, was removed in v4 and then re-added in v5.\n        const router = isExpressWithRouterPrototype\n          ? this.router\n          : this._router;\n        const route = original.apply(this, args);\n        if (router) {\n          const layer = router.stack[router.stack.length - 1];\n          instrumentation._applyPatch(layer, getLayerPath(args));\n        }\n        return route;\n      };\n    };\n  }\n\n  /** Patch each express layer to create span and propagate context */\n  private _applyPatch(\n    this: ExpressInstrumentation,\n    layer: ExpressLayer,\n    layerPath?: string\n  ) {\n    const instrumentation = this;\n    // avoid patching multiple times the same layer\n    if (layer[kLayerPatched] === true) return;\n    layer[kLayerPatched] = true;\n\n    this._wrap(layer, 'handle', original => {\n      // TODO: instrument error handlers\n      if (original.length === 4) return original;\n\n      const patched = function (\n        this: ExpressLayer,\n        req: PatchedRequest,\n        res: express.Response\n      ) {\n        const { isLayerPathStored } = storeLayerPath(req, layerPath);\n\n        const constructedRoute = getConstructedRoute(req);\n        const actualMatchedRoute = getActualMatchedRoute(req);\n\n        const attributes: Attributes = {\n          [ATTR_HTTP_ROUTE]: actualMatchedRoute,\n        };\n        const metadata = getLayerMetadata(constructedRoute, layer, layerPath);\n        const type = metadata.attributes[\n          AttributeNames.EXPRESS_TYPE\n        ] as ExpressLayerType;\n\n        const rpcMetadata = getRPCMetadata(context.active());\n        if (rpcMetadata?.type === RPCType.HTTP) {\n          rpcMetadata.route = actualMatchedRoute;\n        }\n\n        // verify against the config if the layer should be ignored\n        if (isLayerIgnored(metadata.name, type, instrumentation.getConfig())) {\n          if (type === ExpressLayerType.MIDDLEWARE) {\n            (req[_LAYERS_STORE_PROPERTY] as string[]).pop();\n          }\n          return original.apply(this, arguments);\n        }\n\n        if (trace.getSpan(context.active()) === undefined) {\n          return original.apply(this, arguments);\n        }\n\n        const spanName = instrumentation._getSpanName(\n          {\n            request: req,\n            layerType: type,\n            route: constructedRoute,\n          },\n          metadata.name\n        );\n        const span = instrumentation.tracer.startSpan(spanName, {\n          attributes: Object.assign(attributes, metadata.attributes),\n        });\n\n        const parentContext = context.active();\n        let currentContext = trace.setSpan(parentContext, span);\n\n        const { requestHook } = instrumentation.getConfig();\n        if (requestHook) {\n          safeExecuteInTheMiddle(\n            () =>\n              requestHook(span, {\n                request: req,\n                layerType: type,\n                route: constructedRoute,\n              }),\n            e => {\n              if (e) {\n                diag.error('express instrumentation: request hook failed', e);\n              }\n            },\n            true\n          );\n        }\n\n        let spanHasEnded = false;\n        // TODO: Fix router spans (getRouterPath does not work properly) to\n        // have useful names before removing this branch\n        if (\n          metadata.attributes[AttributeNames.EXPRESS_TYPE] ===\n          ExpressLayerType.ROUTER\n        ) {\n          span.end();\n          spanHasEnded = true;\n          currentContext = parentContext;\n        }\n        // listener for response.on('close')\n        const onResponseEnded = () => {\n          if (spanHasEnded === false) {\n            spanHasEnded = true;\n            span.end();\n          }\n        };\n\n        // verify we have a callback\n        const args = Array.from(arguments);\n        const callbackIdx = args.findIndex(arg => typeof arg === 'function');\n        if (callbackIdx >= 0) {\n          arguments[callbackIdx] = function () {\n            // express considers anything but an empty value, \"route\" or \"router\"\n            // passed to its callback to be an error\n            const maybeError = arguments[0];\n            const isError = ![undefined, null, 'route', 'router'].includes(\n              maybeError\n            );\n            if (!spanHasEnded && isError) {\n              const [error, message] = asErrorAndMessage(maybeError);\n              span.recordException(error);\n              span.setStatus({\n                code: SpanStatusCode.ERROR,\n                message,\n              });\n            }\n\n            if (spanHasEnded === false) {\n              spanHasEnded = true;\n              req.res?.removeListener('close', onResponseEnded);\n              span.end();\n            }\n            if (!(req.route && isError) && isLayerPathStored) {\n              (req[_LAYERS_STORE_PROPERTY] as string[]).pop();\n            }\n            const callback = args[callbackIdx] as Function;\n            // Preserve the active context (which may include baggage set by middleware)\n            // but restore the parent span to prevent sibling middleware spans\n            // from nesting under each other\n            const activeContext = context.active();\n            const parentSpan = trace.getSpan(parentContext);\n            const nextContext = parentSpan\n              ? trace.setSpan(activeContext, parentSpan)\n              : activeContext;\n            return context.bind(nextContext, callback).apply(this, arguments);\n          };\n        }\n\n        try {\n          return context.bind(currentContext, original).apply(this, arguments);\n        } catch (anyError) {\n          const [error, message] = asErrorAndMessage(anyError);\n          span.recordException(error);\n          span.setStatus({\n            code: SpanStatusCode.ERROR,\n            message,\n          });\n          throw anyError;\n        } finally {\n          /**\n           * At this point if the callback wasn't called, that means either the\n           * layer is asynchronous (so it will call the callback later on) or that\n           * the layer directly ends the http response, so we'll hook into the \"close\"\n           * event to handle the later case.\n           */\n          if (!spanHasEnded) {\n            res.once('close', onResponseEnded);\n          }\n        }\n      };\n\n      // `handle` isn't just a regular function in some cases. It also contains\n      // some properties holding metadata and state so we need to proxy them\n      // through through patched function\n      // ref: https://github.com/open-telemetry/opentelemetry-js-contrib/issues/1950\n      // Also some apps/libs do their own patching before OTEL and have these properties\n      // in the proptotype. So we use a `for...in` loop to get own properties and also\n      // any enumerable prop in the prototype chain\n      // ref: https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2271\n      for (const key in original) {\n        Object.defineProperty(patched, key, {\n          get() {\n            return original[key];\n          },\n          set(value) {\n            original[key] = value;\n          },\n        });\n      }\n      return patched;\n    });\n  }\n\n  _getSpanName(info: ExpressRequestInfo, defaultName: string) {\n    const { spanNameHook } = this.getConfig();\n\n    if (!(spanNameHook instanceof Function)) {\n      return defaultName;\n    }\n\n    try {\n      return spanNameHook(info, defaultName) ?? defaultName;\n    } catch (err) {\n      diag.error(\n        'express instrumentation: error calling span name rewrite hook',\n        err\n      );\n      return defaultName;\n    }\n  }\n}\n"]}