@sentry/node 9.36.0 → 9.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/build/cjs/debug-build.js.map +1 -1
  2. package/build/cjs/integrations/featureFlagShims/openFeature.js.map +1 -1
  3. package/build/cjs/integrations/fs.js.map +1 -1
  4. package/build/cjs/integrations/tracing/amqplib.js.map +1 -1
  5. package/build/cjs/integrations/tracing/connect.js.map +1 -1
  6. package/build/cjs/integrations/tracing/dataloader.js.map +1 -1
  7. package/build/cjs/integrations/tracing/express-v5/enums/AttributeNames.js.map +1 -1
  8. package/build/cjs/integrations/tracing/express-v5/enums/ExpressLayerType.js.map +1 -1
  9. package/build/cjs/integrations/tracing/express-v5/instrumentation.js.map +1 -1
  10. package/build/cjs/integrations/tracing/express-v5/internal-types.js.map +1 -1
  11. package/build/cjs/integrations/tracing/express-v5/utils.js.map +1 -1
  12. package/build/cjs/integrations/tracing/express.js.map +1 -1
  13. package/build/cjs/integrations/tracing/fastify/fastify-otel/index.js.map +1 -1
  14. package/build/cjs/integrations/tracing/fastify/index.js.map +1 -1
  15. package/build/cjs/integrations/tracing/fastify/v3/constants.js.map +1 -1
  16. package/build/cjs/integrations/tracing/fastify/v3/enums/AttributeNames.js.map +1 -1
  17. package/build/cjs/integrations/tracing/fastify/v3/instrumentation.js.map +1 -1
  18. package/build/cjs/integrations/tracing/fastify/v3/utils.js.map +1 -1
  19. package/build/cjs/integrations/tracing/genericPool.js.map +1 -1
  20. package/build/cjs/integrations/tracing/graphql.js.map +1 -1
  21. package/build/cjs/integrations/tracing/hapi/index.js.map +1 -1
  22. package/build/cjs/integrations/tracing/kafka.js.map +1 -1
  23. package/build/cjs/integrations/tracing/knex.js.map +1 -1
  24. package/build/cjs/integrations/tracing/koa.js.map +1 -1
  25. package/build/cjs/integrations/tracing/lrumemoizer.js.map +1 -1
  26. package/build/cjs/integrations/tracing/mongo.js.map +1 -1
  27. package/build/cjs/integrations/tracing/mongoose.js.map +1 -1
  28. package/build/cjs/integrations/tracing/mysql.js.map +1 -1
  29. package/build/cjs/integrations/tracing/mysql2.js.map +1 -1
  30. package/build/cjs/integrations/tracing/postgres.js.map +1 -1
  31. package/build/cjs/integrations/tracing/postgresjs.js.map +1 -1
  32. package/build/cjs/integrations/tracing/prisma.js.map +1 -1
  33. package/build/cjs/integrations/tracing/redis.js.map +1 -1
  34. package/build/cjs/integrations/tracing/tedious.js.map +1 -1
  35. package/build/cjs/integrations/tracing/vercelai/constants.js.map +1 -1
  36. package/build/cjs/integrations/tracing/vercelai/index.js.map +1 -1
  37. package/build/cjs/integrations/tracing/vercelai/instrumentation.js.map +1 -1
  38. package/build/cjs/preload.js.map +1 -1
  39. package/build/cjs/sdk/index.js.map +1 -1
  40. package/build/cjs/sdk/initOtel.js.map +1 -1
  41. package/build/cjs/utils/redisCache.js.map +1 -1
  42. package/build/esm/debug-build.js.map +1 -1
  43. package/build/esm/integrations/featureFlagShims/openFeature.js.map +1 -1
  44. package/build/esm/integrations/fs.js.map +1 -1
  45. package/build/esm/integrations/tracing/amqplib.js.map +1 -1
  46. package/build/esm/integrations/tracing/connect.js.map +1 -1
  47. package/build/esm/integrations/tracing/dataloader.js.map +1 -1
  48. package/build/esm/integrations/tracing/express-v5/enums/AttributeNames.js.map +1 -1
  49. package/build/esm/integrations/tracing/express-v5/enums/ExpressLayerType.js.map +1 -1
  50. package/build/esm/integrations/tracing/express-v5/instrumentation.js.map +1 -1
  51. package/build/esm/integrations/tracing/express-v5/internal-types.js.map +1 -1
  52. package/build/esm/integrations/tracing/express-v5/utils.js.map +1 -1
  53. package/build/esm/integrations/tracing/express.js.map +1 -1
  54. package/build/esm/integrations/tracing/fastify/fastify-otel/index.js.map +1 -1
  55. package/build/esm/integrations/tracing/fastify/index.js.map +1 -1
  56. package/build/esm/integrations/tracing/fastify/v3/constants.js.map +1 -1
  57. package/build/esm/integrations/tracing/fastify/v3/enums/AttributeNames.js.map +1 -1
  58. package/build/esm/integrations/tracing/fastify/v3/instrumentation.js.map +1 -1
  59. package/build/esm/integrations/tracing/fastify/v3/utils.js.map +1 -1
  60. package/build/esm/integrations/tracing/genericPool.js.map +1 -1
  61. package/build/esm/integrations/tracing/graphql.js.map +1 -1
  62. package/build/esm/integrations/tracing/hapi/index.js.map +1 -1
  63. package/build/esm/integrations/tracing/kafka.js.map +1 -1
  64. package/build/esm/integrations/tracing/knex.js.map +1 -1
  65. package/build/esm/integrations/tracing/koa.js.map +1 -1
  66. package/build/esm/integrations/tracing/lrumemoizer.js.map +1 -1
  67. package/build/esm/integrations/tracing/mongo.js.map +1 -1
  68. package/build/esm/integrations/tracing/mongoose.js.map +1 -1
  69. package/build/esm/integrations/tracing/mysql.js.map +1 -1
  70. package/build/esm/integrations/tracing/mysql2.js.map +1 -1
  71. package/build/esm/integrations/tracing/postgres.js.map +1 -1
  72. package/build/esm/integrations/tracing/postgresjs.js.map +1 -1
  73. package/build/esm/integrations/tracing/prisma.js.map +1 -1
  74. package/build/esm/integrations/tracing/redis.js.map +1 -1
  75. package/build/esm/integrations/tracing/tedious.js.map +1 -1
  76. package/build/esm/integrations/tracing/vercelai/constants.js.map +1 -1
  77. package/build/esm/integrations/tracing/vercelai/index.js.map +1 -1
  78. package/build/esm/integrations/tracing/vercelai/instrumentation.js.map +1 -1
  79. package/build/esm/package.json +1 -1
  80. package/build/esm/preload.js.map +1 -1
  81. package/build/esm/sdk/index.js.map +1 -1
  82. package/build/esm/sdk/initOtel.js.map +1 -1
  83. package/build/esm/utils/redisCache.js.map +1 -1
  84. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/express-v5/instrumentation.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/member-ordering */\n/* eslint-disable guard-for-in */\n/* eslint-disable @typescript-eslint/ban-types */\n/* eslint-disable prefer-rest-params */\n/* eslint-disable @typescript-eslint/no-this-alias */\n/* eslint-disable jsdoc/require-jsdoc */\n/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable @typescript-eslint/explicit-member-accessibility */\n\n/*\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 type { Attributes } from '@opentelemetry/api';\nimport { context, diag, SpanStatusCode, trace } from '@opentelemetry/api';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n isWrapped,\n safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\nimport { SEMATTRS_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport type * as express from 'express';\nimport { AttributeNames } from './enums/AttributeNames';\nimport { ExpressLayerType } from './enums/ExpressLayerType';\nimport type { ExpressLayer, ExpressRouter, PatchedRequest } from './internal-types';\nimport { _LAYERS_STORE_PROPERTY, kLayerPatched } from './internal-types';\nimport type { ExpressInstrumentationConfig, ExpressRequestInfo } from './types';\nimport { asErrorAndMessage, getLayerMetadata, getLayerPath, isLayerIgnored, storeLayerPath } from './utils';\n\nexport const PACKAGE_VERSION = '0.1.0';\nexport const PACKAGE_NAME = '@sentry/instrumentation-express-v5';\n\n/** Express instrumentation for OpenTelemetry */\nexport class ExpressInstrumentationV5 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 ['>=5.0.0'],\n moduleExports => this._setup(moduleExports),\n moduleExports => this._tearDown(moduleExports),\n ),\n ];\n }\n\n private _setup(moduleExports: any) {\n const routerProto = moduleExports.Router.prototype;\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 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(moduleExports.application, 'use', this._getAppUsePatch() as any);\n return moduleExports;\n }\n\n private _tearDown(moduleExports: any) {\n if (moduleExports === undefined) return;\n const routerProto = moduleExports.Router.prototype;\n this._unwrap(routerProto, 'route');\n this._unwrap(routerProto, 'use');\n this._unwrap(moduleExports.application, 'use');\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(this: ExpressRouter, ...args: Parameters<typeof original>) {\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(this: express.Application, ...args: Parameters<typeof original>) {\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() {\n const instrumentation = this;\n return function (original: express.Application['use']) {\n return function use(\n // In express 5.x the router is stored in `router` whereas in 4.x it's stored in `_router`\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 = this.router;\n const route = original.apply(this, args);\n if (router) {\n const layer = router.stack[router.stack.length - 1] as ExpressLayer;\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(this: ExpressInstrumentationV5, layer: ExpressLayer, layerPath?: string) {\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 (this: ExpressLayer, req: PatchedRequest, res: express.Response) {\n storeLayerPath(req, layerPath);\n const route = (req[_LAYERS_STORE_PROPERTY] as string[])\n .filter(path => path !== '/' && path !== '/*')\n .join('')\n // remove duplicate slashes to normalize route\n .replace(/\\/{2,}/g, '/');\n\n const actualRoute = route.length > 0 ? route : undefined;\n\n const attributes: Attributes = {\n // eslint-disable-next-line deprecation/deprecation\n [SEMATTRS_HTTP_ROUTE]: actualRoute,\n };\n const metadata = getLayerMetadata(route, layer, layerPath);\n const type = metadata.attributes[AttributeNames.EXPRESS_TYPE] as ExpressLayerType;\n\n const rpcMetadata = getRPCMetadata(context.active());\n if (rpcMetadata?.type === RPCType.HTTP) {\n rpcMetadata.route = actualRoute;\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,\n },\n metadata.name,\n );\n const span = instrumentation.tracer.startSpan(spanName, {\n attributes: Object.assign(attributes, metadata.attributes),\n });\n\n const { requestHook } = instrumentation.getConfig();\n if (requestHook) {\n safeExecuteInTheMiddle(\n () =>\n requestHook(span, {\n request: req,\n layerType: type,\n route,\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 if (metadata.attributes[AttributeNames.EXPRESS_TYPE] !== ExpressLayerType.MIDDLEWARE) {\n span.end();\n spanHasEnded = true;\n }\n // listener for response.on('finish')\n const onResponseFinish = () => {\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(maybeError);\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('finish', onResponseFinish);\n span.end();\n }\n if (!(req.route && isError)) {\n (req[_LAYERS_STORE_PROPERTY] as string[]).pop();\n }\n const callback = args[callbackIdx] as Function;\n return callback.apply(this, arguments);\n };\n }\n\n try {\n return 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 end the http response, so we'll hook into the \"finish\"\n * event to handle the later case.\n */\n if (!spanHasEnded) {\n res.once('finish', onResponseFinish);\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('express instrumentation: error calling span name rewrite hook', err);\n return defaultName;\n }\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/express-v5/instrumentation.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/member-ordering */\n/* eslint-disable guard-for-in */\n/* eslint-disable @typescript-eslint/ban-types */\n/* eslint-disable prefer-rest-params */\n/* eslint-disable @typescript-eslint/no-this-alias */\n/* eslint-disable jsdoc/require-jsdoc */\n/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable @typescript-eslint/explicit-member-accessibility */\n\n/*\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 type { Attributes } from '@opentelemetry/api';\nimport { context, diag, SpanStatusCode, trace } from '@opentelemetry/api';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n isWrapped,\n safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\nimport { SEMATTRS_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport type * as express from 'express';\nimport { AttributeNames } from './enums/AttributeNames';\nimport { ExpressLayerType } from './enums/ExpressLayerType';\nimport type { ExpressLayer, ExpressRouter, PatchedRequest } from './internal-types';\nimport { _LAYERS_STORE_PROPERTY, kLayerPatched } from './internal-types';\nimport type { ExpressInstrumentationConfig, ExpressRequestInfo } from './types';\nimport { asErrorAndMessage, getLayerMetadata, getLayerPath, isLayerIgnored, storeLayerPath } from './utils';\n\nexport const PACKAGE_VERSION = '0.1.0';\nexport const PACKAGE_NAME = '@sentry/instrumentation-express-v5';\n\n/** Express instrumentation for OpenTelemetry */\nexport class ExpressInstrumentationV5 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 ['>=5.0.0'],\n moduleExports => this._setup(moduleExports),\n moduleExports => this._tearDown(moduleExports),\n ),\n ];\n }\n\n private _setup(moduleExports: any) {\n const routerProto = moduleExports.Router.prototype;\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 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(moduleExports.application, 'use', this._getAppUsePatch() as any);\n return moduleExports;\n }\n\n private _tearDown(moduleExports: any) {\n if (moduleExports === undefined) return;\n const routerProto = moduleExports.Router.prototype;\n this._unwrap(routerProto, 'route');\n this._unwrap(routerProto, 'use');\n this._unwrap(moduleExports.application, 'use');\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(this: ExpressRouter, ...args: Parameters<typeof original>) {\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(this: express.Application, ...args: Parameters<typeof original>) {\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() {\n const instrumentation = this;\n return function (original: express.Application['use']) {\n return function use(\n // In express 5.x the router is stored in `router` whereas in 4.x it's stored in `_router`\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 = this.router;\n const route = original.apply(this, args);\n if (router) {\n const layer = router.stack[router.stack.length - 1] as ExpressLayer;\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(this: ExpressInstrumentationV5, layer: ExpressLayer, layerPath?: string) {\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 (this: ExpressLayer, req: PatchedRequest, res: express.Response) {\n storeLayerPath(req, layerPath);\n const route = (req[_LAYERS_STORE_PROPERTY] as string[])\n .filter(path => path !== '/' && path !== '/*')\n .join('')\n // remove duplicate slashes to normalize route\n .replace(/\\/{2,}/g, '/');\n\n const actualRoute = route.length > 0 ? route : undefined;\n\n const attributes: Attributes = {\n // eslint-disable-next-line deprecation/deprecation\n [SEMATTRS_HTTP_ROUTE]: actualRoute,\n };\n const metadata = getLayerMetadata(route, layer, layerPath);\n const type = metadata.attributes[AttributeNames.EXPRESS_TYPE] as ExpressLayerType;\n\n const rpcMetadata = getRPCMetadata(context.active());\n if (rpcMetadata?.type === RPCType.HTTP) {\n rpcMetadata.route = actualRoute;\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,\n },\n metadata.name,\n );\n const span = instrumentation.tracer.startSpan(spanName, {\n attributes: Object.assign(attributes, metadata.attributes),\n });\n\n const { requestHook } = instrumentation.getConfig();\n if (requestHook) {\n safeExecuteInTheMiddle(\n () =>\n requestHook(span, {\n request: req,\n layerType: type,\n route,\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 if (metadata.attributes[AttributeNames.EXPRESS_TYPE] !== ExpressLayerType.MIDDLEWARE) {\n span.end();\n spanHasEnded = true;\n }\n // listener for response.on('finish')\n const onResponseFinish = () => {\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(maybeError);\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('finish', onResponseFinish);\n span.end();\n }\n if (!(req.route && isError)) {\n (req[_LAYERS_STORE_PROPERTY] as string[]).pop();\n }\n const callback = args[callbackIdx] as Function;\n return callback.apply(this, arguments);\n };\n }\n\n try {\n return 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 end the http response, so we'll hook into the \"finish\"\n * event to handle the later case.\n */\n if (!spanHasEnded) {\n res.once('finish', onResponseFinish);\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('express instrumentation: error calling span name rewrite hook', err);\n return defaultName;\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"internal-types.js","sources":["../../../../../src/integrations/tracing/express-v5/internal-types.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/ban-types */\n\n/*\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 type { Request } from 'express';\n\n/**\n * This symbol is used to mark express layer as being already instrumented\n * since its possible to use a given layer multiple times (ex: middlewares)\n */\nexport const kLayerPatched: unique symbol = Symbol('express-layer-patched');\n\n/**\n * This const define where on the `request` object the Instrumentation will mount the\n * current stack of express layer.\n *\n * It is necessary because express doesn't store the different layers\n * (ie: middleware, router etc) that it called to get to the current layer.\n * Given that, the only way to know the route of a given layer is to\n * store the path of where each previous layer has been mounted.\n *\n * ex: bodyParser > auth middleware > /users router > get /:id\n * in this case the stack would be: [\"/users\", \"/:id\"]\n *\n * ex2: bodyParser > /api router > /v1 router > /users router > get /:id\n * stack: [\"/api\", \"/v1\", \"/users\", \":id\"]\n *\n */\nexport const _LAYERS_STORE_PROPERTY = '__ot_middlewares';\n\nexport type PatchedRequest = {\n [_LAYERS_STORE_PROPERTY]?: string[];\n} & Request;\nexport type PathParams = string | RegExp | Array<string | RegExp>;\n\n// https://github.com/expressjs/express/blob/main/lib/router/index.js#L53\nexport type ExpressRouter = {\n stack: ExpressLayer[];\n};\n\n// https://github.com/expressjs/express/blob/main/lib/router/layer.js#L33\nexport type ExpressLayer = {\n handle: Function & Record<string, any>;\n [kLayerPatched]?: boolean;\n name: string;\n path: string;\n route?: ExpressLayer;\n};\n"],"names":[],"mappings":"AAqBA;AACA;AACA;AACA;MACa,aAAa,GAAkB,MAAM,CAAC,uBAAuB;;AAE1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,sBAAuB,GAAE;;;;"}
1
+ {"version":3,"file":"internal-types.js","sources":["../../../../../src/integrations/tracing/express-v5/internal-types.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/ban-types */\n\n/*\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 type { Request } from 'express';\n\n/**\n * This symbol is used to mark express layer as being already instrumented\n * since its possible to use a given layer multiple times (ex: middlewares)\n */\nexport const kLayerPatched: unique symbol = Symbol('express-layer-patched');\n\n/**\n * This const define where on the `request` object the Instrumentation will mount the\n * current stack of express layer.\n *\n * It is necessary because express doesn't store the different layers\n * (ie: middleware, router etc) that it called to get to the current layer.\n * Given that, the only way to know the route of a given layer is to\n * store the path of where each previous layer has been mounted.\n *\n * ex: bodyParser > auth middleware > /users router > get /:id\n * in this case the stack would be: [\"/users\", \"/:id\"]\n *\n * ex2: bodyParser > /api router > /v1 router > /users router > get /:id\n * stack: [\"/api\", \"/v1\", \"/users\", \":id\"]\n *\n */\nexport const _LAYERS_STORE_PROPERTY = '__ot_middlewares';\n\nexport type PatchedRequest = {\n [_LAYERS_STORE_PROPERTY]?: string[];\n} & Request;\nexport type PathParams = string | RegExp | Array<string | RegExp>;\n\n// https://github.com/expressjs/express/blob/main/lib/router/index.js#L53\nexport type ExpressRouter = {\n stack: ExpressLayer[];\n};\n\n// https://github.com/expressjs/express/blob/main/lib/router/layer.js#L33\nexport type ExpressLayer = {\n handle: Function & Record<string, any>;\n [kLayerPatched]?: boolean;\n name: string;\n path: string;\n route?: ExpressLayer;\n};\n"],"names":[],"mappings":"AAqBA;AACA;AACA;AACA;MACa,aAAa,GAAkB,MAAM,CAAC,uBAAuB;;AAE1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,sBAAA,GAAyB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../../../src/integrations/tracing/express-v5/utils.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-non-null-assertion */\n/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n\n/*\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 type { Attributes } from '@opentelemetry/api';\nimport { AttributeNames } from './enums/AttributeNames';\nimport { ExpressLayerType } from './enums/ExpressLayerType';\nimport type { ExpressLayer, PatchedRequest } from './internal-types';\nimport { _LAYERS_STORE_PROPERTY } from './internal-types';\nimport type { ExpressInstrumentationConfig, IgnoreMatcher, LayerPathSegment } from './types';\n\n/**\n * Store layers path in the request to be able to construct route later\n * @param request The request where\n * @param [value] the value to push into the array\n */\nexport const storeLayerPath = (request: PatchedRequest, value?: string): void => {\n if (Array.isArray(request[_LAYERS_STORE_PROPERTY]) === false) {\n Object.defineProperty(request, _LAYERS_STORE_PROPERTY, {\n enumerable: false,\n value: [],\n });\n }\n if (value === undefined) return;\n (request[_LAYERS_STORE_PROPERTY] as string[]).push(value);\n};\n\n/**\n * Recursively search the router path from layer stack\n * @param path The path to reconstruct\n * @param layer The layer to reconstruct from\n * @returns The reconstructed path\n */\nexport const getRouterPath = (path: string, layer: ExpressLayer): string => {\n const stackLayer = layer.handle?.stack?.[0];\n\n if (stackLayer?.route?.path) {\n return `${path}${stackLayer.route.path}`;\n }\n\n if (stackLayer?.handle?.stack) {\n return getRouterPath(path, stackLayer);\n }\n\n return path;\n};\n\n/**\n * Parse express layer context to retrieve a name and attributes.\n * @param route The route of the layer\n * @param layer Express layer\n * @param [layerPath] if present, the path on which the layer has been mounted\n */\nexport const getLayerMetadata = (\n route: string,\n layer: ExpressLayer,\n layerPath?: string,\n): {\n attributes: Attributes;\n name: string;\n} => {\n if (layer.name === 'router') {\n const maybeRouterPath = getRouterPath('', layer);\n const extractedRouterPath = maybeRouterPath ? maybeRouterPath : layerPath || route || '/';\n\n return {\n attributes: {\n [AttributeNames.EXPRESS_NAME]: extractedRouterPath,\n [AttributeNames.EXPRESS_TYPE]: ExpressLayerType.ROUTER,\n },\n name: `router - ${extractedRouterPath}`,\n };\n } else if (layer.name === 'bound dispatch' || layer.name === 'handle') {\n return {\n attributes: {\n [AttributeNames.EXPRESS_NAME]: (route || layerPath) ?? 'request handler',\n [AttributeNames.EXPRESS_TYPE]: ExpressLayerType.REQUEST_HANDLER,\n },\n name: `request handler${layer.path ? ` - ${route || layerPath}` : ''}`,\n };\n } else {\n return {\n attributes: {\n [AttributeNames.EXPRESS_NAME]: layer.name,\n [AttributeNames.EXPRESS_TYPE]: ExpressLayerType.MIDDLEWARE,\n },\n name: `middleware - ${layer.name}`,\n };\n }\n};\n\n/**\n * Check whether the given obj match pattern\n * @param constant e.g URL of request\n * @param obj obj to inspect\n * @param pattern Match pattern\n */\nconst satisfiesPattern = (constant: string, pattern: IgnoreMatcher): boolean => {\n if (typeof pattern === 'string') {\n return pattern === constant;\n } else if (pattern instanceof RegExp) {\n return pattern.test(constant);\n } else if (typeof pattern === 'function') {\n return pattern(constant);\n } else {\n throw new TypeError('Pattern is in unsupported datatype');\n }\n};\n\n/**\n * Check whether the given request is ignored by configuration\n * It will not re-throw exceptions from `list` provided by the client\n * @param constant e.g URL of request\n * @param [list] List of ignore patterns\n * @param [onException] callback for doing something when an exception has\n * occurred\n */\nexport const isLayerIgnored = (\n name: string,\n type: ExpressLayerType,\n config?: ExpressInstrumentationConfig,\n): boolean => {\n if (Array.isArray(config?.ignoreLayersType) && config?.ignoreLayersType?.includes(type)) {\n return true;\n }\n if (Array.isArray(config?.ignoreLayers) === false) return false;\n try {\n for (const pattern of config!.ignoreLayers!) {\n if (satisfiesPattern(name, pattern)) {\n return true;\n }\n }\n } catch (e) {\n /* catch block */\n }\n\n return false;\n};\n\n/**\n * Converts a user-provided error value into an error and error message pair\n *\n * @param error - User-provided error value\n * @returns Both an Error or string representation of the value and an error message\n */\nexport const asErrorAndMessage = (error: unknown): [error: string | Error, message: string] =>\n error instanceof Error ? [error, error.message] : [String(error), String(error)];\n\n/**\n * Extracts the layer path from the route arguments\n *\n * @param args - Arguments of the route\n * @returns The layer path\n */\nexport const getLayerPath = (args: [LayerPathSegment | LayerPathSegment[], ...unknown[]]): string | undefined => {\n const firstArg = args[0];\n\n if (Array.isArray(firstArg)) {\n return firstArg.map(arg => extractLayerPathSegment(arg) || '').join(',');\n }\n\n return extractLayerPathSegment(firstArg);\n};\n\nconst extractLayerPathSegment = (arg: LayerPathSegment) => {\n if (typeof arg === 'string') {\n return arg;\n }\n\n if (arg instanceof RegExp || typeof arg === 'number') {\n return arg.toString();\n }\n\n return;\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["../../../../../src/integrations/tracing/express-v5/utils.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-non-null-assertion */\n/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n\n/*\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 type { Attributes } from '@opentelemetry/api';\nimport { AttributeNames } from './enums/AttributeNames';\nimport { ExpressLayerType } from './enums/ExpressLayerType';\nimport type { ExpressLayer, PatchedRequest } from './internal-types';\nimport { _LAYERS_STORE_PROPERTY } from './internal-types';\nimport type { ExpressInstrumentationConfig, IgnoreMatcher, LayerPathSegment } from './types';\n\n/**\n * Store layers path in the request to be able to construct route later\n * @param request The request where\n * @param [value] the value to push into the array\n */\nexport const storeLayerPath = (request: PatchedRequest, value?: string): void => {\n if (Array.isArray(request[_LAYERS_STORE_PROPERTY]) === false) {\n Object.defineProperty(request, _LAYERS_STORE_PROPERTY, {\n enumerable: false,\n value: [],\n });\n }\n if (value === undefined) return;\n (request[_LAYERS_STORE_PROPERTY] as string[]).push(value);\n};\n\n/**\n * Recursively search the router path from layer stack\n * @param path The path to reconstruct\n * @param layer The layer to reconstruct from\n * @returns The reconstructed path\n */\nexport const getRouterPath = (path: string, layer: ExpressLayer): string => {\n const stackLayer = layer.handle?.stack?.[0];\n\n if (stackLayer?.route?.path) {\n return `${path}${stackLayer.route.path}`;\n }\n\n if (stackLayer?.handle?.stack) {\n return getRouterPath(path, stackLayer);\n }\n\n return path;\n};\n\n/**\n * Parse express layer context to retrieve a name and attributes.\n * @param route The route of the layer\n * @param layer Express layer\n * @param [layerPath] if present, the path on which the layer has been mounted\n */\nexport const getLayerMetadata = (\n route: string,\n layer: ExpressLayer,\n layerPath?: string,\n): {\n attributes: Attributes;\n name: string;\n} => {\n if (layer.name === 'router') {\n const maybeRouterPath = getRouterPath('', layer);\n const extractedRouterPath = maybeRouterPath ? maybeRouterPath : layerPath || route || '/';\n\n return {\n attributes: {\n [AttributeNames.EXPRESS_NAME]: extractedRouterPath,\n [AttributeNames.EXPRESS_TYPE]: ExpressLayerType.ROUTER,\n },\n name: `router - ${extractedRouterPath}`,\n };\n } else if (layer.name === 'bound dispatch' || layer.name === 'handle') {\n return {\n attributes: {\n [AttributeNames.EXPRESS_NAME]: (route || layerPath) ?? 'request handler',\n [AttributeNames.EXPRESS_TYPE]: ExpressLayerType.REQUEST_HANDLER,\n },\n name: `request handler${layer.path ? ` - ${route || layerPath}` : ''}`,\n };\n } else {\n return {\n attributes: {\n [AttributeNames.EXPRESS_NAME]: layer.name,\n [AttributeNames.EXPRESS_TYPE]: ExpressLayerType.MIDDLEWARE,\n },\n name: `middleware - ${layer.name}`,\n };\n }\n};\n\n/**\n * Check whether the given obj match pattern\n * @param constant e.g URL of request\n * @param obj obj to inspect\n * @param pattern Match pattern\n */\nconst satisfiesPattern = (constant: string, pattern: IgnoreMatcher): boolean => {\n if (typeof pattern === 'string') {\n return pattern === constant;\n } else if (pattern instanceof RegExp) {\n return pattern.test(constant);\n } else if (typeof pattern === 'function') {\n return pattern(constant);\n } else {\n throw new TypeError('Pattern is in unsupported datatype');\n }\n};\n\n/**\n * Check whether the given request is ignored by configuration\n * It will not re-throw exceptions from `list` provided by the client\n * @param constant e.g URL of request\n * @param [list] List of ignore patterns\n * @param [onException] callback for doing something when an exception has\n * occurred\n */\nexport const isLayerIgnored = (\n name: string,\n type: ExpressLayerType,\n config?: ExpressInstrumentationConfig,\n): boolean => {\n if (Array.isArray(config?.ignoreLayersType) && config?.ignoreLayersType?.includes(type)) {\n return true;\n }\n if (Array.isArray(config?.ignoreLayers) === false) return false;\n try {\n for (const pattern of config!.ignoreLayers!) {\n if (satisfiesPattern(name, pattern)) {\n return true;\n }\n }\n } catch (e) {\n /* catch block */\n }\n\n return false;\n};\n\n/**\n * Converts a user-provided error value into an error and error message pair\n *\n * @param error - User-provided error value\n * @returns Both an Error or string representation of the value and an error message\n */\nexport const asErrorAndMessage = (error: unknown): [error: string | Error, message: string] =>\n error instanceof Error ? [error, error.message] : [String(error), String(error)];\n\n/**\n * Extracts the layer path from the route arguments\n *\n * @param args - Arguments of the route\n * @returns The layer path\n */\nexport const getLayerPath = (args: [LayerPathSegment | LayerPathSegment[], ...unknown[]]): string | undefined => {\n const firstArg = args[0];\n\n if (Array.isArray(firstArg)) {\n return firstArg.map(arg => extractLayerPathSegment(arg) || '').join(',');\n }\n\n return extractLayerPathSegment(firstArg);\n};\n\nconst extractLayerPathSegment = (arg: LayerPathSegment) => {\n if (typeof arg === 'string') {\n return arg;\n }\n\n if (arg instanceof RegExp || typeof arg === 'number') {\n return arg.toString();\n }\n\n return;\n};\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"express.js","sources":["../../../../src/integrations/tracing/express.ts"],"sourcesContent":["import type * as http from 'node:http';\nimport type { Span } from '@opentelemetry/api';\nimport type { ExpressRequestInfo } from '@opentelemetry/instrumentation-express';\nimport { ExpressInstrumentation } from '@opentelemetry/instrumentation-express';\nimport type { IntegrationFn } from '@sentry/core';\nimport {\n captureException,\n defineIntegration,\n getDefaultIsolationScope,\n getIsolationScope,\n httpRequestToRequestData,\n logger,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n spanToJSON,\n} from '@sentry/core';\nimport { addOriginToSpan, ensureIsWrapped, generateInstrumentOnce } from '@sentry/node-core';\nimport { DEBUG_BUILD } from '../../debug-build';\nimport { ExpressInstrumentationV5 } from './express-v5/instrumentation';\n\nconst INTEGRATION_NAME = 'Express';\nconst INTEGRATION_NAME_V5 = 'Express-V5';\n\nfunction requestHook(span: Span): void {\n addOriginToSpan(span, 'auto.http.otel.express');\n\n const attributes = spanToJSON(span).data;\n // this is one of: middleware, request_handler, router\n const type = attributes['express.type'];\n\n if (type) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, `${type}.express`);\n }\n\n // Also update the name, we don't need to \"middleware - \" prefix\n const name = attributes['express.name'];\n if (typeof name === 'string') {\n span.updateName(name);\n }\n}\n\nfunction spanNameHook(info: ExpressRequestInfo<unknown>, defaultName: string): string {\n if (getIsolationScope() === getDefaultIsolationScope()) {\n DEBUG_BUILD && logger.warn('Isolation scope is still default isolation scope - skipping setting transactionName');\n return defaultName;\n }\n if (info.layerType === 'request_handler') {\n // type cast b/c Otel unfortunately types info.request as any :(\n const req = info.request as { method?: string };\n const method = req.method ? req.method.toUpperCase() : 'GET';\n getIsolationScope().setTransactionName(`${method} ${info.route}`);\n }\n return defaultName;\n}\n\nexport const instrumentExpress = generateInstrumentOnce(\n INTEGRATION_NAME,\n () =>\n new ExpressInstrumentation({\n requestHook: span => requestHook(span),\n spanNameHook: (info, defaultName) => spanNameHook(info, defaultName),\n }),\n);\n\nexport const instrumentExpressV5 = generateInstrumentOnce(\n INTEGRATION_NAME_V5,\n () =>\n new ExpressInstrumentationV5({\n requestHook: span => requestHook(span),\n spanNameHook: (info, defaultName) => spanNameHook(info, defaultName),\n }),\n);\n\nconst _expressIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentExpress();\n instrumentExpressV5();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for [Express](https://expressjs.com/).\n *\n * If you also want to capture errors, you need to call `setupExpressErrorHandler(app)` after you set up your Express server.\n *\n * For more information, see the [express documentation](https://docs.sentry.io/platforms/javascript/guides/express/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.expressIntegration()],\n * })\n * ```\n */\nexport const expressIntegration = defineIntegration(_expressIntegration);\n\ninterface MiddlewareError extends Error {\n status?: number | string;\n statusCode?: number | string;\n status_code?: number | string;\n output?: {\n statusCode?: number | string;\n };\n}\n\ntype ExpressMiddleware = (req: http.IncomingMessage, res: http.ServerResponse, next: () => void) => void;\n\ntype ExpressErrorMiddleware = (\n error: MiddlewareError,\n req: http.IncomingMessage,\n res: http.ServerResponse,\n next: (error: MiddlewareError) => void,\n) => void;\n\ninterface ExpressHandlerOptions {\n /**\n * Callback method deciding whether error should be captured and sent to Sentry\n * @param error Captured middleware error\n */\n shouldHandleError?(this: void, error: MiddlewareError): boolean;\n}\n\n/**\n * An Express-compatible error handler.\n */\nexport function expressErrorHandler(options?: ExpressHandlerOptions): ExpressErrorMiddleware {\n return function sentryErrorMiddleware(\n error: MiddlewareError,\n request: http.IncomingMessage,\n res: http.ServerResponse,\n next: (error: MiddlewareError) => void,\n ): void {\n const normalizedRequest = httpRequestToRequestData(request);\n // Ensure we use the express-enhanced request here, instead of the plain HTTP one\n // When an error happens, the `expressRequestHandler` middleware does not run, so we set it here too\n getIsolationScope().setSDKProcessingMetadata({ normalizedRequest });\n\n const shouldHandleError = options?.shouldHandleError || defaultShouldHandleError;\n\n if (shouldHandleError(error)) {\n const eventId = captureException(error, { mechanism: { type: 'middleware', handled: false } });\n (res as { sentry?: string }).sentry = eventId;\n }\n\n next(error);\n };\n}\n\nfunction expressRequestHandler(): ExpressMiddleware {\n return function sentryRequestMiddleware(\n request: http.IncomingMessage,\n _res: http.ServerResponse,\n next: () => void,\n ): void {\n const normalizedRequest = httpRequestToRequestData(request);\n // Ensure we use the express-enhanced request here, instead of the plain HTTP one\n getIsolationScope().setSDKProcessingMetadata({ normalizedRequest });\n\n next();\n };\n}\n\n/**\n * Add an Express error handler to capture errors to Sentry.\n *\n * The error handler must be before any other middleware and after all controllers.\n *\n * @param app The Express instances\n * @param options {ExpressHandlerOptions} Configuration options for the handler\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n * const express = require(\"express\");\n *\n * const app = express();\n *\n * // Add your routes, etc.\n *\n * // Add this after all routes,\n * // but before any and other error-handling middlewares are defined\n * Sentry.setupExpressErrorHandler(app);\n *\n * app.listen(3000);\n * ```\n */\nexport function setupExpressErrorHandler(\n app: { use: (middleware: ExpressMiddleware | ExpressErrorMiddleware) => unknown },\n options?: ExpressHandlerOptions,\n): void {\n app.use(expressRequestHandler());\n app.use(expressErrorHandler(options));\n ensureIsWrapped(app.use, 'express');\n}\n\nfunction getStatusCodeFromResponse(error: MiddlewareError): number {\n const statusCode = error.status || error.statusCode || error.status_code || error.output?.statusCode;\n return statusCode ? parseInt(statusCode as string, 10) : 500;\n}\n\n/** Returns true if response code is internal server error */\nfunction defaultShouldHandleError(error: MiddlewareError): boolean {\n const status = getStatusCodeFromResponse(error);\n return status >= 500;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"express.js","sources":["../../../../src/integrations/tracing/express.ts"],"sourcesContent":["import type * as http from 'node:http';\nimport type { Span } from '@opentelemetry/api';\nimport type { ExpressRequestInfo } from '@opentelemetry/instrumentation-express';\nimport { ExpressInstrumentation } from '@opentelemetry/instrumentation-express';\nimport type { IntegrationFn } from '@sentry/core';\nimport {\n captureException,\n defineIntegration,\n getDefaultIsolationScope,\n getIsolationScope,\n httpRequestToRequestData,\n logger,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n spanToJSON,\n} from '@sentry/core';\nimport { addOriginToSpan, ensureIsWrapped, generateInstrumentOnce } from '@sentry/node-core';\nimport { DEBUG_BUILD } from '../../debug-build';\nimport { ExpressInstrumentationV5 } from './express-v5/instrumentation';\n\nconst INTEGRATION_NAME = 'Express';\nconst INTEGRATION_NAME_V5 = 'Express-V5';\n\nfunction requestHook(span: Span): void {\n addOriginToSpan(span, 'auto.http.otel.express');\n\n const attributes = spanToJSON(span).data;\n // this is one of: middleware, request_handler, router\n const type = attributes['express.type'];\n\n if (type) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, `${type}.express`);\n }\n\n // Also update the name, we don't need to \"middleware - \" prefix\n const name = attributes['express.name'];\n if (typeof name === 'string') {\n span.updateName(name);\n }\n}\n\nfunction spanNameHook(info: ExpressRequestInfo<unknown>, defaultName: string): string {\n if (getIsolationScope() === getDefaultIsolationScope()) {\n DEBUG_BUILD && logger.warn('Isolation scope is still default isolation scope - skipping setting transactionName');\n return defaultName;\n }\n if (info.layerType === 'request_handler') {\n // type cast b/c Otel unfortunately types info.request as any :(\n const req = info.request as { method?: string };\n const method = req.method ? req.method.toUpperCase() : 'GET';\n getIsolationScope().setTransactionName(`${method} ${info.route}`);\n }\n return defaultName;\n}\n\nexport const instrumentExpress = generateInstrumentOnce(\n INTEGRATION_NAME,\n () =>\n new ExpressInstrumentation({\n requestHook: span => requestHook(span),\n spanNameHook: (info, defaultName) => spanNameHook(info, defaultName),\n }),\n);\n\nexport const instrumentExpressV5 = generateInstrumentOnce(\n INTEGRATION_NAME_V5,\n () =>\n new ExpressInstrumentationV5({\n requestHook: span => requestHook(span),\n spanNameHook: (info, defaultName) => spanNameHook(info, defaultName),\n }),\n);\n\nconst _expressIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentExpress();\n instrumentExpressV5();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for [Express](https://expressjs.com/).\n *\n * If you also want to capture errors, you need to call `setupExpressErrorHandler(app)` after you set up your Express server.\n *\n * For more information, see the [express documentation](https://docs.sentry.io/platforms/javascript/guides/express/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.expressIntegration()],\n * })\n * ```\n */\nexport const expressIntegration = defineIntegration(_expressIntegration);\n\ninterface MiddlewareError extends Error {\n status?: number | string;\n statusCode?: number | string;\n status_code?: number | string;\n output?: {\n statusCode?: number | string;\n };\n}\n\ntype ExpressMiddleware = (req: http.IncomingMessage, res: http.ServerResponse, next: () => void) => void;\n\ntype ExpressErrorMiddleware = (\n error: MiddlewareError,\n req: http.IncomingMessage,\n res: http.ServerResponse,\n next: (error: MiddlewareError) => void,\n) => void;\n\ninterface ExpressHandlerOptions {\n /**\n * Callback method deciding whether error should be captured and sent to Sentry\n * @param error Captured middleware error\n */\n shouldHandleError?(this: void, error: MiddlewareError): boolean;\n}\n\n/**\n * An Express-compatible error handler.\n */\nexport function expressErrorHandler(options?: ExpressHandlerOptions): ExpressErrorMiddleware {\n return function sentryErrorMiddleware(\n error: MiddlewareError,\n request: http.IncomingMessage,\n res: http.ServerResponse,\n next: (error: MiddlewareError) => void,\n ): void {\n const normalizedRequest = httpRequestToRequestData(request);\n // Ensure we use the express-enhanced request here, instead of the plain HTTP one\n // When an error happens, the `expressRequestHandler` middleware does not run, so we set it here too\n getIsolationScope().setSDKProcessingMetadata({ normalizedRequest });\n\n const shouldHandleError = options?.shouldHandleError || defaultShouldHandleError;\n\n if (shouldHandleError(error)) {\n const eventId = captureException(error, { mechanism: { type: 'middleware', handled: false } });\n (res as { sentry?: string }).sentry = eventId;\n }\n\n next(error);\n };\n}\n\nfunction expressRequestHandler(): ExpressMiddleware {\n return function sentryRequestMiddleware(\n request: http.IncomingMessage,\n _res: http.ServerResponse,\n next: () => void,\n ): void {\n const normalizedRequest = httpRequestToRequestData(request);\n // Ensure we use the express-enhanced request here, instead of the plain HTTP one\n getIsolationScope().setSDKProcessingMetadata({ normalizedRequest });\n\n next();\n };\n}\n\n/**\n * Add an Express error handler to capture errors to Sentry.\n *\n * The error handler must be before any other middleware and after all controllers.\n *\n * @param app The Express instances\n * @param options {ExpressHandlerOptions} Configuration options for the handler\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n * const express = require(\"express\");\n *\n * const app = express();\n *\n * // Add your routes, etc.\n *\n * // Add this after all routes,\n * // but before any and other error-handling middlewares are defined\n * Sentry.setupExpressErrorHandler(app);\n *\n * app.listen(3000);\n * ```\n */\nexport function setupExpressErrorHandler(\n app: { use: (middleware: ExpressMiddleware | ExpressErrorMiddleware) => unknown },\n options?: ExpressHandlerOptions,\n): void {\n app.use(expressRequestHandler());\n app.use(expressErrorHandler(options));\n ensureIsWrapped(app.use, 'express');\n}\n\nfunction getStatusCodeFromResponse(error: MiddlewareError): number {\n const statusCode = error.status || error.statusCode || error.status_code || error.output?.statusCode;\n return statusCode ? parseInt(statusCode as string, 10) : 500;\n}\n\n/** Returns true if response code is internal server error */\nfunction defaultShouldHandleError(error: MiddlewareError): boolean {\n const status = getStatusCodeFromResponse(error);\n return status >= 500;\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../../../src/integrations/tracing/fastify/fastify-otel/index.js"],"sourcesContent":["/*\nVendored in and modified from @fastify/otel version 0.8.0\nhttps://github.com/fastify/otel/releases/tag/v0.8.0\n\nTried not to modify the original code too much keeping it as a JavaScript CJS module to make it easier to update when required\n\nModifications include:\n- Removed reading of package.json to get the version and package name\n\nMIT License\n\nCopyright (c) 2024 Fastify\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n/* eslint-disable jsdoc/require-jsdoc */\n/* eslint-disable max-lines */\n/* eslint-disable no-param-reassign */\nimport dc from 'node:diagnostics_channel';\nimport { context, diag, propagation, SpanStatusCode, trace } from '@opentelemetry/api';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport { InstrumentationBase } from '@opentelemetry/instrumentation';\nimport {\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_HTTP_RESPONSE_STATUS_CODE,\n ATTR_HTTP_ROUTE,\n ATTR_SERVICE_NAME,\n} from '@opentelemetry/semantic-conventions';\nimport * as minimatch from 'minimatch';\n\n// SENTRY VENDOR NOTE\n// Instead of using the package.json file, we hard code the package name and version here.\nconst PACKAGE_NAME = '@fastify/otel';\nconst PACKAGE_VERSION = '0.8.0';\n\n// Constants\nconst SUPPORTED_VERSIONS = '>=4.0.0 <6';\nconst FASTIFY_HOOKS = [\n 'onRequest',\n 'preParsing',\n 'preValidation',\n 'preHandler',\n 'preSerialization',\n 'onSend',\n 'onResponse',\n 'onError',\n];\nconst ATTRIBUTE_NAMES = {\n HOOK_NAME: 'hook.name',\n FASTIFY_TYPE: 'fastify.type',\n HOOK_CALLBACK_NAME: 'hook.callback.name',\n ROOT: 'fastify.root',\n};\nconst HOOK_TYPES = {\n ROUTE: 'route-hook',\n INSTANCE: 'hook',\n HANDLER: 'request-handler',\n};\nconst ANONYMOUS_FUNCTION_NAME = 'anonymous';\n\n// Symbols\nconst kInstrumentation = Symbol('fastify otel instance');\nconst kRequestSpan = Symbol('fastify otel request spans');\nconst kRequestContext = Symbol('fastify otel request context');\nconst kAddHookOriginal = Symbol('fastify otel addhook original');\nconst kSetNotFoundOriginal = Symbol('fastify otel setnotfound original');\nconst kIgnorePaths = Symbol('fastify otel ignore path');\n\nexport class FastifyOtelInstrumentation extends InstrumentationBase {\n constructor(config) {\n super(PACKAGE_NAME, PACKAGE_VERSION, config);\n this.servername = config?.servername ?? process.env.OTEL_SERVICE_NAME ?? 'fastify';\n this[kIgnorePaths] = null;\n this._logger = diag.createComponentLogger({ namespace: PACKAGE_NAME });\n\n if (config?.ignorePaths != null || process.env.OTEL_FASTIFY_IGNORE_PATHS != null) {\n const ignorePaths = config?.ignorePaths ?? process.env.OTEL_FASTIFY_IGNORE_PATHS;\n\n if ((typeof ignorePaths !== 'string' || ignorePaths.length === 0) && typeof ignorePaths !== 'function') {\n throw new TypeError('ignorePaths must be a string or a function');\n }\n\n const globMatcher = minimatch.minimatch;\n\n this[kIgnorePaths] = routeOptions => {\n if (typeof ignorePaths === 'function') {\n return ignorePaths(routeOptions);\n } else {\n return globMatcher(routeOptions.url, ignorePaths);\n }\n };\n }\n }\n\n enable() {\n if (this._handleInitialization === undefined && this.getConfig().registerOnInitialization) {\n const FastifyInstrumentationPlugin = this.plugin();\n this._handleInitialization = message => {\n message.fastify.register(FastifyInstrumentationPlugin);\n };\n dc.subscribe('fastify.initialization', this._handleInitialization);\n }\n return super.enable();\n }\n\n disable() {\n if (this._handleInitialization) {\n dc.unsubscribe('fastify.initialization', this._handleInitialization);\n this._handleInitialization = undefined;\n }\n return super.disable();\n }\n\n // We do not do patching in this instrumentation\n init() {\n return [];\n }\n\n plugin() {\n const instrumentation = this;\n\n FastifyInstrumentationPlugin[Symbol.for('skip-override')] = true;\n FastifyInstrumentationPlugin[Symbol.for('fastify.display-name')] = '@fastify/otel';\n FastifyInstrumentationPlugin[Symbol.for('plugin-meta')] = {\n fastify: SUPPORTED_VERSIONS,\n name: '@fastify/otel',\n };\n\n return FastifyInstrumentationPlugin;\n\n function FastifyInstrumentationPlugin(instance, opts, done) {\n instance.decorate(kInstrumentation, instrumentation);\n // addHook and notfoundHandler are essentially inherited from the prototype\n // what is important is to bound it to the right instance\n instance.decorate(kAddHookOriginal, instance.addHook);\n instance.decorate(kSetNotFoundOriginal, instance.setNotFoundHandler);\n instance.decorateRequest('opentelemetry', function openetelemetry() {\n const ctx = this[kRequestContext];\n const span = this[kRequestSpan];\n return {\n span,\n tracer: instrumentation.tracer,\n context: ctx,\n inject: (carrier, setter) => {\n return propagation.inject(ctx, carrier, setter);\n },\n extract: (carrier, getter) => {\n return propagation.extract(ctx, carrier, getter);\n },\n };\n });\n instance.decorateRequest(kRequestSpan, null);\n instance.decorateRequest(kRequestContext, null);\n\n instance.addHook('onRoute', function (routeOptions) {\n if (instrumentation[kIgnorePaths]?.(routeOptions) === true) {\n instrumentation._logger.debug(\n `Ignoring route instrumentation ${routeOptions.method} ${routeOptions.url} because it matches the ignore path`,\n );\n return;\n }\n\n for (const hook of FASTIFY_HOOKS) {\n if (routeOptions[hook] != null) {\n const handlerLike = routeOptions[hook];\n\n if (typeof handlerLike === 'function') {\n routeOptions[hook] = handlerWrapper(handlerLike, {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - route -> ${hook}`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.ROUTE,\n [ATTR_HTTP_ROUTE]: routeOptions.url,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n handlerLike.name?.length > 0 ? handlerLike.name : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */,\n });\n } else if (Array.isArray(handlerLike)) {\n const wrappedHandlers = [];\n\n for (const handler of handlerLike) {\n wrappedHandlers.push(\n handlerWrapper(handler, {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - route -> ${hook}`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.ROUTE,\n [ATTR_HTTP_ROUTE]: routeOptions.url,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n handler.name?.length > 0 ? handler.name : ANONYMOUS_FUNCTION_NAME,\n }),\n );\n }\n\n routeOptions[hook] = wrappedHandlers;\n }\n }\n }\n\n // We always want to add the onSend hook to the route to be executed last\n if (routeOptions.onSend != null) {\n routeOptions.onSend = Array.isArray(routeOptions.onSend)\n ? [...routeOptions.onSend, onSendHook]\n : [routeOptions.onSend, onSendHook];\n } else {\n routeOptions.onSend = onSendHook;\n }\n\n // We always want to add the onError hook to the route to be executed last\n if (routeOptions.onError != null) {\n routeOptions.onError = Array.isArray(routeOptions.onError)\n ? [...routeOptions.onError, onErrorHook]\n : [routeOptions.onError, onErrorHook];\n } else {\n routeOptions.onError = onErrorHook;\n }\n\n routeOptions.handler = handlerWrapper(routeOptions.handler, {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - route-handler`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.HANDLER,\n [ATTR_HTTP_ROUTE]: routeOptions.url,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n routeOptions.handler.name.length > 0 ? routeOptions.handler.name : ANONYMOUS_FUNCTION_NAME,\n });\n });\n\n instance.addHook('onRequest', function (request, _reply, hookDone) {\n if (this[kInstrumentation].isEnabled() === false) {\n return hookDone();\n } else if (\n this[kInstrumentation][kIgnorePaths]?.({\n url: request.url,\n method: request.method,\n }) === true\n ) {\n this[kInstrumentation]._logger.debug(\n `Ignoring request ${request.method} ${request.url} because it matches the ignore path`,\n );\n return hookDone();\n }\n\n let ctx = context.active();\n\n if (trace.getSpan(ctx) == null) {\n ctx = propagation.extract(ctx, request.headers);\n }\n\n const rpcMetadata = getRPCMetadata(ctx);\n\n if (request.routeOptions.url != null && rpcMetadata?.type === RPCType.HTTP) {\n rpcMetadata.route = request.routeOptions.url;\n }\n\n /** @type {import('@opentelemetry/api').Span} */\n const span = this[kInstrumentation].tracer.startSpan(\n 'request',\n {\n attributes: {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.ROOT]: '@fastify/otel',\n [ATTR_HTTP_ROUTE]: request.url,\n [ATTR_HTTP_REQUEST_METHOD]: request.method,\n },\n },\n ctx,\n );\n\n request[kRequestContext] = trace.setSpan(ctx, span);\n request[kRequestSpan] = span;\n\n context.with(request[kRequestContext], () => {\n hookDone();\n });\n });\n\n // onResponse is the last hook to be executed, only added for 404 handlers\n instance.addHook('onResponse', function (request, reply, hookDone) {\n const span = request[kRequestSpan];\n\n if (span != null) {\n span.setStatus({\n code: SpanStatusCode.OK,\n message: 'OK',\n });\n span.setAttributes({\n [ATTR_HTTP_RESPONSE_STATUS_CODE]: 404,\n });\n span.end();\n }\n\n request[kRequestSpan] = null;\n\n hookDone();\n });\n\n instance.addHook = addHookPatched;\n instance.setNotFoundHandler = setNotFoundHandlerPatched;\n\n done();\n\n function onSendHook(request, reply, payload, hookDone) {\n /** @type {import('@opentelemetry/api').Span} */\n const span = request[kRequestSpan];\n\n if (span != null) {\n if (reply.statusCode < 500) {\n span.setStatus({\n code: SpanStatusCode.OK,\n message: 'OK',\n });\n }\n\n span.setAttributes({\n [ATTR_HTTP_RESPONSE_STATUS_CODE]: reply.statusCode,\n });\n span.end();\n }\n\n request[kRequestSpan] = null;\n\n hookDone(null, payload);\n }\n\n function onErrorHook(request, reply, error, hookDone) {\n /** @type {Span} */\n const span = request[kRequestSpan];\n\n if (span != null) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n });\n span.recordException(error);\n }\n\n hookDone();\n }\n\n function addHookPatched(name, hook) {\n const addHookOriginal = this[kAddHookOriginal];\n\n if (FASTIFY_HOOKS.includes(name)) {\n return addHookOriginal.call(\n this,\n name,\n handlerWrapper(hook, {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - ${name}`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n hook.name?.length > 0 ? hook.name : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */,\n }),\n );\n } else {\n return addHookOriginal.call(this, name, hook);\n }\n }\n\n function setNotFoundHandlerPatched(hooks, handler) {\n const setNotFoundHandlerOriginal = this[kSetNotFoundOriginal];\n if (typeof hooks === 'function') {\n handler = handlerWrapper(hooks, {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - not-found-handler`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n hooks.name?.length > 0 ? hooks.name : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */,\n });\n setNotFoundHandlerOriginal.call(this, handler);\n } else {\n if (hooks.preValidation != null) {\n hooks.preValidation = handlerWrapper(hooks.preValidation, {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - not-found-handler - preValidation`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n hooks.preValidation.name?.length > 0\n ? hooks.preValidation.name\n : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */,\n });\n }\n\n if (hooks.preHandler != null) {\n hooks.preHandler = handlerWrapper(hooks.preHandler, {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - not-found-handler - preHandler`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n hooks.preHandler.name?.length > 0\n ? hooks.preHandler.name\n : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */,\n });\n }\n\n handler = handlerWrapper(handler, {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - not-found-handler`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n handler.name?.length > 0 ? handler.name : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */,\n });\n setNotFoundHandlerOriginal.call(this, hooks, handler);\n }\n }\n\n function handlerWrapper(handler, spanAttributes = {}) {\n return function handlerWrapped(...args) {\n /** @type {FastifyOtelInstrumentation} */\n const instrumentation = this[kInstrumentation];\n const [request] = args;\n\n if (instrumentation.isEnabled() === false) {\n return handler.call(this, ...args);\n }\n\n const ctx = request[kRequestContext] ?? context.active();\n const span = instrumentation.tracer.startSpan(\n `handler - ${\n handler.name?.length > 0\n ? handler.name\n : this.pluginName /* c8 ignore next */ ?? ANONYMOUS_FUNCTION_NAME /* c8 ignore next */\n }`,\n {\n attributes: spanAttributes,\n },\n ctx,\n );\n\n return context.with(\n trace.setSpan(ctx, span),\n function () {\n try {\n const res = handler.call(this, ...args);\n\n if (typeof res?.then === 'function') {\n return res.then(\n result => {\n span.end();\n return result;\n },\n error => {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n });\n span.recordException(error);\n span.end();\n return Promise.reject(error);\n },\n );\n }\n\n span.end();\n return res;\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n });\n span.recordException(error);\n span.end();\n throw error;\n }\n },\n this,\n );\n };\n }\n }\n }\n}\n"],"names":["dc"],"mappings":";;;;;;;AAAA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAiBA;AACA;AACA,MAAM,YAAA,GAAe,eAAe;AACpC,MAAM,eAAA,GAAkB,OAAO;;AAE/B;AACA,MAAM,kBAAA,GAAqB,YAAY;AACvC,MAAM,gBAAgB;AACtB,EAAE,WAAW;AACb,EAAE,YAAY;AACd,EAAE,eAAe;AACjB,EAAE,YAAY;AACd,EAAE,kBAAkB;AACpB,EAAE,QAAQ;AACV,EAAE,YAAY;AACd,EAAE,SAAS;AACX,CAAC;AACD,MAAM,kBAAkB;AACxB,EAAE,SAAS,EAAE,WAAW;AACxB,EAAE,YAAY,EAAE,cAAc;AAC9B,EAAE,kBAAkB,EAAE,oBAAoB;AAC1C,EAAE,IAAI,EAAE,cAAc;AACtB,CAAC;AACD,MAAM,aAAa;AACnB,EAAE,KAAK,EAAE,YAAY;AACrB,EAAE,QAAQ,EAAE,MAAM;AAClB,EAAE,OAAO,EAAE,iBAAiB;AAC5B,CAAC;AACD,MAAM,uBAAA,GAA0B,WAAW;;AAE3C;AACA,MAAM,gBAAiB,GAAE,MAAM,CAAC,uBAAuB,CAAC;AACxD,MAAM,YAAa,GAAE,MAAM,CAAC,4BAA4B,CAAC;AACzD,MAAM,eAAgB,GAAE,MAAM,CAAC,8BAA8B,CAAC;AAC9D,MAAM,gBAAiB,GAAE,MAAM,CAAC,+BAA+B,CAAC;AAChE,MAAM,oBAAqB,GAAE,MAAM,CAAC,mCAAmC,CAAC;AACxE,MAAM,YAAa,GAAE,MAAM,CAAC,0BAA0B,CAAC;;AAEhD,MAAM,0BAA2B,SAAQ,mBAAoB,CAAA;AACpE,EAAE,WAAW,CAAC,MAAM,EAAE;AACtB,IAAI,KAAK,CAAC,YAAY,EAAE,eAAe,EAAE,MAAM,CAAC;AAChD,IAAI,IAAI,CAAC,UAAW,GAAE,MAAM,EAAE,UAAA,IAAc,OAAO,CAAC,GAAG,CAAC,iBAAA,IAAqB,SAAS;AACtF,IAAI,IAAI,CAAC,YAAY,CAAA,GAAI,IAAI;AAC7B,IAAI,IAAI,CAAC,OAAQ,GAAE,IAAI,CAAC,qBAAqB,CAAC,EAAE,SAAS,EAAE,YAAA,EAAc,CAAC;;AAE1E,IAAI,IAAI,MAAM,EAAE,eAAe,IAAA,IAAQ,OAAO,CAAC,GAAG,CAAC,yBAA0B,IAAG,IAAI,EAAE;AACtF,MAAM,MAAM,WAAY,GAAE,MAAM,EAAE,WAAY,IAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB;;AAEtF,MAAM,IAAI,CAAC,OAAO,WAAY,KAAI,YAAY,WAAW,CAAC,MAAO,KAAI,CAAC,KAAK,OAAO,WAAY,KAAI,UAAU,EAAE;AAC9G,QAAQ,MAAM,IAAI,SAAS,CAAC,4CAA4C,CAAC;AACzE;;AAEA,MAAM,MAAM,WAAA,GAAc,SAAS,CAAC,SAAS;;AAE7C,MAAM,IAAI,CAAC,YAAY,CAAE,GAAE,gBAAgB;AAC3C,QAAQ,IAAI,OAAO,WAAY,KAAI,UAAU,EAAE;AAC/C,UAAU,OAAO,WAAW,CAAC,YAAY,CAAC;AAC1C,eAAe;AACf,UAAU,OAAO,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,WAAW,CAAC;AAC3D;AACA,OAAO;AACP;AACA;;AAEA,EAAE,MAAM,GAAG;AACX,IAAI,IAAI,IAAI,CAAC,0BAA0B,SAAA,IAAa,IAAI,CAAC,SAAS,EAAE,CAAC,wBAAwB,EAAE;AAC/F,MAAM,MAAM,4BAA6B,GAAE,IAAI,CAAC,MAAM,EAAE;AACxD,MAAM,IAAI,CAAC,qBAAsB,GAAE,WAAW;AAC9C,QAAQ,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAAC;AAC9D,OAAO;AACP,MAAMA,WAAE,CAAC,SAAS,CAAC,wBAAwB,EAAE,IAAI,CAAC,qBAAqB,CAAC;AACxE;AACA,IAAI,OAAO,KAAK,CAAC,MAAM,EAAE;AACzB;;AAEA,EAAE,OAAO,GAAG;AACZ,IAAI,IAAI,IAAI,CAAC,qBAAqB,EAAE;AACpC,MAAMA,WAAE,CAAC,WAAW,CAAC,wBAAwB,EAAE,IAAI,CAAC,qBAAqB,CAAC;AAC1E,MAAM,IAAI,CAAC,qBAAsB,GAAE,SAAS;AAC5C;AACA,IAAI,OAAO,KAAK,CAAC,OAAO,EAAE;AAC1B;;AAEA;AACA,EAAE,IAAI,GAAG;AACT,IAAI,OAAO,EAAE;AACb;;AAEA,EAAE,MAAM,GAAG;AACX,IAAI,MAAM,eAAgB,GAAE,IAAI;;AAEhC,IAAI,4BAA4B,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAE,GAAE,IAAI;AACpE,IAAI,4BAA4B,CAAC,MAAM,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAE,GAAE,eAAe;AACtF,IAAI,4BAA4B,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA,GAAI;AAC9D,MAAM,OAAO,EAAE,kBAAkB;AACjC,MAAM,IAAI,EAAE,eAAe;AAC3B,KAAK;;AAEL,IAAI,OAAO,4BAA4B;;AAEvC,IAAI,SAAS,4BAA4B,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE;AAChE,MAAM,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,EAAE,eAAe,CAAC;AAC1D;AACA;AACA,MAAM,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,EAAE,QAAQ,CAAC,OAAO,CAAC;AAC3D,MAAM,QAAQ,CAAC,QAAQ,CAAC,oBAAoB,EAAE,QAAQ,CAAC,kBAAkB,CAAC;AAC1E,MAAM,QAAQ,CAAC,eAAe,CAAC,eAAe,EAAE,SAAS,cAAc,GAAG;AAC1E,QAAQ,MAAM,GAAI,GAAE,IAAI,CAAC,eAAe,CAAC;AACzC,QAAQ,MAAM,IAAK,GAAE,IAAI,CAAC,YAAY,CAAC;AACvC,QAAQ,OAAO;AACf,UAAU,IAAI;AACd,UAAU,MAAM,EAAE,eAAe,CAAC,MAAM;AACxC,UAAU,OAAO,EAAE,GAAG;AACtB,UAAU,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;AACvC,YAAY,OAAO,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC;AAC3D,WAAW;AACX,UAAU,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;AACxC,YAAY,OAAO,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC;AAC5D,WAAW;AACX,SAAS;AACT,OAAO,CAAC;AACR,MAAM,QAAQ,CAAC,eAAe,CAAC,YAAY,EAAE,IAAI,CAAC;AAClD,MAAM,QAAQ,CAAC,eAAe,CAAC,eAAe,EAAE,IAAI,CAAC;;AAErD,MAAM,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,UAAU,YAAY,EAAE;AAC1D,QAAQ,IAAI,eAAe,CAAC,YAAY,CAAC,GAAG,YAAY,CAAA,KAAM,IAAI,EAAE;AACpE,UAAU,eAAe,CAAC,OAAO,CAAC,KAAK;AACvC,YAAY,CAAC,+BAA+B,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC,mCAAmC,CAAC;AAC1H,WAAW;AACX,UAAU;AACV;;AAEA,QAAQ,KAAK,MAAM,IAAK,IAAG,aAAa,EAAE;AAC1C,UAAU,IAAI,YAAY,CAAC,IAAI,CAAE,IAAG,IAAI,EAAE;AAC1C,YAAY,MAAM,WAAY,GAAE,YAAY,CAAC,IAAI,CAAC;;AAElD,YAAY,IAAI,OAAO,WAAY,KAAI,UAAU,EAAE;AACnD,cAAc,YAAY,CAAC,IAAI,CAAA,GAAI,cAAc,CAAC,WAAW,EAAE;AAC/D,gBAAgB,CAAC,iBAAiB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC,UAAU;AAC1E,gBAAgB,CAAC,eAAe,CAAC,SAAS,GAAG,CAAC,EAAA,IAAA,CAAA,UAAA,CAAA,YAAA,EAAA,IAAA,CAAA,CAAA;AACA,gBAAA,CAAA,eAAA,CAAA,YAAA,GAAA,UAAA,CAAA,KAAA;AACA,gBAAA,CAAA,eAAA,GAAA,YAAA,CAAA,GAAA;AACA,gBAAA,CAAA,eAAA,CAAA,kBAAA;AACA,kBAAA,WAAA,CAAA,IAAA,EAAA,MAAA,GAAA,CAAA,GAAA,WAAA,CAAA,IAAA,GAAA,uBAAA;AACA,eAAA,CAAA;AACA,aAAA,MAAA,IAAA,KAAA,CAAA,OAAA,CAAA,WAAA,CAAA,EAAA;AACA,cAAA,MAAA,eAAA,GAAA,EAAA;;AAEA,cAAA,KAAA,MAAA,OAAA,IAAA,WAAA,EAAA;AACA,gBAAA,eAAA,CAAA,IAAA;AACA,kBAAA,cAAA,CAAA,OAAA,EAAA;AACA,oBAAA,CAAA,iBAAA,GAAA,QAAA,CAAA,gBAAA,CAAA,CAAA,UAAA;AACA,oBAAA,CAAA,eAAA,CAAA,SAAA,GAAA,CAAA,EAAA,IAAA,CAAA,UAAA,CAAA,YAAA,EAAA,IAAA,CAAA,CAAA;AACA,oBAAA,CAAA,eAAA,CAAA,YAAA,GAAA,UAAA,CAAA,KAAA;AACA,oBAAA,CAAA,eAAA,GAAA,YAAA,CAAA,GAAA;AACA,oBAAA,CAAA,eAAA,CAAA,kBAAA;AACA,sBAAA,OAAA,CAAA,IAAA,EAAA,MAAA,GAAA,CAAA,GAAA,OAAA,CAAA,IAAA,GAAA,uBAAA;AACA,mBAAA,CAAA;AACA,iBAAA;AACA;;AAEA,cAAA,YAAA,CAAA,IAAA,CAAA,GAAA,eAAA;AACA;AACA;AACA;;AAEA;AACA,QAAA,IAAA,YAAA,CAAA,MAAA,IAAA,IAAA,EAAA;AACA,UAAA,YAAA,CAAA,MAAA,GAAA,KAAA,CAAA,OAAA,CAAA,YAAA,CAAA,MAAA;AACA,cAAA,CAAA,GAAA,YAAA,CAAA,MAAA,EAAA,UAAA;AACA,cAAA,CAAA,YAAA,CAAA,MAAA,EAAA,UAAA,CAAA;AACA,SAAA,MAAA;AACA,UAAA,YAAA,CAAA,MAAA,GAAA,UAAA;AACA;;AAEA;AACA,QAAA,IAAA,YAAA,CAAA,OAAA,IAAA,IAAA,EAAA;AACA,UAAA,YAAA,CAAA,OAAA,GAAA,KAAA,CAAA,OAAA,CAAA,YAAA,CAAA,OAAA;AACA,cAAA,CAAA,GAAA,YAAA,CAAA,OAAA,EAAA,WAAA;AACA,cAAA,CAAA,YAAA,CAAA,OAAA,EAAA,WAAA,CAAA;AACA,SAAA,MAAA;AACA,UAAA,YAAA,CAAA,OAAA,GAAA,WAAA;AACA;;AAEA,QAAA,YAAA,CAAA,OAAA,GAAA,cAAA,CAAA,YAAA,CAAA,OAAA,EAAA;AACA,UAAA,CAAA,iBAAA,GAAA,QAAA,CAAA,gBAAA,CAAA,CAAA,UAAA;AACA,UAAA,CAAA,eAAA,CAAA,SAAA,GAAA,CAAA,EAAA,IAAA,CAAA,UAAA,CAAA,gBAAA,CAAA;AACA,UAAA,CAAA,eAAA,CAAA,YAAA,GAAA,UAAA,CAAA,OAAA;AACA,UAAA,CAAA,eAAA,GAAA,YAAA,CAAA,GAAA;AACA,UAAA,CAAA,eAAA,CAAA,kBAAA;AACA,YAAA,YAAA,CAAA,OAAA,CAAA,IAAA,CAAA,MAAA,GAAA,CAAA,GAAA,YAAA,CAAA,OAAA,CAAA,IAAA,GAAA,uBAAA;AACA,SAAA,CAAA;AACA,OAAA,CAAA;;AAEA,MAAA,QAAA,CAAA,OAAA,CAAA,WAAA,EAAA,UAAA,OAAA,EAAA,MAAA,EAAA,QAAA,EAAA;AACA,QAAA,IAAA,IAAA,CAAA,gBAAA,CAAA,CAAA,SAAA,EAAA,KAAA,KAAA,EAAA;AACA,UAAA,OAAA,QAAA,EAAA;AACA,SAAA,MAAA;AACA,UAAA,IAAA,CAAA,gBAAA,CAAA,CAAA,YAAA,CAAA,GAAA;AACA,YAAA,GAAA,EAAA,OAAA,CAAA,GAAA;AACA,YAAA,MAAA,EAAA,OAAA,CAAA,MAAA;AACA,WAAA,CAAA,KAAA;AACA,UAAA;AACA,UAAA,IAAA,CAAA,gBAAA,CAAA,CAAA,OAAA,CAAA,KAAA;AACA,YAAA,CAAA,iBAAA,EAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,OAAA,CAAA,GAAA,CAAA,mCAAA,CAAA;AACA,WAAA;AACA,UAAA,OAAA,QAAA,EAAA;AACA;;AAEA,QAAA,IAAA,GAAA,GAAA,OAAA,CAAA,MAAA,EAAA;;AAEA,QAAA,IAAA,KAAA,CAAA,OAAA,CAAA,GAAA,CAAA,IAAA,IAAA,EAAA;AACA,UAAA,GAAA,GAAA,WAAA,CAAA,OAAA,CAAA,GAAA,EAAA,OAAA,CAAA,OAAA,CAAA;AACA;;AAEA,QAAA,MAAA,WAAA,GAAA,cAAA,CAAA,GAAA,CAAA;;AAEA,QAAA,IAAA,OAAA,CAAA,YAAA,CAAA,GAAA,IAAA,IAAA,IAAA,WAAA,EAAA,IAAA,KAAA,OAAA,CAAA,IAAA,EAAA;AACA,UAAA,WAAA,CAAA,KAAA,GAAA,OAAA,CAAA,YAAA,CAAA,GAAA;AACA;;AAEA;AACA,QAAA,MAAA,IAAA,GAAA,IAAA,CAAA,gBAAA,CAAA,CAAA,MAAA,CAAA,SAAA;AACA,UAAA,SAAA;AACA,UAAA;AACA,YAAA,UAAA,EAAA;AACA,cAAA,CAAA,iBAAA,GAAA,QAAA,CAAA,gBAAA,CAAA,CAAA,UAAA;AACA,cAAA,CAAA,eAAA,CAAA,IAAA,GAAA,eAAA;AACA,cAAA,CAAA,eAAA,GAAA,OAAA,CAAA,GAAA;AACA,cAAA,CAAA,wBAAA,GAAA,OAAA,CAAA,MAAA;AACA,aAAA;AACA,WAAA;AACA,UAAA,GAAA;AACA,SAAA;;AAEA,QAAA,OAAA,CAAA,eAAA,CAAA,GAAA,KAAA,CAAA,OAAA,CAAA,GAAA,EAAA,IAAA,CAAA;AACA,QAAA,OAAA,CAAA,YAAA,CAAA,GAAA,IAAA;;AAEA,QAAA,OAAA,CAAA,IAAA,CAAA,OAAA,CAAA,eAAA,CAAA,EAAA,MAAA;AACA,UAAA,QAAA,EAAA;AACA,SAAA,CAAA;AACA,OAAA,CAAA;;AAEA;AACA,MAAA,QAAA,CAAA,OAAA,CAAA,YAAA,EAAA,UAAA,OAAA,EAAA,KAAA,EAAA,QAAA,EAAA;AACA,QAAA,MAAA,IAAA,GAAA,OAAA,CAAA,YAAA,CAAA;;AAEA,QAAA,IAAA,IAAA,IAAA,IAAA,EAAA;AACA,UAAA,IAAA,CAAA,SAAA,CAAA;AACA,YAAA,IAAA,EAAA,cAAA,CAAA,EAAA;AACA,YAAA,OAAA,EAAA,IAAA;AACA,WAAA,CAAA;AACA,UAAA,IAAA,CAAA,aAAA,CAAA;AACA,YAAA,CAAA,8BAAA,GAAA,GAAA;AACA,WAAA,CAAA;AACA,UAAA,IAAA,CAAA,GAAA,EAAA;AACA;;AAEA,QAAA,OAAA,CAAA,YAAA,CAAA,GAAA,IAAA;;AAEA,QAAA,QAAA,EAAA;AACA,OAAA,CAAA;;AAEA,MAAA,QAAA,CAAA,OAAA,GAAA,cAAA;AACA,MAAA,QAAA,CAAA,kBAAA,GAAA,yBAAA;;AAEA,MAAA,IAAA,EAAA;;AAEA,MAAA,SAAA,UAAA,CAAA,OAAA,EAAA,KAAA,EAAA,OAAA,EAAA,QAAA,EAAA;AACA;AACA,QAAA,MAAA,IAAA,GAAA,OAAA,CAAA,YAAA,CAAA;;AAEA,QAAA,IAAA,IAAA,IAAA,IAAA,EAAA;AACA,UAAA,IAAA,KAAA,CAAA,UAAA,GAAA,GAAA,EAAA;AACA,YAAA,IAAA,CAAA,SAAA,CAAA;AACA,cAAA,IAAA,EAAA,cAAA,CAAA,EAAA;AACA,cAAA,OAAA,EAAA,IAAA;AACA,aAAA,CAAA;AACA;;AAEA,UAAA,IAAA,CAAA,aAAA,CAAA;AACA,YAAA,CAAA,8BAAA,GAAA,KAAA,CAAA,UAAA;AACA,WAAA,CAAA;AACA,UAAA,IAAA,CAAA,GAAA,EAAA;AACA;;AAEA,QAAA,OAAA,CAAA,YAAA,CAAA,GAAA,IAAA;;AAEA,QAAA,QAAA,CAAA,IAAA,EAAA,OAAA,CAAA;AACA;;AAEA,MAAA,SAAA,WAAA,CAAA,OAAA,EAAA,KAAA,EAAA,KAAA,EAAA,QAAA,EAAA;AACA;AACA,QAAA,MAAA,IAAA,GAAA,OAAA,CAAA,YAAA,CAAA;;AAEA,QAAA,IAAA,IAAA,IAAA,IAAA,EAAA;AACA,UAAA,IAAA,CAAA,SAAA,CAAA;AACA,YAAA,IAAA,EAAA,cAAA,CAAA,KAAA;AACA,YAAA,OAAA,EAAA,KAAA,CAAA,OAAA;AACA,WAAA,CAAA;AACA,UAAA,IAAA,CAAA,eAAA,CAAA,KAAA,CAAA;AACA;;AAEA,QAAA,QAAA,EAAA;AACA;;AAEA,MAAA,SAAA,cAAA,CAAA,IAAA,EAAA,IAAA,EAAA;AACA,QAAA,MAAA,eAAA,GAAA,IAAA,CAAA,gBAAA,CAAA;;AAEA,QAAA,IAAA,aAAA,CAAA,QAAA,CAAA,IAAA,CAAA,EAAA;AACA,UAAA,OAAA,eAAA,CAAA,IAAA;AACA,YAAA,IAAA;AACA,YAAA,IAAA;AACA,YAAA,cAAA,CAAA,IAAA,EAAA;AACA,cAAA,CAAA,iBAAA,GAAA,QAAA,CAAA,gBAAA,CAAA,CAAA,UAAA;AACA,cAAA,CAAA,eAAA,CAAA,SAAA,GAAA,CAAA,EAAA,IAAA,CAAA,UAAA,CAAA,GAAA,EAAA,IAAA,CAAA,CAAA;AACA,cAAA,CAAA,eAAA,CAAA,YAAA,GAAA,UAAA,CAAA,QAAA;AACA,cAAA,CAAA,eAAA,CAAA,kBAAA;AACA,gBAAA,IAAA,CAAA,IAAA,EAAA,MAAA,GAAA,CAAA,GAAA,IAAA,CAAA,IAAA,GAAA,uBAAA;AACA,aAAA,CAAA;AACA,WAAA;AACA,SAAA,MAAA;AACA,UAAA,OAAA,eAAA,CAAA,IAAA,CAAA,IAAA,EAAA,IAAA,EAAA,IAAA,CAAA;AACA;AACA;;AAEA,MAAA,SAAA,yBAAA,CAAA,KAAA,EAAA,OAAA,EAAA;AACA,QAAA,MAAA,0BAAA,GAAA,IAAA,CAAA,oBAAA,CAAA;AACA,QAAA,IAAA,OAAA,KAAA,KAAA,UAAA,EAAA;AACA,UAAA,OAAA,GAAA,cAAA,CAAA,KAAA,EAAA;AACA,YAAA,CAAA,iBAAA,GAAA,QAAA,CAAA,gBAAA,CAAA,CAAA,UAAA;AACA,YAAA,CAAA,eAAA,CAAA,SAAA,GAAA,CAAA,EAAA,IAAA,CAAA,UAAA,CAAA,oBAAA,CAAA;AACA,YAAA,CAAA,eAAA,CAAA,YAAA,GAAA,UAAA,CAAA,QAAA;AACA,YAAA,CAAA,eAAA,CAAA,kBAAA;AACA,cAAA,KAAA,CAAA,IAAA,EAAA,MAAA,GAAA,CAAA,GAAA,KAAA,CAAA,IAAA,GAAA,uBAAA;AACA,WAAA,CAAA;AACA,UAAA,0BAAA,CAAA,IAAA,CAAA,IAAA,EAAA,OAAA,CAAA;AACA,SAAA,MAAA;AACA,UAAA,IAAA,KAAA,CAAA,aAAA,IAAA,IAAA,EAAA;AACA,YAAA,KAAA,CAAA,aAAA,GAAA,cAAA,CAAA,KAAA,CAAA,aAAA,EAAA;AACA,cAAA,CAAA,iBAAA,GAAA,QAAA,CAAA,gBAAA,CAAA,CAAA,UAAA;AACA,cAAA,CAAA,eAAA,CAAA,SAAA,GAAA,CAAA,EAAA,IAAA,CAAA,UAAA,CAAA,oCAAA,CAAA;AACA,cAAA,CAAA,eAAA,CAAA,YAAA,GAAA,UAAA,CAAA,QAAA;AACA,cAAA,CAAA,eAAA,CAAA,kBAAA;AACA,gBAAA,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,MAAA,GAAA;AACA,oBAAA,KAAA,CAAA,aAAA,CAAA;AACA,oBAAA,uBAAA;AACA,aAAA,CAAA;AACA;;AAEA,UAAA,IAAA,KAAA,CAAA,UAAA,IAAA,IAAA,EAAA;AACA,YAAA,KAAA,CAAA,UAAA,GAAA,cAAA,CAAA,KAAA,CAAA,UAAA,EAAA;AACA,cAAA,CAAA,iBAAA,GAAA,QAAA,CAAA,gBAAA,CAAA,CAAA,UAAA;AACA,cAAA,CAAA,eAAA,CAAA,SAAA,GAAA,CAAA,EAAA,IAAA,CAAA,UAAA,CAAA,iCAAA,CAAA;AACA,cAAA,CAAA,eAAA,CAAA,YAAA,GAAA,UAAA,CAAA,QAAA;AACA,cAAA,CAAA,eAAA,CAAA,kBAAA;AACA,gBAAA,KAAA,CAAA,UAAA,CAAA,IAAA,EAAA,MAAA,GAAA;AACA,oBAAA,KAAA,CAAA,UAAA,CAAA;AACA,oBAAA,uBAAA;AACA,aAAA,CAAA;AACA;;AAEA,UAAA,OAAA,GAAA,cAAA,CAAA,OAAA,EAAA;AACA,YAAA,CAAA,iBAAA,GAAA,QAAA,CAAA,gBAAA,CAAA,CAAA,UAAA;AACA,YAAA,CAAA,eAAA,CAAA,SAAA,GAAA,CAAA,EAAA,IAAA,CAAA,UAAA,CAAA,oBAAA,CAAA;AACA,YAAA,CAAA,eAAA,CAAA,YAAA,GAAA,UAAA,CAAA,QAAA;AACA,YAAA,CAAA,eAAA,CAAA,kBAAA;AACA,cAAA,OAAA,CAAA,IAAA,EAAA,MAAA,GAAA,CAAA,GAAA,OAAA,CAAA,IAAA,GAAA,uBAAA;AACA,WAAA,CAAA;AACA,UAAA,0BAAA,CAAA,IAAA,CAAA,IAAA,EAAA,KAAA,EAAA,OAAA,CAAA;AACA;AACA;;AAEA,MAAA,SAAA,cAAA,CAAA,OAAA,EAAA,cAAA,GAAA,EAAA,EAAA;AACA,QAAA,OAAA,SAAA,cAAA,CAAA,GAAA,IAAA,EAAA;AACA;AACA,UAAA,MAAA,eAAA,GAAA,IAAA,CAAA,gBAAA,CAAA;AACA,UAAA,MAAA,CAAA,OAAA,CAAA,GAAA,IAAA;;AAEA,UAAA,IAAA,eAAA,CAAA,SAAA,EAAA,KAAA,KAAA,EAAA;AACA,YAAA,OAAA,OAAA,CAAA,IAAA,CAAA,IAAA,EAAA,GAAA,IAAA,CAAA;AACA;;AAEA,UAAA,MAAA,GAAA,GAAA,OAAA,CAAA,eAAA,CAAA,IAAA,OAAA,CAAA,MAAA,EAAA;AACA,UAAA,MAAA,IAAA,GAAA,eAAA,CAAA,MAAA,CAAA,SAAA;AACA,YAAA,CAAA,UAAA;AACA,cAAA,OAAA,CAAA,IAAA,EAAA,MAAA,GAAA;AACA,kBAAA,OAAA,CAAA;AACA,kBAAA,IAAA,CAAA,UAAA,yBAAA,uBAAA;AACA,aAAA,CAAA;AACA,YAAA;AACA,cAAA,UAAA,EAAA,cAAA;AACA,aAAA;AACA,YAAA,GAAA;AACA,WAAA;;AAEA,UAAA,OAAA,OAAA,CAAA,IAAA;AACA,YAAA,KAAA,CAAA,OAAA,CAAA,GAAA,EAAA,IAAA,CAAA;AACA,YAAA,YAAA;AACA,cAAA,IAAA;AACA,gBAAA,MAAA,GAAA,GAAA,OAAA,CAAA,IAAA,CAAA,IAAA,EAAA,GAAA,IAAA,CAAA;;AAEA,gBAAA,IAAA,OAAA,GAAA,EAAA,IAAA,KAAA,UAAA,EAAA;AACA,kBAAA,OAAA,GAAA,CAAA,IAAA;AACA,oBAAA,MAAA,IAAA;AACA,sBAAA,IAAA,CAAA,GAAA,EAAA;AACA,sBAAA,OAAA,MAAA;AACA,qBAAA;AACA,oBAAA,KAAA,IAAA;AACA,sBAAA,IAAA,CAAA,SAAA,CAAA;AACA,wBAAA,IAAA,EAAA,cAAA,CAAA,KAAA;AACA,wBAAA,OAAA,EAAA,KAAA,CAAA,OAAA;AACA,uBAAA,CAAA;AACA,sBAAA,IAAA,CAAA,eAAA,CAAA,KAAA,CAAA;AACA,sBAAA,IAAA,CAAA,GAAA,EAAA;AACA,sBAAA,OAAA,OAAA,CAAA,MAAA,CAAA,KAAA,CAAA;AACA,qBAAA;AACA,mBAAA;AACA;;AAEA,gBAAA,IAAA,CAAA,GAAA,EAAA;AACA,gBAAA,OAAA,GAAA;AACA,eAAA,CAAA,OAAA,KAAA,EAAA;AACA,gBAAA,IAAA,CAAA,SAAA,CAAA;AACA,kBAAA,IAAA,EAAA,cAAA,CAAA,KAAA;AACA,kBAAA,OAAA,EAAA,KAAA,CAAA,OAAA;AACA,iBAAA,CAAA;AACA,gBAAA,IAAA,CAAA,eAAA,CAAA,KAAA,CAAA;AACA,gBAAA,IAAA,CAAA,GAAA,EAAA;AACA,gBAAA,MAAA,KAAA;AACA;AACA,aAAA;AACA,YAAA,IAAA;AACA,WAAA;AACA,SAAA;AACA;AACA;AACA;AACA;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../../../src/integrations/tracing/fastify/fastify-otel/index.js"],"sourcesContent":["/*\nVendored in and modified from @fastify/otel version 0.8.0\nhttps://github.com/fastify/otel/releases/tag/v0.8.0\n\nTried not to modify the original code too much keeping it as a JavaScript CJS module to make it easier to update when required\n\nModifications include:\n- Removed reading of package.json to get the version and package name\n\nMIT License\n\nCopyright (c) 2024 Fastify\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n/* eslint-disable jsdoc/require-jsdoc */\n/* eslint-disable max-lines */\n/* eslint-disable no-param-reassign */\nimport dc from 'node:diagnostics_channel';\nimport { context, diag, propagation, SpanStatusCode, trace } from '@opentelemetry/api';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport { InstrumentationBase } from '@opentelemetry/instrumentation';\nimport {\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_HTTP_RESPONSE_STATUS_CODE,\n ATTR_HTTP_ROUTE,\n ATTR_SERVICE_NAME,\n} from '@opentelemetry/semantic-conventions';\nimport * as minimatch from 'minimatch';\n\n// SENTRY VENDOR NOTE\n// Instead of using the package.json file, we hard code the package name and version here.\nconst PACKAGE_NAME = '@fastify/otel';\nconst PACKAGE_VERSION = '0.8.0';\n\n// Constants\nconst SUPPORTED_VERSIONS = '>=4.0.0 <6';\nconst FASTIFY_HOOKS = [\n 'onRequest',\n 'preParsing',\n 'preValidation',\n 'preHandler',\n 'preSerialization',\n 'onSend',\n 'onResponse',\n 'onError',\n];\nconst ATTRIBUTE_NAMES = {\n HOOK_NAME: 'hook.name',\n FASTIFY_TYPE: 'fastify.type',\n HOOK_CALLBACK_NAME: 'hook.callback.name',\n ROOT: 'fastify.root',\n};\nconst HOOK_TYPES = {\n ROUTE: 'route-hook',\n INSTANCE: 'hook',\n HANDLER: 'request-handler',\n};\nconst ANONYMOUS_FUNCTION_NAME = 'anonymous';\n\n// Symbols\nconst kInstrumentation = Symbol('fastify otel instance');\nconst kRequestSpan = Symbol('fastify otel request spans');\nconst kRequestContext = Symbol('fastify otel request context');\nconst kAddHookOriginal = Symbol('fastify otel addhook original');\nconst kSetNotFoundOriginal = Symbol('fastify otel setnotfound original');\nconst kIgnorePaths = Symbol('fastify otel ignore path');\n\nexport class FastifyOtelInstrumentation extends InstrumentationBase {\n constructor(config) {\n super(PACKAGE_NAME, PACKAGE_VERSION, config);\n this.servername = config?.servername ?? process.env.OTEL_SERVICE_NAME ?? 'fastify';\n this[kIgnorePaths] = null;\n this._logger = diag.createComponentLogger({ namespace: PACKAGE_NAME });\n\n if (config?.ignorePaths != null || process.env.OTEL_FASTIFY_IGNORE_PATHS != null) {\n const ignorePaths = config?.ignorePaths ?? process.env.OTEL_FASTIFY_IGNORE_PATHS;\n\n if ((typeof ignorePaths !== 'string' || ignorePaths.length === 0) && typeof ignorePaths !== 'function') {\n throw new TypeError('ignorePaths must be a string or a function');\n }\n\n const globMatcher = minimatch.minimatch;\n\n this[kIgnorePaths] = routeOptions => {\n if (typeof ignorePaths === 'function') {\n return ignorePaths(routeOptions);\n } else {\n return globMatcher(routeOptions.url, ignorePaths);\n }\n };\n }\n }\n\n enable() {\n if (this._handleInitialization === undefined && this.getConfig().registerOnInitialization) {\n const FastifyInstrumentationPlugin = this.plugin();\n this._handleInitialization = message => {\n message.fastify.register(FastifyInstrumentationPlugin);\n };\n dc.subscribe('fastify.initialization', this._handleInitialization);\n }\n return super.enable();\n }\n\n disable() {\n if (this._handleInitialization) {\n dc.unsubscribe('fastify.initialization', this._handleInitialization);\n this._handleInitialization = undefined;\n }\n return super.disable();\n }\n\n // We do not do patching in this instrumentation\n init() {\n return [];\n }\n\n plugin() {\n const instrumentation = this;\n\n FastifyInstrumentationPlugin[Symbol.for('skip-override')] = true;\n FastifyInstrumentationPlugin[Symbol.for('fastify.display-name')] = '@fastify/otel';\n FastifyInstrumentationPlugin[Symbol.for('plugin-meta')] = {\n fastify: SUPPORTED_VERSIONS,\n name: '@fastify/otel',\n };\n\n return FastifyInstrumentationPlugin;\n\n function FastifyInstrumentationPlugin(instance, opts, done) {\n instance.decorate(kInstrumentation, instrumentation);\n // addHook and notfoundHandler are essentially inherited from the prototype\n // what is important is to bound it to the right instance\n instance.decorate(kAddHookOriginal, instance.addHook);\n instance.decorate(kSetNotFoundOriginal, instance.setNotFoundHandler);\n instance.decorateRequest('opentelemetry', function openetelemetry() {\n const ctx = this[kRequestContext];\n const span = this[kRequestSpan];\n return {\n span,\n tracer: instrumentation.tracer,\n context: ctx,\n inject: (carrier, setter) => {\n return propagation.inject(ctx, carrier, setter);\n },\n extract: (carrier, getter) => {\n return propagation.extract(ctx, carrier, getter);\n },\n };\n });\n instance.decorateRequest(kRequestSpan, null);\n instance.decorateRequest(kRequestContext, null);\n\n instance.addHook('onRoute', function (routeOptions) {\n if (instrumentation[kIgnorePaths]?.(routeOptions) === true) {\n instrumentation._logger.debug(\n `Ignoring route instrumentation ${routeOptions.method} ${routeOptions.url} because it matches the ignore path`,\n );\n return;\n }\n\n for (const hook of FASTIFY_HOOKS) {\n if (routeOptions[hook] != null) {\n const handlerLike = routeOptions[hook];\n\n if (typeof handlerLike === 'function') {\n routeOptions[hook] = handlerWrapper(handlerLike, {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - route -> ${hook}`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.ROUTE,\n [ATTR_HTTP_ROUTE]: routeOptions.url,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n handlerLike.name?.length > 0 ? handlerLike.name : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */,\n });\n } else if (Array.isArray(handlerLike)) {\n const wrappedHandlers = [];\n\n for (const handler of handlerLike) {\n wrappedHandlers.push(\n handlerWrapper(handler, {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - route -> ${hook}`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.ROUTE,\n [ATTR_HTTP_ROUTE]: routeOptions.url,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n handler.name?.length > 0 ? handler.name : ANONYMOUS_FUNCTION_NAME,\n }),\n );\n }\n\n routeOptions[hook] = wrappedHandlers;\n }\n }\n }\n\n // We always want to add the onSend hook to the route to be executed last\n if (routeOptions.onSend != null) {\n routeOptions.onSend = Array.isArray(routeOptions.onSend)\n ? [...routeOptions.onSend, onSendHook]\n : [routeOptions.onSend, onSendHook];\n } else {\n routeOptions.onSend = onSendHook;\n }\n\n // We always want to add the onError hook to the route to be executed last\n if (routeOptions.onError != null) {\n routeOptions.onError = Array.isArray(routeOptions.onError)\n ? [...routeOptions.onError, onErrorHook]\n : [routeOptions.onError, onErrorHook];\n } else {\n routeOptions.onError = onErrorHook;\n }\n\n routeOptions.handler = handlerWrapper(routeOptions.handler, {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - route-handler`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.HANDLER,\n [ATTR_HTTP_ROUTE]: routeOptions.url,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n routeOptions.handler.name.length > 0 ? routeOptions.handler.name : ANONYMOUS_FUNCTION_NAME,\n });\n });\n\n instance.addHook('onRequest', function (request, _reply, hookDone) {\n if (this[kInstrumentation].isEnabled() === false) {\n return hookDone();\n } else if (\n this[kInstrumentation][kIgnorePaths]?.({\n url: request.url,\n method: request.method,\n }) === true\n ) {\n this[kInstrumentation]._logger.debug(\n `Ignoring request ${request.method} ${request.url} because it matches the ignore path`,\n );\n return hookDone();\n }\n\n let ctx = context.active();\n\n if (trace.getSpan(ctx) == null) {\n ctx = propagation.extract(ctx, request.headers);\n }\n\n const rpcMetadata = getRPCMetadata(ctx);\n\n if (request.routeOptions.url != null && rpcMetadata?.type === RPCType.HTTP) {\n rpcMetadata.route = request.routeOptions.url;\n }\n\n /** @type {import('@opentelemetry/api').Span} */\n const span = this[kInstrumentation].tracer.startSpan(\n 'request',\n {\n attributes: {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.ROOT]: '@fastify/otel',\n [ATTR_HTTP_ROUTE]: request.url,\n [ATTR_HTTP_REQUEST_METHOD]: request.method,\n },\n },\n ctx,\n );\n\n request[kRequestContext] = trace.setSpan(ctx, span);\n request[kRequestSpan] = span;\n\n context.with(request[kRequestContext], () => {\n hookDone();\n });\n });\n\n // onResponse is the last hook to be executed, only added for 404 handlers\n instance.addHook('onResponse', function (request, reply, hookDone) {\n const span = request[kRequestSpan];\n\n if (span != null) {\n span.setStatus({\n code: SpanStatusCode.OK,\n message: 'OK',\n });\n span.setAttributes({\n [ATTR_HTTP_RESPONSE_STATUS_CODE]: 404,\n });\n span.end();\n }\n\n request[kRequestSpan] = null;\n\n hookDone();\n });\n\n instance.addHook = addHookPatched;\n instance.setNotFoundHandler = setNotFoundHandlerPatched;\n\n done();\n\n function onSendHook(request, reply, payload, hookDone) {\n /** @type {import('@opentelemetry/api').Span} */\n const span = request[kRequestSpan];\n\n if (span != null) {\n if (reply.statusCode < 500) {\n span.setStatus({\n code: SpanStatusCode.OK,\n message: 'OK',\n });\n }\n\n span.setAttributes({\n [ATTR_HTTP_RESPONSE_STATUS_CODE]: reply.statusCode,\n });\n span.end();\n }\n\n request[kRequestSpan] = null;\n\n hookDone(null, payload);\n }\n\n function onErrorHook(request, reply, error, hookDone) {\n /** @type {Span} */\n const span = request[kRequestSpan];\n\n if (span != null) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n });\n span.recordException(error);\n }\n\n hookDone();\n }\n\n function addHookPatched(name, hook) {\n const addHookOriginal = this[kAddHookOriginal];\n\n if (FASTIFY_HOOKS.includes(name)) {\n return addHookOriginal.call(\n this,\n name,\n handlerWrapper(hook, {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - ${name}`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n hook.name?.length > 0 ? hook.name : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */,\n }),\n );\n } else {\n return addHookOriginal.call(this, name, hook);\n }\n }\n\n function setNotFoundHandlerPatched(hooks, handler) {\n const setNotFoundHandlerOriginal = this[kSetNotFoundOriginal];\n if (typeof hooks === 'function') {\n handler = handlerWrapper(hooks, {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - not-found-handler`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n hooks.name?.length > 0 ? hooks.name : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */,\n });\n setNotFoundHandlerOriginal.call(this, handler);\n } else {\n if (hooks.preValidation != null) {\n hooks.preValidation = handlerWrapper(hooks.preValidation, {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - not-found-handler - preValidation`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n hooks.preValidation.name?.length > 0\n ? hooks.preValidation.name\n : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */,\n });\n }\n\n if (hooks.preHandler != null) {\n hooks.preHandler = handlerWrapper(hooks.preHandler, {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - not-found-handler - preHandler`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n hooks.preHandler.name?.length > 0\n ? hooks.preHandler.name\n : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */,\n });\n }\n\n handler = handlerWrapper(handler, {\n [ATTR_SERVICE_NAME]: instance[kInstrumentation].servername,\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - not-found-handler`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n handler.name?.length > 0 ? handler.name : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */,\n });\n setNotFoundHandlerOriginal.call(this, hooks, handler);\n }\n }\n\n function handlerWrapper(handler, spanAttributes = {}) {\n return function handlerWrapped(...args) {\n /** @type {FastifyOtelInstrumentation} */\n const instrumentation = this[kInstrumentation];\n const [request] = args;\n\n if (instrumentation.isEnabled() === false) {\n return handler.call(this, ...args);\n }\n\n const ctx = request[kRequestContext] ?? context.active();\n const span = instrumentation.tracer.startSpan(\n `handler - ${\n handler.name?.length > 0\n ? handler.name\n : this.pluginName /* c8 ignore next */ ?? ANONYMOUS_FUNCTION_NAME /* c8 ignore next */\n }`,\n {\n attributes: spanAttributes,\n },\n ctx,\n );\n\n return context.with(\n trace.setSpan(ctx, span),\n function () {\n try {\n const res = handler.call(this, ...args);\n\n if (typeof res?.then === 'function') {\n return res.then(\n result => {\n span.end();\n return result;\n },\n error => {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n });\n span.recordException(error);\n span.end();\n return Promise.reject(error);\n },\n );\n }\n\n span.end();\n return res;\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n });\n span.recordException(error);\n span.end();\n throw error;\n }\n },\n this,\n );\n };\n }\n }\n }\n}\n"],"names":["dc"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../../src/integrations/tracing/fastify/index.ts"],"sourcesContent":["import * as diagnosticsChannel from 'node:diagnostics_channel';\nimport type { Instrumentation, InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport type { IntegrationFn, Span } from '@sentry/core';\nimport {\n captureException,\n defineIntegration,\n getClient,\n getIsolationScope,\n logger,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n} from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node-core';\nimport { DEBUG_BUILD } from '../../../debug-build';\nimport { FastifyOtelInstrumentation } from './fastify-otel/index';\nimport type { FastifyInstance, FastifyReply, FastifyRequest } from './types';\nimport { FastifyInstrumentationV3 } from './v3/instrumentation';\n\ninterface FastifyHandlerOptions {\n /**\n * Callback method deciding whether error should be captured and sent to Sentry\n *\n * @param error Captured Fastify error\n * @param request Fastify request (or any object containing at least method, routeOptions.url, and routerPath)\n * @param reply Fastify reply (or any object containing at least statusCode)\n *\n * @example\n *\n * ```javascript\n * setupFastifyErrorHandler(app, {\n * shouldHandleError(_error, _request, reply) {\n * return reply.statusCode >= 400;\n * },\n * });\n * ```\n *\n * If using TypeScript, you can cast the request and reply to get full type safety.\n *\n * ```typescript\n * import type { FastifyRequest, FastifyReply } from 'fastify';\n *\n * setupFastifyErrorHandler(app, {\n * shouldHandleError(error, minimalRequest, minimalReply) {\n * const request = minimalRequest as FastifyRequest;\n * const reply = minimalReply as FastifyReply;\n * return reply.statusCode >= 500;\n * },\n * });\n * ```\n */\n shouldHandleError: (error: Error, request: FastifyRequest, reply: FastifyReply) => boolean;\n}\n\nconst INTEGRATION_NAME = 'Fastify';\nconst INTEGRATION_NAME_V3 = 'Fastify-V3';\n\nexport const instrumentFastifyV3 = generateInstrumentOnce(INTEGRATION_NAME_V3, () => new FastifyInstrumentationV3());\n\nfunction handleFastifyError(\n this: {\n diagnosticsChannelExists?: boolean;\n },\n error: Error,\n request: FastifyRequest & { opentelemetry?: () => { span?: Span } },\n reply: FastifyReply,\n shouldHandleError: (error: Error, request: FastifyRequest, reply: FastifyReply) => boolean,\n handlerOrigin: 'diagnostics-channel' | 'onError-hook',\n): void {\n // Diagnostics channel runs before the onError hook, so we can use it to check if the handler was already registered\n if (handlerOrigin === 'diagnostics-channel') {\n this.diagnosticsChannelExists = true;\n }\n\n if (this.diagnosticsChannelExists && handlerOrigin === 'onError-hook') {\n DEBUG_BUILD &&\n logger.warn(\n 'Fastify error handler was already registered via diagnostics channel.',\n 'You can safely remove `setupFastifyErrorHandler` call.',\n );\n\n // If the diagnostics channel already exists, we don't need to handle the error again\n return;\n }\n\n if (shouldHandleError(error, request, reply)) {\n captureException(error);\n }\n}\n\nexport const instrumentFastify = generateInstrumentOnce(INTEGRATION_NAME, () => {\n const fastifyOtelInstrumentationInstance = new FastifyOtelInstrumentation();\n const plugin = fastifyOtelInstrumentationInstance.plugin();\n const options = fastifyOtelInstrumentationInstance.getConfig();\n const shouldHandleError = (options as FastifyHandlerOptions)?.shouldHandleError || defaultShouldHandleError;\n\n // This message handler works for Fastify versions 3, 4 and 5\n diagnosticsChannel.subscribe('fastify.initialization', message => {\n const fastifyInstance = (message as { fastify?: FastifyInstance }).fastify;\n\n fastifyInstance?.register(plugin).after(err => {\n if (err) {\n DEBUG_BUILD && logger.error('Failed to setup Fastify instrumentation', err);\n } else {\n instrumentClient();\n\n if (fastifyInstance) {\n instrumentOnRequest(fastifyInstance);\n }\n }\n });\n });\n\n // This diagnostics channel only works on Fastify version 5\n // For versions 3 and 4, we use `setupFastifyErrorHandler` instead\n diagnosticsChannel.subscribe('tracing:fastify.request.handler:error', message => {\n const { error, request, reply } = message as {\n error: Error;\n request: FastifyRequest & { opentelemetry?: () => { span?: Span } };\n reply: FastifyReply;\n };\n\n handleFastifyError.call(handleFastifyError, error, request, reply, shouldHandleError, 'diagnostics-channel');\n });\n\n // Returning this as unknown not to deal with the internal types of the FastifyOtelInstrumentation\n return fastifyOtelInstrumentationInstance as Instrumentation<InstrumentationConfig & FastifyHandlerOptions>;\n});\n\nconst _fastifyIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentFastifyV3();\n instrumentFastify();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for [Fastify](https://fastify.dev/).\n *\n * If you also want to capture errors, you need to call `setupFastifyErrorHandler(app)` after you set up your Fastify server.\n *\n * For more information, see the [fastify documentation](https://docs.sentry.io/platforms/javascript/guides/fastify/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.fastifyIntegration()],\n * })\n * ```\n */\nexport const fastifyIntegration = defineIntegration(_fastifyIntegration);\n\n/**\n * Default function to determine if an error should be sent to Sentry\n *\n * 3xx and 4xx errors are not sent by default.\n */\nfunction defaultShouldHandleError(_error: Error, _request: FastifyRequest, reply: FastifyReply): boolean {\n const statusCode = reply.statusCode;\n // 3xx and 4xx errors are not sent by default.\n return statusCode >= 500 || statusCode <= 299;\n}\n\n/**\n * Add an Fastify error handler to capture errors to Sentry.\n *\n * @param fastify The Fastify instance to which to add the error handler\n * @param options Configuration options for the handler\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n * const Fastify = require(\"fastify\");\n *\n * const app = Fastify();\n *\n * Sentry.setupFastifyErrorHandler(app);\n *\n * // Add your routes, etc.\n *\n * app.listen({ port: 3000 });\n * ```\n */\nexport function setupFastifyErrorHandler(fastify: FastifyInstance, options?: Partial<FastifyHandlerOptions>): void {\n const shouldHandleError = options?.shouldHandleError || defaultShouldHandleError;\n const plugin = Object.assign(\n function (fastify: FastifyInstance, _options: unknown, done: () => void): void {\n fastify.addHook('onError', async (request, reply, error) => {\n handleFastifyError.call(handleFastifyError, error, request, reply, shouldHandleError, 'onError-hook');\n });\n done();\n },\n {\n [Symbol.for('skip-override')]: true,\n [Symbol.for('fastify.display-name')]: 'sentry-fastify-error-handler',\n },\n );\n\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n fastify.register(plugin);\n}\n\nfunction addFastifySpanAttributes(span: Span): void {\n const spanJSON = spanToJSON(span);\n const spanName = spanJSON.description;\n const attributes = spanJSON.data;\n\n const type = attributes['fastify.type'];\n\n const isHook = type === 'hook';\n const isHandler = type === spanName?.startsWith('handler -');\n // In @fastify/otel `request-handler` is separated by dash, not underscore\n const isRequestHandler = spanName === 'request' || type === 'request-handler';\n\n // If this is already set, or we have no fastify span, no need to process again...\n if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] || (!isHandler && !isRequestHandler && !isHook)) {\n return;\n }\n\n const opPrefix = isHook ? 'hook' : isHandler ? 'middleware' : isRequestHandler ? 'request-handler' : '<unknown>';\n\n span.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.otel.fastify',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${opPrefix}.fastify`,\n });\n\n const attrName = attributes['fastify.name'] || attributes['plugin.name'] || attributes['hook.name'];\n if (typeof attrName === 'string') {\n // Try removing `fastify -> ` and `@fastify/otel -> ` prefixes\n // This is a bit of a hack, and not always working for all spans\n // But it's the best we can do without a proper API\n const updatedName = attrName.replace(/^fastify -> /, '').replace(/^@fastify\\/otel -> /, '');\n\n span.updateName(updatedName);\n }\n}\n\nfunction instrumentClient(): void {\n const client = getClient();\n if (client) {\n client.on('spanStart', (span: Span) => {\n addFastifySpanAttributes(span);\n });\n }\n}\n\nfunction instrumentOnRequest(fastify: FastifyInstance): void {\n fastify.addHook('onRequest', async (request: FastifyRequest & { opentelemetry?: () => { span?: Span } }, _reply) => {\n if (request.opentelemetry) {\n const { span } = request.opentelemetry();\n\n if (span) {\n addFastifySpanAttributes(span);\n }\n }\n\n const routeName = request.routeOptions?.url;\n const method = request.method || 'GET';\n\n getIsolationScope().setTransactionName(`${method} ${routeName}`);\n });\n}\n"],"names":["diagnosticsChannel"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../../src/integrations/tracing/fastify/index.ts"],"sourcesContent":["import * as diagnosticsChannel from 'node:diagnostics_channel';\nimport type { Instrumentation, InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport type { IntegrationFn, Span } from '@sentry/core';\nimport {\n captureException,\n defineIntegration,\n getClient,\n getIsolationScope,\n logger,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n} from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node-core';\nimport { DEBUG_BUILD } from '../../../debug-build';\nimport { FastifyOtelInstrumentation } from './fastify-otel/index';\nimport type { FastifyInstance, FastifyReply, FastifyRequest } from './types';\nimport { FastifyInstrumentationV3 } from './v3/instrumentation';\n\ninterface FastifyHandlerOptions {\n /**\n * Callback method deciding whether error should be captured and sent to Sentry\n *\n * @param error Captured Fastify error\n * @param request Fastify request (or any object containing at least method, routeOptions.url, and routerPath)\n * @param reply Fastify reply (or any object containing at least statusCode)\n *\n * @example\n *\n * ```javascript\n * setupFastifyErrorHandler(app, {\n * shouldHandleError(_error, _request, reply) {\n * return reply.statusCode >= 400;\n * },\n * });\n * ```\n *\n * If using TypeScript, you can cast the request and reply to get full type safety.\n *\n * ```typescript\n * import type { FastifyRequest, FastifyReply } from 'fastify';\n *\n * setupFastifyErrorHandler(app, {\n * shouldHandleError(error, minimalRequest, minimalReply) {\n * const request = minimalRequest as FastifyRequest;\n * const reply = minimalReply as FastifyReply;\n * return reply.statusCode >= 500;\n * },\n * });\n * ```\n */\n shouldHandleError: (error: Error, request: FastifyRequest, reply: FastifyReply) => boolean;\n}\n\nconst INTEGRATION_NAME = 'Fastify';\nconst INTEGRATION_NAME_V3 = 'Fastify-V3';\n\nexport const instrumentFastifyV3 = generateInstrumentOnce(INTEGRATION_NAME_V3, () => new FastifyInstrumentationV3());\n\nfunction handleFastifyError(\n this: {\n diagnosticsChannelExists?: boolean;\n },\n error: Error,\n request: FastifyRequest & { opentelemetry?: () => { span?: Span } },\n reply: FastifyReply,\n shouldHandleError: (error: Error, request: FastifyRequest, reply: FastifyReply) => boolean,\n handlerOrigin: 'diagnostics-channel' | 'onError-hook',\n): void {\n // Diagnostics channel runs before the onError hook, so we can use it to check if the handler was already registered\n if (handlerOrigin === 'diagnostics-channel') {\n this.diagnosticsChannelExists = true;\n }\n\n if (this.diagnosticsChannelExists && handlerOrigin === 'onError-hook') {\n DEBUG_BUILD &&\n logger.warn(\n 'Fastify error handler was already registered via diagnostics channel.',\n 'You can safely remove `setupFastifyErrorHandler` call.',\n );\n\n // If the diagnostics channel already exists, we don't need to handle the error again\n return;\n }\n\n if (shouldHandleError(error, request, reply)) {\n captureException(error);\n }\n}\n\nexport const instrumentFastify = generateInstrumentOnce(INTEGRATION_NAME, () => {\n const fastifyOtelInstrumentationInstance = new FastifyOtelInstrumentation();\n const plugin = fastifyOtelInstrumentationInstance.plugin();\n const options = fastifyOtelInstrumentationInstance.getConfig();\n const shouldHandleError = (options as FastifyHandlerOptions)?.shouldHandleError || defaultShouldHandleError;\n\n // This message handler works for Fastify versions 3, 4 and 5\n diagnosticsChannel.subscribe('fastify.initialization', message => {\n const fastifyInstance = (message as { fastify?: FastifyInstance }).fastify;\n\n fastifyInstance?.register(plugin).after(err => {\n if (err) {\n DEBUG_BUILD && logger.error('Failed to setup Fastify instrumentation', err);\n } else {\n instrumentClient();\n\n if (fastifyInstance) {\n instrumentOnRequest(fastifyInstance);\n }\n }\n });\n });\n\n // This diagnostics channel only works on Fastify version 5\n // For versions 3 and 4, we use `setupFastifyErrorHandler` instead\n diagnosticsChannel.subscribe('tracing:fastify.request.handler:error', message => {\n const { error, request, reply } = message as {\n error: Error;\n request: FastifyRequest & { opentelemetry?: () => { span?: Span } };\n reply: FastifyReply;\n };\n\n handleFastifyError.call(handleFastifyError, error, request, reply, shouldHandleError, 'diagnostics-channel');\n });\n\n // Returning this as unknown not to deal with the internal types of the FastifyOtelInstrumentation\n return fastifyOtelInstrumentationInstance as Instrumentation<InstrumentationConfig & FastifyHandlerOptions>;\n});\n\nconst _fastifyIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentFastifyV3();\n instrumentFastify();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for [Fastify](https://fastify.dev/).\n *\n * If you also want to capture errors, you need to call `setupFastifyErrorHandler(app)` after you set up your Fastify server.\n *\n * For more information, see the [fastify documentation](https://docs.sentry.io/platforms/javascript/guides/fastify/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.fastifyIntegration()],\n * })\n * ```\n */\nexport const fastifyIntegration = defineIntegration(_fastifyIntegration);\n\n/**\n * Default function to determine if an error should be sent to Sentry\n *\n * 3xx and 4xx errors are not sent by default.\n */\nfunction defaultShouldHandleError(_error: Error, _request: FastifyRequest, reply: FastifyReply): boolean {\n const statusCode = reply.statusCode;\n // 3xx and 4xx errors are not sent by default.\n return statusCode >= 500 || statusCode <= 299;\n}\n\n/**\n * Add an Fastify error handler to capture errors to Sentry.\n *\n * @param fastify The Fastify instance to which to add the error handler\n * @param options Configuration options for the handler\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n * const Fastify = require(\"fastify\");\n *\n * const app = Fastify();\n *\n * Sentry.setupFastifyErrorHandler(app);\n *\n * // Add your routes, etc.\n *\n * app.listen({ port: 3000 });\n * ```\n */\nexport function setupFastifyErrorHandler(fastify: FastifyInstance, options?: Partial<FastifyHandlerOptions>): void {\n const shouldHandleError = options?.shouldHandleError || defaultShouldHandleError;\n const plugin = Object.assign(\n function (fastify: FastifyInstance, _options: unknown, done: () => void): void {\n fastify.addHook('onError', async (request, reply, error) => {\n handleFastifyError.call(handleFastifyError, error, request, reply, shouldHandleError, 'onError-hook');\n });\n done();\n },\n {\n [Symbol.for('skip-override')]: true,\n [Symbol.for('fastify.display-name')]: 'sentry-fastify-error-handler',\n },\n );\n\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n fastify.register(plugin);\n}\n\nfunction addFastifySpanAttributes(span: Span): void {\n const spanJSON = spanToJSON(span);\n const spanName = spanJSON.description;\n const attributes = spanJSON.data;\n\n const type = attributes['fastify.type'];\n\n const isHook = type === 'hook';\n const isHandler = type === spanName?.startsWith('handler -');\n // In @fastify/otel `request-handler` is separated by dash, not underscore\n const isRequestHandler = spanName === 'request' || type === 'request-handler';\n\n // If this is already set, or we have no fastify span, no need to process again...\n if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] || (!isHandler && !isRequestHandler && !isHook)) {\n return;\n }\n\n const opPrefix = isHook ? 'hook' : isHandler ? 'middleware' : isRequestHandler ? 'request-handler' : '<unknown>';\n\n span.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.otel.fastify',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${opPrefix}.fastify`,\n });\n\n const attrName = attributes['fastify.name'] || attributes['plugin.name'] || attributes['hook.name'];\n if (typeof attrName === 'string') {\n // Try removing `fastify -> ` and `@fastify/otel -> ` prefixes\n // This is a bit of a hack, and not always working for all spans\n // But it's the best we can do without a proper API\n const updatedName = attrName.replace(/^fastify -> /, '').replace(/^@fastify\\/otel -> /, '');\n\n span.updateName(updatedName);\n }\n}\n\nfunction instrumentClient(): void {\n const client = getClient();\n if (client) {\n client.on('spanStart', (span: Span) => {\n addFastifySpanAttributes(span);\n });\n }\n}\n\nfunction instrumentOnRequest(fastify: FastifyInstance): void {\n fastify.addHook('onRequest', async (request: FastifyRequest & { opentelemetry?: () => { span?: Span } }, _reply) => {\n if (request.opentelemetry) {\n const { span } = request.opentelemetry();\n\n if (span) {\n addFastifySpanAttributes(span);\n }\n }\n\n const routeName = request.routeOptions?.url;\n const method = request.method || 'GET';\n\n getIsolationScope().setTransactionName(`${method} ${routeName}`);\n });\n}\n"],"names":["diagnosticsChannel"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sources":["../../../../../../src/integrations/tracing/fastify/v3/constants.ts"],"sourcesContent":["// Vendored from https://github.com/open-telemetry/opentelemetry-js-contrib/blob/407f61591ba69a39a6908264379d4d98a48dbec4/plugins/node/opentelemetry-instrumentation-fastify/src/constants.ts\n/*\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\nexport const spanRequestSymbol = Symbol('opentelemetry.instrumentation.fastify.request_active_span');\n\n// The instrumentation creates a span for invocations of lifecycle hook handlers\n// that take `(request, reply, ...[, done])` arguments. Currently this is all\n// lifecycle hooks except `onRequestAbort`.\n// https://fastify.dev/docs/latest/Reference/Hooks\nexport const hooksNamesToWrap = new Set([\n 'onTimeout',\n 'onRequest',\n 'preParsing',\n 'preValidation',\n 'preSerialization',\n 'preHandler',\n 'onSend',\n 'onResponse',\n 'onError',\n]);\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;MAEa,iBAAkB,GAAE,MAAM,CAAC,2DAA2D;;;;"}
1
+ {"version":3,"file":"constants.js","sources":["../../../../../../src/integrations/tracing/fastify/v3/constants.ts"],"sourcesContent":["// Vendored from https://github.com/open-telemetry/opentelemetry-js-contrib/blob/407f61591ba69a39a6908264379d4d98a48dbec4/plugins/node/opentelemetry-instrumentation-fastify/src/constants.ts\n/*\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\nexport const spanRequestSymbol = Symbol('opentelemetry.instrumentation.fastify.request_active_span');\n\n// The instrumentation creates a span for invocations of lifecycle hook handlers\n// that take `(request, reply, ...[, done])` arguments. Currently this is all\n// lifecycle hooks except `onRequestAbort`.\n// https://fastify.dev/docs/latest/Reference/Hooks\nexport const hooksNamesToWrap = new Set([\n 'onTimeout',\n 'onRequest',\n 'preParsing',\n 'preValidation',\n 'preSerialization',\n 'preHandler',\n 'onSend',\n 'onResponse',\n 'onError',\n]);\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;MAEa,iBAAA,GAAoB,MAAM,CAAC,2DAA2D;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"AttributeNames.js","sources":["../../../../../../../src/integrations/tracing/fastify/v3/enums/AttributeNames.ts"],"sourcesContent":["// Vendored from https://github.com/open-telemetry/opentelemetry-js-contrib/blob/407f61591ba69a39a6908264379d4d98a48dbec4/plugins/node/opentelemetry-instrumentation-fastify/src/enums/AttributeNames.ts\n//\n/*\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\nexport enum AttributeNames {\n FASTIFY_NAME = 'fastify.name',\n FASTIFY_TYPE = 'fastify.type',\n HOOK_NAME = 'hook.name',\n PLUGIN_NAME = 'plugin.name',\n}\n\nexport enum FastifyTypes {\n MIDDLEWARE = 'middleware',\n REQUEST_HANDLER = 'request_handler',\n}\n\nexport enum FastifyNames {\n MIDDLEWARE = 'middleware',\n REQUEST_HANDLER = 'request handler',\n}\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAE2B,IAAA,eAAA,CAAA,CAAA,UAAA,cAAA,EAAA;AAC3B,EAAE,MAAA,YAAA,GAAe,cAAc,CAAA,CAAA,cAAA,CAAA,cAAA,CAAA,GAAA,YAAA;AAC/B,EAAE,MAAA,YAAA,GAAe,cAAc,CAAA,CAAA,cAAA,CAAA,cAAA,CAAA,GAAA,YAAA;AAC/B,EAAE,MAAA,SAAA,GAAY,WAAW,CAAA,CAAA,cAAA,CAAA,WAAA,CAAA,GAAA,SAAA;AACzB,EAAE,MAAA,WAAA,GAAc,aAAa,CAAA,CAAA,cAAA,CAAA,aAAA,CAAA,GAAA,WAAA;AAC7B,CAAA,EAAA,cAAA,KAAA,cAAA,GAAA,EAAA,CAAA,CAAA;;AAEyB,IAAA,aAAA,CAAA,CAAA,UAAA,YAAA,EAAA;AACzB,EAAE,MAAA,UAAA,GAAa,YAAY,CAAA,CAAA,YAAA,CAAA,YAAA,CAAA,GAAA,UAAA;AAC3B,EAAE,MAAA,eAAA,GAAkB,iBAAiB,CAAA,CAAA,YAAA,CAAA,iBAAA,CAAA,GAAA,eAAA;AACrC,CAAA,EAAA,YAAA,KAAA,YAAA,GAAA,EAAA,CAAA,CAAA;;AAEyB,IAAA,aAAA,CAAA,CAAA,UAAA,YAAA,EAAA;AACzB,EAAE,MAAA,UAAA,GAAa,YAAY,CAAA,CAAA,YAAA,CAAA,YAAA,CAAA,GAAA,UAAA;AAC3B,EAAE,MAAA,eAAA,GAAkB,iBAAiB,CAAA,CAAA,YAAA,CAAA,iBAAA,CAAA,GAAA,eAAA;AACrC,CAAA,EAAA,YAAA,KAAA,YAAA,GAAA,EAAA,CAAA,CAAA;;;;"}
1
+ {"version":3,"file":"AttributeNames.js","sources":["../../../../../../../src/integrations/tracing/fastify/v3/enums/AttributeNames.ts"],"sourcesContent":["// Vendored from https://github.com/open-telemetry/opentelemetry-js-contrib/blob/407f61591ba69a39a6908264379d4d98a48dbec4/plugins/node/opentelemetry-instrumentation-fastify/src/enums/AttributeNames.ts\n//\n/*\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\nexport enum AttributeNames {\n FASTIFY_NAME = 'fastify.name',\n FASTIFY_TYPE = 'fastify.type',\n HOOK_NAME = 'hook.name',\n PLUGIN_NAME = 'plugin.name',\n}\n\nexport enum FastifyTypes {\n MIDDLEWARE = 'middleware',\n REQUEST_HANDLER = 'request_handler',\n}\n\nexport enum FastifyNames {\n MIDDLEWARE = 'middleware',\n REQUEST_HANDLER = 'request handler',\n}\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,IAAA,eAAA,CAAA,CAAA,UAAA,cAAA,EAA2B;AAC3B,EAAE,MAAA,YAAA,GAAe,cAAA,CAAA,CAAA,cAAA,CAAA,cAAA,CAAA,GAAA,YAAA;AACjB,EAAE,MAAA,YAAA,GAAe,cAAA,CAAA,CAAA,cAAA,CAAA,cAAA,CAAA,GAAA,YAAA;AACjB,EAAE,MAAA,SAAA,GAAY,WAAA,CAAA,CAAA,cAAA,CAAA,WAAA,CAAA,GAAA,SAAA;AACd,EAAE,MAAA,WAAA,GAAc,aAAA,CAAA,CAAA,cAAA,CAAA,aAAA,CAAA,GAAA,WAAA;AAChB,CAAA,EAAA,cAAA,KAAA,cAAA,GAAA,EAAA,CAAA,CAAA;;AAEA,IAAA,aAAA,CAAA,CAAA,UAAA,YAAA,EAAyB;AACzB,EAAE,MAAA,UAAA,GAAa,YAAA,CAAA,CAAA,YAAA,CAAA,YAAA,CAAA,GAAA,UAAA;AACf,EAAE,MAAA,eAAA,GAAkB,iBAAA,CAAA,CAAA,YAAA,CAAA,iBAAA,CAAA,GAAA,eAAA;AACpB,CAAA,EAAA,YAAA,KAAA,YAAA,GAAA,EAAA,CAAA,CAAA;;AAEA,IAAA,aAAA,CAAA,CAAA,UAAA,YAAA,EAAyB;AACzB,EAAE,MAAA,UAAA,GAAa,YAAA,CAAA,CAAA,YAAA,CAAA,YAAA,CAAA,GAAA,UAAA;AACf,EAAE,MAAA,eAAA,GAAkB,iBAAA,CAAA,CAAA,YAAA,CAAA,iBAAA,CAAA,GAAA,eAAA;AACpB,CAAA,EAAA,YAAA,KAAA,YAAA,GAAA,EAAA,CAAA,CAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentation.js","sources":["../../../../../../src/integrations/tracing/fastify/v3/instrumentation.ts"],"sourcesContent":["// Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/blob/407f61591ba69a39a6908264379d4d98a48dbec4/plugins/node/opentelemetry-instrumentation-fastify/src/instrumentation.ts\n/* eslint-disable @typescript-eslint/no-this-alias */\n/* eslint-disable jsdoc/require-jsdoc */\n/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n\n/*\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 { type Attributes, context, SpanStatusCode, trace } from '@opentelemetry/api';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\nimport { SEMATTRS_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport type { Span } from '@sentry/core';\nimport {\n getClient,\n getIsolationScope,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n} from '@sentry/core';\nimport type {\n FastifyErrorCodes,\n FastifyInstance,\n FastifyReply,\n FastifyRequest,\n HandlerOriginal,\n HookHandlerDoneFunction,\n} from '../types';\nimport { AttributeNames, FastifyNames, FastifyTypes } from './enums/AttributeNames';\nimport type { PluginFastifyReply } from './internal-types';\nimport type { FastifyInstrumentationConfig } from './types';\nimport { endSpan, safeExecuteInTheMiddleMaybePromise, startSpan } from './utils';\n/** @knipignore */\n\nconst PACKAGE_VERSION = '0.1.0';\n\nconst PACKAGE_NAME = '@sentry/instrumentation-fastify-v3';\nconst ANONYMOUS_NAME = 'anonymous';\n\n// The instrumentation creates a span for invocations of lifecycle hook handlers\n// that take `(request, reply, ...[, done])` arguments. Currently this is all\n// lifecycle hooks except `onRequestAbort`.\n// https://fastify.dev/docs/latest/Reference/Hooks\nconst hooksNamesToWrap = new Set([\n 'onTimeout',\n 'onRequest',\n 'preParsing',\n 'preValidation',\n 'preSerialization',\n 'preHandler',\n 'onSend',\n 'onResponse',\n 'onError',\n]);\n\n/**\n * Fastify instrumentation for OpenTelemetry\n */\nexport class FastifyInstrumentationV3 extends InstrumentationBase<FastifyInstrumentationConfig> {\n public constructor(config: FastifyInstrumentationConfig = {}) {\n super(PACKAGE_NAME, PACKAGE_VERSION, config);\n }\n\n public init(): InstrumentationNodeModuleDefinition[] {\n return [\n new InstrumentationNodeModuleDefinition('fastify', ['>=3.0.0 <4'], moduleExports => {\n return this._patchConstructor(moduleExports);\n }),\n ];\n }\n\n private _hookOnRequest() {\n const instrumentation = this;\n\n return function onRequest(request: FastifyRequest, reply: FastifyReply, done: HookHandlerDoneFunction) {\n if (!instrumentation.isEnabled()) {\n return done();\n }\n instrumentation._wrap(reply, 'send', instrumentation._patchSend());\n\n const anyRequest = request as any;\n\n const rpcMetadata = getRPCMetadata(context.active());\n const routeName = anyRequest.routeOptions\n ? anyRequest.routeOptions.url // since fastify@4.10.0\n : request.routerPath;\n if (routeName && rpcMetadata?.type === RPCType.HTTP) {\n rpcMetadata.route = routeName;\n }\n\n const method = request.method || 'GET';\n\n getIsolationScope().setTransactionName(`${method} ${routeName}`);\n done();\n };\n }\n\n private _wrapHandler(\n pluginName: string,\n hookName: string,\n original: HandlerOriginal,\n syncFunctionWithDone: boolean,\n ): () => Promise<unknown> {\n const instrumentation = this;\n this._diag.debug('Patching fastify route.handler function');\n\n return function (this: any, ...args: unknown[]): Promise<unknown> {\n if (!instrumentation.isEnabled()) {\n return original.apply(this, args);\n }\n\n const name = original.name || pluginName || ANONYMOUS_NAME;\n const spanName = `${FastifyNames.MIDDLEWARE} - ${name}`;\n\n const reply = args[1] as PluginFastifyReply;\n\n const span = startSpan(reply, instrumentation.tracer, spanName, {\n [AttributeNames.FASTIFY_TYPE]: FastifyTypes.MIDDLEWARE,\n [AttributeNames.PLUGIN_NAME]: pluginName,\n [AttributeNames.HOOK_NAME]: hookName,\n });\n\n const origDone = syncFunctionWithDone && (args[args.length - 1] as HookHandlerDoneFunction);\n if (origDone) {\n args[args.length - 1] = function (...doneArgs: Parameters<HookHandlerDoneFunction>) {\n endSpan(reply);\n origDone.apply(this, doneArgs);\n };\n }\n\n return context.with(trace.setSpan(context.active(), span), () => {\n return safeExecuteInTheMiddleMaybePromise(\n () => {\n return original.apply(this, args);\n },\n err => {\n if (err instanceof Error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: err.message,\n });\n span.recordException(err);\n }\n // async hooks should end the span as soon as the promise is resolved\n if (!syncFunctionWithDone) {\n endSpan(reply);\n }\n },\n );\n });\n };\n }\n\n private _wrapAddHook(): (original: FastifyInstance['addHook']) => () => FastifyInstance {\n const instrumentation = this;\n this._diag.debug('Patching fastify server.addHook function');\n\n // biome-ignore lint/complexity/useArrowFunction: <explanation>\n return function (original: FastifyInstance['addHook']): () => FastifyInstance {\n return function wrappedAddHook(this: any, ...args: any) {\n const name = args[0] as string;\n const handler = args[1] as HandlerOriginal;\n const pluginName = this.pluginName;\n if (!hooksNamesToWrap.has(name)) {\n return original.apply(this, args);\n }\n\n const syncFunctionWithDone =\n typeof args[args.length - 1] === 'function' && handler.constructor.name !== 'AsyncFunction';\n\n return original.apply(this, [\n name,\n instrumentation._wrapHandler(pluginName, name, handler, syncFunctionWithDone),\n ] as never);\n };\n };\n }\n\n private _patchConstructor(moduleExports: {\n fastify: () => FastifyInstance;\n errorCodes: FastifyErrorCodes | undefined;\n }): () => FastifyInstance {\n const instrumentation = this;\n\n function fastify(this: FastifyInstance, ...args: any) {\n const app: FastifyInstance = moduleExports.fastify.apply(this, args);\n app.addHook('onRequest', instrumentation._hookOnRequest());\n app.addHook('preHandler', instrumentation._hookPreHandler());\n\n instrumentClient();\n\n instrumentation._wrap(app, 'addHook', instrumentation._wrapAddHook());\n\n return app;\n }\n\n if (moduleExports.errorCodes !== undefined) {\n fastify.errorCodes = moduleExports.errorCodes;\n }\n fastify.fastify = fastify;\n fastify.default = fastify;\n return fastify;\n }\n\n private _patchSend() {\n const instrumentation = this;\n this._diag.debug('Patching fastify reply.send function');\n\n return function patchSend(original: () => FastifyReply): () => FastifyReply {\n return function send(this: FastifyReply, ...args: any) {\n const maybeError: any = args[0];\n\n if (!instrumentation.isEnabled()) {\n return original.apply(this, args);\n }\n\n return safeExecuteInTheMiddle<FastifyReply>(\n () => {\n return original.apply(this, args);\n },\n err => {\n if (!err && maybeError instanceof Error) {\n // eslint-disable-next-line no-param-reassign\n err = maybeError;\n }\n endSpan(this, err);\n },\n );\n };\n };\n }\n\n private _hookPreHandler() {\n const instrumentation = this;\n this._diag.debug('Patching fastify preHandler function');\n\n return function preHandler(this: any, request: FastifyRequest, reply: FastifyReply, done: HookHandlerDoneFunction) {\n if (!instrumentation.isEnabled()) {\n return done();\n }\n const anyRequest = request as any;\n\n const handler = anyRequest.routeOptions?.handler || anyRequest.context?.handler;\n const handlerName = handler?.name.startsWith('bound ') ? handler.name.substring(6) : handler?.name;\n const spanName = `${FastifyNames.REQUEST_HANDLER} - ${handlerName || this.pluginName || ANONYMOUS_NAME}`;\n\n const spanAttributes: Attributes = {\n [AttributeNames.PLUGIN_NAME]: this.pluginName,\n [AttributeNames.FASTIFY_TYPE]: FastifyTypes.REQUEST_HANDLER,\n // eslint-disable-next-line deprecation/deprecation\n [SEMATTRS_HTTP_ROUTE]: anyRequest.routeOptions\n ? anyRequest.routeOptions.url // since fastify@4.10.0\n : request.routerPath,\n };\n if (handlerName) {\n spanAttributes[AttributeNames.FASTIFY_NAME] = handlerName;\n }\n const span = startSpan(reply, instrumentation.tracer, spanName, spanAttributes);\n\n addFastifyV3SpanAttributes(span);\n\n const { requestHook } = instrumentation.getConfig();\n if (requestHook) {\n safeExecuteInTheMiddle(\n () => requestHook(span, { request }),\n e => {\n if (e) {\n instrumentation._diag.error('request hook failed', e);\n }\n },\n true,\n );\n }\n\n return context.with(trace.setSpan(context.active(), span), () => {\n done();\n });\n };\n }\n}\n\nfunction instrumentClient(): void {\n const client = getClient();\n if (client) {\n client.on('spanStart', (span: Span) => {\n addFastifyV3SpanAttributes(span);\n });\n }\n}\n\nfunction addFastifyV3SpanAttributes(span: Span): void {\n const attributes = spanToJSON(span).data;\n\n // this is one of: middleware, request_handler\n const type = attributes['fastify.type'];\n\n // If this is already set, or we have no fastify span, no need to process again...\n if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] || !type) {\n return;\n }\n\n span.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.otel.fastify',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${type}.fastify`,\n });\n\n // Also update the name, we don't need to \"middleware - \" prefix\n const name = attributes['fastify.name'] || attributes['plugin.name'] || attributes['hook.name'];\n if (typeof name === 'string') {\n // Try removing `fastify -> ` and `@fastify/otel -> ` prefixes\n // This is a bit of a hack, and not always working for all spans\n // But it's the best we can do without a proper API\n const updatedName = name.replace(/^fastify -> /, '').replace(/^@fastify\\/otel -> /, '');\n\n span.updateName(updatedName);\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"instrumentation.js","sources":["../../../../../../src/integrations/tracing/fastify/v3/instrumentation.ts"],"sourcesContent":["// Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/blob/407f61591ba69a39a6908264379d4d98a48dbec4/plugins/node/opentelemetry-instrumentation-fastify/src/instrumentation.ts\n/* eslint-disable @typescript-eslint/no-this-alias */\n/* eslint-disable jsdoc/require-jsdoc */\n/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n\n/*\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 { type Attributes, context, SpanStatusCode, trace } from '@opentelemetry/api';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\nimport { SEMATTRS_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport type { Span } from '@sentry/core';\nimport {\n getClient,\n getIsolationScope,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n} from '@sentry/core';\nimport type {\n FastifyErrorCodes,\n FastifyInstance,\n FastifyReply,\n FastifyRequest,\n HandlerOriginal,\n HookHandlerDoneFunction,\n} from '../types';\nimport { AttributeNames, FastifyNames, FastifyTypes } from './enums/AttributeNames';\nimport type { PluginFastifyReply } from './internal-types';\nimport type { FastifyInstrumentationConfig } from './types';\nimport { endSpan, safeExecuteInTheMiddleMaybePromise, startSpan } from './utils';\n/** @knipignore */\n\nconst PACKAGE_VERSION = '0.1.0';\n\nconst PACKAGE_NAME = '@sentry/instrumentation-fastify-v3';\nconst ANONYMOUS_NAME = 'anonymous';\n\n// The instrumentation creates a span for invocations of lifecycle hook handlers\n// that take `(request, reply, ...[, done])` arguments. Currently this is all\n// lifecycle hooks except `onRequestAbort`.\n// https://fastify.dev/docs/latest/Reference/Hooks\nconst hooksNamesToWrap = new Set([\n 'onTimeout',\n 'onRequest',\n 'preParsing',\n 'preValidation',\n 'preSerialization',\n 'preHandler',\n 'onSend',\n 'onResponse',\n 'onError',\n]);\n\n/**\n * Fastify instrumentation for OpenTelemetry\n */\nexport class FastifyInstrumentationV3 extends InstrumentationBase<FastifyInstrumentationConfig> {\n public constructor(config: FastifyInstrumentationConfig = {}) {\n super(PACKAGE_NAME, PACKAGE_VERSION, config);\n }\n\n public init(): InstrumentationNodeModuleDefinition[] {\n return [\n new InstrumentationNodeModuleDefinition('fastify', ['>=3.0.0 <4'], moduleExports => {\n return this._patchConstructor(moduleExports);\n }),\n ];\n }\n\n private _hookOnRequest() {\n const instrumentation = this;\n\n return function onRequest(request: FastifyRequest, reply: FastifyReply, done: HookHandlerDoneFunction) {\n if (!instrumentation.isEnabled()) {\n return done();\n }\n instrumentation._wrap(reply, 'send', instrumentation._patchSend());\n\n const anyRequest = request as any;\n\n const rpcMetadata = getRPCMetadata(context.active());\n const routeName = anyRequest.routeOptions\n ? anyRequest.routeOptions.url // since fastify@4.10.0\n : request.routerPath;\n if (routeName && rpcMetadata?.type === RPCType.HTTP) {\n rpcMetadata.route = routeName;\n }\n\n const method = request.method || 'GET';\n\n getIsolationScope().setTransactionName(`${method} ${routeName}`);\n done();\n };\n }\n\n private _wrapHandler(\n pluginName: string,\n hookName: string,\n original: HandlerOriginal,\n syncFunctionWithDone: boolean,\n ): () => Promise<unknown> {\n const instrumentation = this;\n this._diag.debug('Patching fastify route.handler function');\n\n return function (this: any, ...args: unknown[]): Promise<unknown> {\n if (!instrumentation.isEnabled()) {\n return original.apply(this, args);\n }\n\n const name = original.name || pluginName || ANONYMOUS_NAME;\n const spanName = `${FastifyNames.MIDDLEWARE} - ${name}`;\n\n const reply = args[1] as PluginFastifyReply;\n\n const span = startSpan(reply, instrumentation.tracer, spanName, {\n [AttributeNames.FASTIFY_TYPE]: FastifyTypes.MIDDLEWARE,\n [AttributeNames.PLUGIN_NAME]: pluginName,\n [AttributeNames.HOOK_NAME]: hookName,\n });\n\n const origDone = syncFunctionWithDone && (args[args.length - 1] as HookHandlerDoneFunction);\n if (origDone) {\n args[args.length - 1] = function (...doneArgs: Parameters<HookHandlerDoneFunction>) {\n endSpan(reply);\n origDone.apply(this, doneArgs);\n };\n }\n\n return context.with(trace.setSpan(context.active(), span), () => {\n return safeExecuteInTheMiddleMaybePromise(\n () => {\n return original.apply(this, args);\n },\n err => {\n if (err instanceof Error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: err.message,\n });\n span.recordException(err);\n }\n // async hooks should end the span as soon as the promise is resolved\n if (!syncFunctionWithDone) {\n endSpan(reply);\n }\n },\n );\n });\n };\n }\n\n private _wrapAddHook(): (original: FastifyInstance['addHook']) => () => FastifyInstance {\n const instrumentation = this;\n this._diag.debug('Patching fastify server.addHook function');\n\n // biome-ignore lint/complexity/useArrowFunction: <explanation>\n return function (original: FastifyInstance['addHook']): () => FastifyInstance {\n return function wrappedAddHook(this: any, ...args: any) {\n const name = args[0] as string;\n const handler = args[1] as HandlerOriginal;\n const pluginName = this.pluginName;\n if (!hooksNamesToWrap.has(name)) {\n return original.apply(this, args);\n }\n\n const syncFunctionWithDone =\n typeof args[args.length - 1] === 'function' && handler.constructor.name !== 'AsyncFunction';\n\n return original.apply(this, [\n name,\n instrumentation._wrapHandler(pluginName, name, handler, syncFunctionWithDone),\n ] as never);\n };\n };\n }\n\n private _patchConstructor(moduleExports: {\n fastify: () => FastifyInstance;\n errorCodes: FastifyErrorCodes | undefined;\n }): () => FastifyInstance {\n const instrumentation = this;\n\n function fastify(this: FastifyInstance, ...args: any) {\n const app: FastifyInstance = moduleExports.fastify.apply(this, args);\n app.addHook('onRequest', instrumentation._hookOnRequest());\n app.addHook('preHandler', instrumentation._hookPreHandler());\n\n instrumentClient();\n\n instrumentation._wrap(app, 'addHook', instrumentation._wrapAddHook());\n\n return app;\n }\n\n if (moduleExports.errorCodes !== undefined) {\n fastify.errorCodes = moduleExports.errorCodes;\n }\n fastify.fastify = fastify;\n fastify.default = fastify;\n return fastify;\n }\n\n private _patchSend() {\n const instrumentation = this;\n this._diag.debug('Patching fastify reply.send function');\n\n return function patchSend(original: () => FastifyReply): () => FastifyReply {\n return function send(this: FastifyReply, ...args: any) {\n const maybeError: any = args[0];\n\n if (!instrumentation.isEnabled()) {\n return original.apply(this, args);\n }\n\n return safeExecuteInTheMiddle<FastifyReply>(\n () => {\n return original.apply(this, args);\n },\n err => {\n if (!err && maybeError instanceof Error) {\n // eslint-disable-next-line no-param-reassign\n err = maybeError;\n }\n endSpan(this, err);\n },\n );\n };\n };\n }\n\n private _hookPreHandler() {\n const instrumentation = this;\n this._diag.debug('Patching fastify preHandler function');\n\n return function preHandler(this: any, request: FastifyRequest, reply: FastifyReply, done: HookHandlerDoneFunction) {\n if (!instrumentation.isEnabled()) {\n return done();\n }\n const anyRequest = request as any;\n\n const handler = anyRequest.routeOptions?.handler || anyRequest.context?.handler;\n const handlerName = handler?.name.startsWith('bound ') ? handler.name.substring(6) : handler?.name;\n const spanName = `${FastifyNames.REQUEST_HANDLER} - ${handlerName || this.pluginName || ANONYMOUS_NAME}`;\n\n const spanAttributes: Attributes = {\n [AttributeNames.PLUGIN_NAME]: this.pluginName,\n [AttributeNames.FASTIFY_TYPE]: FastifyTypes.REQUEST_HANDLER,\n // eslint-disable-next-line deprecation/deprecation\n [SEMATTRS_HTTP_ROUTE]: anyRequest.routeOptions\n ? anyRequest.routeOptions.url // since fastify@4.10.0\n : request.routerPath,\n };\n if (handlerName) {\n spanAttributes[AttributeNames.FASTIFY_NAME] = handlerName;\n }\n const span = startSpan(reply, instrumentation.tracer, spanName, spanAttributes);\n\n addFastifyV3SpanAttributes(span);\n\n const { requestHook } = instrumentation.getConfig();\n if (requestHook) {\n safeExecuteInTheMiddle(\n () => requestHook(span, { request }),\n e => {\n if (e) {\n instrumentation._diag.error('request hook failed', e);\n }\n },\n true,\n );\n }\n\n return context.with(trace.setSpan(context.active(), span), () => {\n done();\n });\n };\n }\n}\n\nfunction instrumentClient(): void {\n const client = getClient();\n if (client) {\n client.on('spanStart', (span: Span) => {\n addFastifyV3SpanAttributes(span);\n });\n }\n}\n\nfunction addFastifyV3SpanAttributes(span: Span): void {\n const attributes = spanToJSON(span).data;\n\n // this is one of: middleware, request_handler\n const type = attributes['fastify.type'];\n\n // If this is already set, or we have no fastify span, no need to process again...\n if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] || !type) {\n return;\n }\n\n span.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.otel.fastify',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${type}.fastify`,\n });\n\n // Also update the name, we don't need to \"middleware - \" prefix\n const name = attributes['fastify.name'] || attributes['plugin.name'] || attributes['hook.name'];\n if (typeof name === 'string') {\n // Try removing `fastify -> ` and `@fastify/otel -> ` prefixes\n // This is a bit of a hack, and not always working for all spans\n // But it's the best we can do without a proper API\n const updatedName = name.replace(/^fastify -> /, '').replace(/^@fastify\\/otel -> /, '');\n\n span.updateName(updatedName);\n }\n}\n"],"names":[],"mappings":"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"}