@sentry/node 10.13.0 → 10.15.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 (55) hide show
  1. package/build/cjs/index.js +18 -15
  2. package/build/cjs/index.js.map +1 -1
  3. package/build/cjs/integrations/tracing/fastify/index.js +1 -1
  4. package/build/cjs/integrations/tracing/fastify/index.js.map +1 -1
  5. package/build/cjs/integrations/tracing/firebase/firebase.js +1 -1
  6. package/build/cjs/integrations/tracing/firebase/firebase.js.map +1 -1
  7. package/build/cjs/integrations/tracing/google-genai/instrumentation.js +1 -1
  8. package/build/cjs/integrations/tracing/google-genai/instrumentation.js.map +1 -1
  9. package/build/cjs/integrations/tracing/hono/constants.js +15 -0
  10. package/build/cjs/integrations/tracing/hono/constants.js.map +1 -0
  11. package/build/cjs/integrations/tracing/hono/index.js +137 -0
  12. package/build/cjs/integrations/tracing/hono/index.js.map +1 -0
  13. package/build/cjs/integrations/tracing/hono/instrumentation.js +236 -0
  14. package/build/cjs/integrations/tracing/hono/instrumentation.js.map +1 -0
  15. package/build/cjs/integrations/tracing/index.js +15 -12
  16. package/build/cjs/integrations/tracing/index.js.map +1 -1
  17. package/build/cjs/utils/redisCache.js +2 -2
  18. package/build/cjs/utils/redisCache.js.map +1 -1
  19. package/build/esm/index.js +1 -0
  20. package/build/esm/index.js.map +1 -1
  21. package/build/esm/integrations/tracing/fastify/index.js +1 -1
  22. package/build/esm/integrations/tracing/fastify/index.js.map +1 -1
  23. package/build/esm/integrations/tracing/firebase/firebase.js +1 -1
  24. package/build/esm/integrations/tracing/firebase/firebase.js.map +1 -1
  25. package/build/esm/integrations/tracing/google-genai/instrumentation.js +1 -1
  26. package/build/esm/integrations/tracing/google-genai/instrumentation.js.map +1 -1
  27. package/build/esm/integrations/tracing/hono/constants.js +12 -0
  28. package/build/esm/integrations/tracing/hono/constants.js.map +1 -0
  29. package/build/esm/integrations/tracing/hono/index.js +133 -0
  30. package/build/esm/integrations/tracing/hono/index.js.map +1 -0
  31. package/build/esm/integrations/tracing/hono/instrumentation.js +234 -0
  32. package/build/esm/integrations/tracing/hono/instrumentation.js.map +1 -0
  33. package/build/esm/integrations/tracing/index.js +3 -0
  34. package/build/esm/integrations/tracing/index.js.map +1 -1
  35. package/build/esm/package.json +1 -1
  36. package/build/esm/utils/redisCache.js +2 -2
  37. package/build/esm/utils/redisCache.js.map +1 -1
  38. package/build/types/index.d.ts +1 -0
  39. package/build/types/index.d.ts.map +1 -1
  40. package/build/types/integrations/tracing/firebase/firebase.d.ts.map +1 -1
  41. package/build/types/integrations/tracing/hono/constants.d.ts +11 -0
  42. package/build/types/integrations/tracing/hono/constants.d.ts.map +1 -0
  43. package/build/types/integrations/tracing/hono/index.d.ts +30 -0
  44. package/build/types/integrations/tracing/hono/index.d.ts.map +1 -1
  45. package/build/types/integrations/tracing/hono/instrumentation.d.ts +29 -2
  46. package/build/types/integrations/tracing/hono/instrumentation.d.ts.map +1 -1
  47. package/build/types/integrations/tracing/hono/types.d.ts +4 -1
  48. package/build/types/integrations/tracing/hono/types.d.ts.map +1 -1
  49. package/build/types/integrations/tracing/index.d.ts.map +1 -1
  50. package/build/types-ts3.8/index.d.ts +1 -0
  51. package/build/types-ts3.8/integrations/tracing/hono/constants.d.ts +11 -0
  52. package/build/types-ts3.8/integrations/tracing/hono/index.d.ts +30 -0
  53. package/build/types-ts3.8/integrations/tracing/hono/instrumentation.d.ts +29 -2
  54. package/build/types-ts3.8/integrations/tracing/hono/types.d.ts +4 -1
  55. package/package.json +4 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/hono/instrumentation.ts"],"sourcesContent":["import type { Span } from '@opentelemetry/api';\nimport { context, SpanStatusCode, trace } from '@opentelemetry/api';\nimport type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';\nimport { isThenable } from '@sentry/core';\nimport { AttributeNames, HonoTypes } from './constants';\nimport type {\n Context,\n Handler,\n HandlerInterface,\n Hono,\n HonoInstance,\n MiddlewareHandler,\n MiddlewareHandlerInterface,\n Next,\n OnHandlerInterface,\n} from './types';\n\nconst PACKAGE_NAME = '@sentry/instrumentation-hono';\nconst PACKAGE_VERSION = '0.0.1';\n\nexport interface HonoResponseHookFunction {\n (span: Span): void;\n}\n\nexport interface HonoInstrumentationConfig extends InstrumentationConfig {\n /** Function for adding custom span attributes from the response */\n responseHook?: HonoResponseHookFunction;\n}\n\n/**\n * Hono instrumentation for OpenTelemetry\n */\nexport class HonoInstrumentation extends InstrumentationBase<HonoInstrumentationConfig> {\n public constructor(config: HonoInstrumentationConfig = {}) {\n super(PACKAGE_NAME, PACKAGE_VERSION, config);\n }\n\n /**\n * Initialize the instrumentation.\n */\n public init(): InstrumentationNodeModuleDefinition[] {\n return [\n new InstrumentationNodeModuleDefinition('hono', ['>=4.0.0 <5'], moduleExports => this._patch(moduleExports)),\n ];\n }\n\n /**\n * Patches the module exports to instrument Hono.\n */\n private _patch(moduleExports: { Hono: Hono }): { Hono: Hono } {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const instrumentation = this;\n\n class WrappedHono extends moduleExports.Hono {\n public constructor(...args: unknown[]) {\n super(...args);\n\n instrumentation._wrap(this, 'get', instrumentation._patchHandler());\n instrumentation._wrap(this, 'post', instrumentation._patchHandler());\n instrumentation._wrap(this, 'put', instrumentation._patchHandler());\n instrumentation._wrap(this, 'delete', instrumentation._patchHandler());\n instrumentation._wrap(this, 'options', instrumentation._patchHandler());\n instrumentation._wrap(this, 'patch', instrumentation._patchHandler());\n instrumentation._wrap(this, 'all', instrumentation._patchHandler());\n instrumentation._wrap(this, 'on', instrumentation._patchOnHandler());\n instrumentation._wrap(this, 'use', instrumentation._patchMiddlewareHandler());\n }\n }\n\n try {\n moduleExports.Hono = WrappedHono;\n } catch {\n // This is a workaround for environments where direct assignment is not allowed.\n return { ...moduleExports, Hono: WrappedHono };\n }\n\n return moduleExports;\n }\n\n /**\n * Patches the route handler to instrument it.\n */\n private _patchHandler(): (original: HandlerInterface) => HandlerInterface {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const instrumentation = this;\n\n return function (original: HandlerInterface) {\n return function wrappedHandler(this: HonoInstance, ...args: unknown[]) {\n if (typeof args[0] === 'string') {\n const path = args[0];\n if (args.length === 1) {\n return original.apply(this, [path]);\n }\n\n const handlers = args.slice(1);\n return original.apply(this, [\n path,\n ...handlers.map(handler => instrumentation._wrapHandler(handler as Handler | MiddlewareHandler)),\n ]);\n }\n\n return original.apply(\n this,\n args.map(handler => instrumentation._wrapHandler(handler as Handler | MiddlewareHandler)),\n );\n };\n };\n }\n\n /**\n * Patches the 'on' handler to instrument it.\n */\n private _patchOnHandler(): (original: OnHandlerInterface) => OnHandlerInterface {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const instrumentation = this;\n\n return function (original: OnHandlerInterface) {\n return function wrappedHandler(this: HonoInstance, ...args: unknown[]) {\n const handlers = args.slice(2);\n return original.apply(this, [\n ...args.slice(0, 2),\n ...handlers.map(handler => instrumentation._wrapHandler(handler as Handler | MiddlewareHandler)),\n ]);\n };\n };\n }\n\n /**\n * Patches the middleware handler to instrument it.\n */\n private _patchMiddlewareHandler(): (original: MiddlewareHandlerInterface) => MiddlewareHandlerInterface {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const instrumentation = this;\n\n return function (original: MiddlewareHandlerInterface) {\n return function wrappedHandler(this: HonoInstance, ...args: unknown[]) {\n if (typeof args[0] === 'string') {\n const path = args[0];\n if (args.length === 1) {\n return original.apply(this, [path]);\n }\n\n const handlers = args.slice(1);\n return original.apply(this, [\n path,\n ...handlers.map(handler => instrumentation._wrapHandler(handler as MiddlewareHandler)),\n ]);\n }\n\n return original.apply(\n this,\n args.map(handler => instrumentation._wrapHandler(handler as MiddlewareHandler)),\n );\n };\n };\n }\n\n /**\n * Wraps a handler or middleware handler to apply instrumentation.\n */\n private _wrapHandler(handler: Handler | MiddlewareHandler): Handler | MiddlewareHandler {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const instrumentation = this;\n\n return function (this: unknown, c: Context, next: Next) {\n if (!instrumentation.isEnabled()) {\n return handler.apply(this, [c, next]);\n }\n\n const path = c.req.path;\n const span = instrumentation.tracer.startSpan(path);\n\n return context.with(trace.setSpan(context.active(), span), () => {\n return instrumentation._safeExecute(\n () => {\n const result = handler.apply(this, [c, next]);\n if (isThenable(result)) {\n return result.then(result => {\n const type = instrumentation._determineHandlerType(result);\n span.setAttributes({\n [AttributeNames.HONO_TYPE]: type,\n [AttributeNames.HONO_NAME]: type === HonoTypes.REQUEST_HANDLER ? path : handler.name || 'anonymous',\n });\n instrumentation.getConfig().responseHook?.(span);\n return result;\n });\n } else {\n const type = instrumentation._determineHandlerType(result);\n span.setAttributes({\n [AttributeNames.HONO_TYPE]: type,\n [AttributeNames.HONO_NAME]: type === HonoTypes.REQUEST_HANDLER ? path : handler.name || 'anonymous',\n });\n instrumentation.getConfig().responseHook?.(span);\n return result;\n }\n },\n () => span.end(),\n error => {\n instrumentation._handleError(span, error);\n span.end();\n },\n );\n });\n };\n }\n\n /**\n * Safely executes a function and handles errors.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _safeExecute(execute: () => any, onSuccess: () => void, onFailure: (error: unknown) => void): () => any {\n try {\n const result = execute();\n\n if (isThenable(result)) {\n result.then(\n () => onSuccess(),\n (error: unknown) => onFailure(error),\n );\n } else {\n onSuccess();\n }\n\n return result;\n } catch (error: unknown) {\n onFailure(error);\n throw error;\n }\n }\n\n /**\n * Determines the handler type based on the result.\n * @param result\n * @private\n */\n private _determineHandlerType(result: unknown): HonoTypes {\n return result === undefined ? HonoTypes.MIDDLEWARE : HonoTypes.REQUEST_HANDLER;\n }\n\n /**\n * Handles errors by setting the span status and recording the exception.\n */\n private _handleError(span: Span, error: unknown): void {\n if (error instanceof Error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n });\n span.recordException(error);\n }\n }\n}\n"],"names":["InstrumentationBase","InstrumentationNodeModuleDefinition","context","trace","isThenable","AttributeNames","HonoTypes","SpanStatusCode"],"mappings":";;;;;;;AAkBA,MAAM,YAAA,GAAe,8BAA8B;AACnD,MAAM,eAAA,GAAkB,OAAO;;AAW/B;AACA;AACA;AACO,MAAM,mBAAA,SAA4BA,mCAAmB,CAA4B;AACxF,GAAS,WAAW,CAAC,MAAM,GAA8B,EAAE,EAAE;AAC7D,IAAI,KAAK,CAAC,YAAY,EAAE,eAAe,EAAE,MAAM,CAAC;AAChD;;AAEA;AACA;AACA;AACA,GAAS,IAAI,GAA0C;AACvD,IAAI,OAAO;AACX,MAAM,IAAIC,mDAAmC,CAAC,MAAM,EAAE,CAAC,YAAY,CAAC,EAAE,aAAA,IAAiB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;AAClH,KAAK;AACL;;AAEA;AACA;AACA;AACA,GAAU,MAAM,CAAC,aAAa,EAAkC;AAChE;AACA,IAAI,MAAM,eAAA,GAAkB,IAAI;;AAEhC,IAAI,MAAM,WAAA,SAAoB,aAAa,CAAC,IAAA,CAAK;AACjD,OAAa,WAAW,CAAC,GAAG,IAAI,EAAa;AAC7C,QAAQ,KAAK,CAAC,GAAG,IAAI,CAAC;;AAEtB,QAAQ,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,eAAe,CAAC,aAAa,EAAE,CAAC;AAC3E,QAAQ,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,aAAa,EAAE,CAAC;AAC5E,QAAQ,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,eAAe,CAAC,aAAa,EAAE,CAAC;AAC3E,QAAQ,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,eAAe,CAAC,aAAa,EAAE,CAAC;AAC9E,QAAQ,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,eAAe,CAAC,aAAa,EAAE,CAAC;AAC/E,QAAQ,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,eAAe,CAAC,aAAa,EAAE,CAAC;AAC7E,QAAQ,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,eAAe,CAAC,aAAa,EAAE,CAAC;AAC3E,QAAQ,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,eAAe,CAAC,eAAe,EAAE,CAAC;AAC5E,QAAQ,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,eAAe,CAAC,uBAAuB,EAAE,CAAC;AACrF;AACA;;AAEA,IAAI,IAAI;AACR,MAAM,aAAa,CAAC,IAAA,GAAO,WAAW;AACtC,MAAM,MAAM;AACZ;AACA,MAAM,OAAO,EAAE,GAAG,aAAa,EAAE,IAAI,EAAE,aAAa;AACpD;;AAEA,IAAI,OAAO,aAAa;AACxB;;AAEA;AACA;AACA;AACA,GAAU,aAAa,GAAqD;AAC5E;AACA,IAAI,MAAM,eAAA,GAAkB,IAAI;;AAEhC,IAAI,OAAO,UAAU,QAAQ,EAAoB;AACjD,MAAM,OAAO,SAAS,cAAc,EAAqB,GAAG,IAAI,EAAa;AAC7E,QAAQ,IAAI,OAAO,IAAI,CAAC,CAAC,CAAA,KAAM,QAAQ,EAAE;AACzC,UAAU,MAAM,IAAA,GAAO,IAAI,CAAC,CAAC,CAAC;AAC9B,UAAU,IAAI,IAAI,CAAC,MAAA,KAAW,CAAC,EAAE;AACjC,YAAY,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;AAC/C;;AAEA,UAAU,MAAM,WAAW,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AACxC,UAAU,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE;AACtC,YAAY,IAAI;AAChB,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAA,IAAW,eAAe,CAAC,YAAY,CAAC,OAAA,EAAuC,CAAC;AAC5G,WAAW,CAAC;AACZ;;AAEA,QAAQ,OAAO,QAAQ,CAAC,KAAK;AAC7B,UAAU,IAAI;AACd,UAAU,IAAI,CAAC,GAAG,CAAC,OAAA,IAAW,eAAe,CAAC,YAAY,CAAC,OAAA,EAAuC,CAAC;AACnG,SAAS;AACT,OAAO;AACP,KAAK;AACL;;AAEA;AACA;AACA;AACA,GAAU,eAAe,GAAyD;AAClF;AACA,IAAI,MAAM,eAAA,GAAkB,IAAI;;AAEhC,IAAI,OAAO,UAAU,QAAQ,EAAsB;AACnD,MAAM,OAAO,SAAS,cAAc,EAAqB,GAAG,IAAI,EAAa;AAC7E,QAAQ,MAAM,WAAW,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AACtC,QAAQ,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE;AACpC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;AAC7B,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAA,IAAW,eAAe,CAAC,YAAY,CAAC,OAAA,EAAuC,CAAC;AAC1G,SAAS,CAAC;AACV,OAAO;AACP,KAAK;AACL;;AAEA;AACA;AACA;AACA,GAAU,uBAAuB,GAAyE;AAC1G;AACA,IAAI,MAAM,eAAA,GAAkB,IAAI;;AAEhC,IAAI,OAAO,UAAU,QAAQ,EAA8B;AAC3D,MAAM,OAAO,SAAS,cAAc,EAAqB,GAAG,IAAI,EAAa;AAC7E,QAAQ,IAAI,OAAO,IAAI,CAAC,CAAC,CAAA,KAAM,QAAQ,EAAE;AACzC,UAAU,MAAM,IAAA,GAAO,IAAI,CAAC,CAAC,CAAC;AAC9B,UAAU,IAAI,IAAI,CAAC,MAAA,KAAW,CAAC,EAAE;AACjC,YAAY,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;AAC/C;;AAEA,UAAU,MAAM,WAAW,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AACxC,UAAU,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE;AACtC,YAAY,IAAI;AAChB,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAA,IAAW,eAAe,CAAC,YAAY,CAAC,OAAA,EAA6B,CAAC;AAClG,WAAW,CAAC;AACZ;;AAEA,QAAQ,OAAO,QAAQ,CAAC,KAAK;AAC7B,UAAU,IAAI;AACd,UAAU,IAAI,CAAC,GAAG,CAAC,OAAA,IAAW,eAAe,CAAC,YAAY,CAAC,OAAA,EAA6B,CAAC;AACzF,SAAS;AACT,OAAO;AACP,KAAK;AACL;;AAEA;AACA;AACA;AACA,GAAU,YAAY,CAAC,OAAO,EAA4D;AAC1F;AACA,IAAI,MAAM,eAAA,GAAkB,IAAI;;AAEhC,IAAI,OAAO,WAAyB,CAAC,EAAW,IAAI,EAAQ;AAC5D,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,EAAE;AACxC,QAAQ,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAC7C;;AAEA,MAAM,MAAM,IAAA,GAAO,CAAC,CAAC,GAAG,CAAC,IAAI;AAC7B,MAAM,MAAM,IAAA,GAAO,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;;AAEzD,MAAM,OAAOC,WAAO,CAAC,IAAI,CAACC,SAAK,CAAC,OAAO,CAACD,WAAO,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM;AACvE,QAAQ,OAAO,eAAe,CAAC,YAAY;AAC3C,UAAU,MAAM;AAChB,YAAY,MAAM,MAAA,GAAS,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AACzD,YAAY,IAAIE,eAAU,CAAC,MAAM,CAAC,EAAE;AACpC,cAAc,OAAO,MAAM,CAAC,IAAI,CAAC,UAAU;AAC3C,gBAAgB,MAAM,OAAO,eAAe,CAAC,qBAAqB,CAAC,MAAM,CAAC;AAC1E,gBAAgB,IAAI,CAAC,aAAa,CAAC;AACnC,kBAAkB,CAACC,wBAAc,CAAC,SAAS,GAAG,IAAI;AAClD,kBAAkB,CAACA,wBAAc,CAAC,SAAS,GAAG,SAASC,mBAAS,CAAC,eAAA,GAAkB,IAAA,GAAO,OAAO,CAAC,IAAA,IAAQ,WAAW;AACrH,iBAAiB,CAAC;AAClB,gBAAgB,eAAe,CAAC,SAAS,EAAE,CAAC,YAAY,GAAG,IAAI,CAAC;AAChE,gBAAgB,OAAO,MAAM;AAC7B,eAAe,CAAC;AAChB,mBAAmB;AACnB,cAAc,MAAM,OAAO,eAAe,CAAC,qBAAqB,CAAC,MAAM,CAAC;AACxE,cAAc,IAAI,CAAC,aAAa,CAAC;AACjC,gBAAgB,CAACD,wBAAc,CAAC,SAAS,GAAG,IAAI;AAChD,gBAAgB,CAACA,wBAAc,CAAC,SAAS,GAAG,SAASC,mBAAS,CAAC,eAAA,GAAkB,IAAA,GAAO,OAAO,CAAC,IAAA,IAAQ,WAAW;AACnH,eAAe,CAAC;AAChB,cAAc,eAAe,CAAC,SAAS,EAAE,CAAC,YAAY,GAAG,IAAI,CAAC;AAC9D,cAAc,OAAO,MAAM;AAC3B;AACA,WAAW;AACX,UAAU,MAAM,IAAI,CAAC,GAAG,EAAE;AAC1B,UAAU,SAAS;AACnB,YAAY,eAAe,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC;AACrD,YAAY,IAAI,CAAC,GAAG,EAAE;AACtB,WAAW;AACX,SAAS;AACT,OAAO,CAAC;AACR,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA,GAAU,YAAY,CAAC,OAAO,EAAa,SAAS,EAAc,SAAS,EAAuC;AAClH,IAAI,IAAI;AACR,MAAM,MAAM,MAAA,GAAS,OAAO,EAAE;;AAE9B,MAAM,IAAIF,eAAU,CAAC,MAAM,CAAC,EAAE;AAC9B,QAAQ,MAAM,CAAC,IAAI;AACnB,UAAU,MAAM,SAAS,EAAE;AAC3B,UAAU,CAAC,KAAK,KAAc,SAAS,CAAC,KAAK,CAAC;AAC9C,SAAS;AACT,aAAa;AACb,QAAQ,SAAS,EAAE;AACnB;;AAEA,MAAM,OAAO,MAAM;AACnB,KAAI,CAAE,OAAO,KAAK,EAAW;AAC7B,MAAM,SAAS,CAAC,KAAK,CAAC;AACtB,MAAM,MAAM,KAAK;AACjB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAU,qBAAqB,CAAC,MAAM,EAAsB;AAC5D,IAAI,OAAO,MAAA,KAAW,SAAA,GAAYE,mBAAS,CAAC,UAAA,GAAaA,mBAAS,CAAC,eAAe;AAClF;;AAEA;AACA;AACA;AACA,GAAU,YAAY,CAAC,IAAI,EAAQ,KAAK,EAAiB;AACzD,IAAI,IAAI,KAAA,YAAiB,KAAK,EAAE;AAChC,MAAM,IAAI,CAAC,SAAS,CAAC;AACrB,QAAQ,IAAI,EAAEC,kBAAc,CAAC,KAAK;AAClC,QAAQ,OAAO,EAAE,KAAK,CAAC,OAAO;AAC9B,OAAO,CAAC;AACR,MAAM,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;AACjC;AACA;AACA;;;;"}
@@ -2,15 +2,16 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const http = require('../http.js');
4
4
  const amqplib = require('./amqplib.js');
5
- const index$4 = require('./anthropic-ai/index.js');
5
+ const index$5 = require('./anthropic-ai/index.js');
6
6
  const connect = require('./connect.js');
7
7
  const express = require('./express.js');
8
8
  const index = require('./fastify/index.js');
9
9
  const firebase = require('./firebase/firebase.js');
10
10
  const genericPool = require('./genericPool.js');
11
- const index$5 = require('./google-genai/index.js');
11
+ const index$6 = require('./google-genai/index.js');
12
12
  const graphql = require('./graphql.js');
13
13
  const index$1 = require('./hapi/index.js');
14
+ const index$2 = require('./hono/index.js');
14
15
  const kafka = require('./kafka.js');
15
16
  const koa = require('./koa.js');
16
17
  const lrumemoizer = require('./lrumemoizer.js');
@@ -18,13 +19,13 @@ const mongo = require('./mongo.js');
18
19
  const mongoose = require('./mongoose.js');
19
20
  const mysql = require('./mysql.js');
20
21
  const mysql2 = require('./mysql2.js');
21
- const index$3 = require('./openai/index.js');
22
+ const index$4 = require('./openai/index.js');
22
23
  const postgres = require('./postgres.js');
23
24
  const postgresjs = require('./postgresjs.js');
24
25
  const prisma = require('./prisma.js');
25
26
  const redis = require('./redis.js');
26
27
  const tedious = require('./tedious.js');
27
- const index$2 = require('./vercelai/index.js');
28
+ const index$3 = require('./vercelai/index.js');
28
29
 
29
30
  /**
30
31
  * With OTEL, all performance integrations will be added, as OTEL only initializes them when the patched package is actually required.
@@ -34,6 +35,7 @@ function getAutoPerformanceIntegrations() {
34
35
  express.expressIntegration(),
35
36
  index.fastifyIntegration(),
36
37
  graphql.graphqlIntegration(),
38
+ index$2.honoIntegration(),
37
39
  mongo.mongoIntegration(),
38
40
  mongoose.mongooseIntegration(),
39
41
  mysql.mysqlIntegration(),
@@ -49,12 +51,12 @@ function getAutoPerformanceIntegrations() {
49
51
  kafka.kafkaIntegration(),
50
52
  amqplib.amqplibIntegration(),
51
53
  lrumemoizer.lruMemoizerIntegration(),
52
- index$2.vercelAIIntegration(),
53
- index$3.openAIIntegration(),
54
+ index$3.vercelAIIntegration(),
55
+ index$4.openAIIntegration(),
54
56
  postgresjs.postgresJsIntegration(),
55
57
  firebase.firebaseIntegration(),
56
- index$4.anthropicAIIntegration(),
57
- index$5.googleGenAIIntegration(),
58
+ index$5.anthropicAIIntegration(),
59
+ index$6.googleGenAIIntegration(),
58
60
  ];
59
61
  }
60
62
 
@@ -71,6 +73,7 @@ function getOpenTelemetryInstrumentationToPreload() {
71
73
  index.instrumentFastify,
72
74
  index.instrumentFastifyV3,
73
75
  index$1.instrumentHapi,
76
+ index$2.instrumentHono,
74
77
  kafka.instrumentKafka,
75
78
  koa.instrumentKoa,
76
79
  lrumemoizer.instrumentLruMemoizer,
@@ -85,12 +88,12 @@ function getOpenTelemetryInstrumentationToPreload() {
85
88
  tedious.instrumentTedious,
86
89
  genericPool.instrumentGenericPool,
87
90
  amqplib.instrumentAmqplib,
88
- index$2.instrumentVercelAi,
89
- index$3.instrumentOpenAi,
91
+ index$3.instrumentVercelAi,
92
+ index$4.instrumentOpenAi,
90
93
  postgresjs.instrumentPostgresJs,
91
94
  firebase.instrumentFirebase,
92
- index$4.instrumentAnthropicAi,
93
- index$5.instrumentGoogleGenAI,
95
+ index$5.instrumentAnthropicAi,
96
+ index$6.instrumentGoogleGenAI,
94
97
  ];
95
98
  }
96
99
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/integrations/tracing/index.ts"],"sourcesContent":["import type { Integration } from '@sentry/core';\nimport { instrumentOtelHttp, instrumentSentryHttp } from '../http';\nimport { amqplibIntegration, instrumentAmqplib } from './amqplib';\nimport { anthropicAIIntegration, instrumentAnthropicAi } from './anthropic-ai';\nimport { connectIntegration, instrumentConnect } from './connect';\nimport { expressIntegration, instrumentExpress } from './express';\nimport { fastifyIntegration, instrumentFastify, instrumentFastifyV3 } from './fastify';\nimport { firebaseIntegration, instrumentFirebase } from './firebase';\nimport { genericPoolIntegration, instrumentGenericPool } from './genericPool';\nimport { googleGenAIIntegration, instrumentGoogleGenAI } from './google-genai';\nimport { graphqlIntegration, instrumentGraphql } from './graphql';\nimport { hapiIntegration, instrumentHapi } from './hapi';\nimport { instrumentKafka, kafkaIntegration } from './kafka';\nimport { instrumentKoa, koaIntegration } from './koa';\nimport { instrumentLruMemoizer, lruMemoizerIntegration } from './lrumemoizer';\nimport { instrumentMongo, mongoIntegration } from './mongo';\nimport { instrumentMongoose, mongooseIntegration } from './mongoose';\nimport { instrumentMysql, mysqlIntegration } from './mysql';\nimport { instrumentMysql2, mysql2Integration } from './mysql2';\nimport { instrumentOpenAi, openAIIntegration } from './openai';\nimport { instrumentPostgres, postgresIntegration } from './postgres';\nimport { instrumentPostgresJs, postgresJsIntegration } from './postgresjs';\nimport { prismaIntegration } from './prisma';\nimport { instrumentRedis, redisIntegration } from './redis';\nimport { instrumentTedious, tediousIntegration } from './tedious';\nimport { instrumentVercelAi, vercelAIIntegration } from './vercelai';\n\n/**\n * With OTEL, all performance integrations will be added, as OTEL only initializes them when the patched package is actually required.\n */\nexport function getAutoPerformanceIntegrations(): Integration[] {\n return [\n expressIntegration(),\n fastifyIntegration(),\n graphqlIntegration(),\n mongoIntegration(),\n mongooseIntegration(),\n mysqlIntegration(),\n mysql2Integration(),\n redisIntegration(),\n postgresIntegration(),\n prismaIntegration(),\n hapiIntegration(),\n koaIntegration(),\n connectIntegration(),\n tediousIntegration(),\n genericPoolIntegration(),\n kafkaIntegration(),\n amqplibIntegration(),\n lruMemoizerIntegration(),\n vercelAIIntegration(),\n openAIIntegration(),\n postgresJsIntegration(),\n firebaseIntegration(),\n anthropicAIIntegration(),\n googleGenAIIntegration(),\n ];\n}\n\n/**\n * Get a list of methods to instrument OTEL, when preload instrumentation.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getOpenTelemetryInstrumentationToPreload(): (((options?: any) => void) & { id: string })[] {\n return [\n instrumentSentryHttp,\n instrumentOtelHttp,\n instrumentExpress,\n instrumentConnect,\n instrumentFastify,\n instrumentFastifyV3,\n instrumentHapi,\n instrumentKafka,\n instrumentKoa,\n instrumentLruMemoizer,\n instrumentMongo,\n instrumentMongoose,\n instrumentMysql,\n instrumentMysql2,\n instrumentPostgres,\n instrumentHapi,\n instrumentGraphql,\n instrumentRedis,\n instrumentTedious,\n instrumentGenericPool,\n instrumentAmqplib,\n instrumentVercelAi,\n instrumentOpenAi,\n instrumentPostgresJs,\n instrumentFirebase,\n instrumentAnthropicAi,\n instrumentGoogleGenAI,\n ];\n}\n"],"names":["expressIntegration","fastifyIntegration","graphqlIntegration","mongoIntegration","mongooseIntegration","mysqlIntegration","mysql2Integration","redisIntegration","postgresIntegration","prismaIntegration","hapiIntegration","koaIntegration","connectIntegration","tediousIntegration","genericPoolIntegration","kafkaIntegration","amqplibIntegration","lruMemoizerIntegration","vercelAIIntegration","openAIIntegration","postgresJsIntegration","firebaseIntegration","anthropicAIIntegration","googleGenAIIntegration","instrumentSentryHttp","instrumentOtelHttp","instrumentExpress","instrumentConnect","instrumentFastify","instrumentFastifyV3","instrumentHapi","instrumentKafka","instrumentKoa","instrumentLruMemoizer","instrumentMongo","instrumentMongoose","instrumentMysql","instrumentMysql2","instrumentPostgres","instrumentGraphql","instrumentRedis","instrumentTedious","instrumentGenericPool","instrumentAmqplib","instrumentVercelAi","instrumentOpenAi","instrumentPostgresJs","instrumentFirebase","instrumentAnthropicAi","instrumentGoogleGenAI"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA;AACA;AACA;AACO,SAAS,8BAA8B,GAAkB;AAChE,EAAE,OAAO;AACT,IAAIA,0BAAkB,EAAE;AACxB,IAAIC,wBAAkB,EAAE;AACxB,IAAIC,0BAAkB,EAAE;AACxB,IAAIC,sBAAgB,EAAE;AACtB,IAAIC,4BAAmB,EAAE;AACzB,IAAIC,sBAAgB,EAAE;AACtB,IAAIC,wBAAiB,EAAE;AACvB,IAAIC,sBAAgB,EAAE;AACtB,IAAIC,4BAAmB,EAAE;AACzB,IAAIC,wBAAiB,EAAE;AACvB,IAAIC,uBAAe,EAAE;AACrB,IAAIC,kBAAc,EAAE;AACpB,IAAIC,0BAAkB,EAAE;AACxB,IAAIC,0BAAkB,EAAE;AACxB,IAAIC,kCAAsB,EAAE;AAC5B,IAAIC,sBAAgB,EAAE;AACtB,IAAIC,0BAAkB,EAAE;AACxB,IAAIC,kCAAsB,EAAE;AAC5B,IAAIC,2BAAmB,EAAE;AACzB,IAAIC,yBAAiB,EAAE;AACvB,IAAIC,gCAAqB,EAAE;AAC3B,IAAIC,4BAAmB,EAAE;AACzB,IAAIC,8BAAsB,EAAE;AAC5B,IAAIC,8BAAsB,EAAE;AAC5B,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACO,SAAS,wCAAwC,GAAmD;AAC3G,EAAE,OAAO;AACT,IAAIC,yBAAoB;AACxB,IAAIC,uBAAkB;AACtB,IAAIC,yBAAiB;AACrB,IAAIC,yBAAiB;AACrB,IAAIC,uBAAiB;AACrB,IAAIC,yBAAmB;AACvB,IAAIC,sBAAc;AAClB,IAAIC,qBAAe;AACnB,IAAIC,iBAAa;AACjB,IAAIC,iCAAqB;AACzB,IAAIC,qBAAe;AACnB,IAAIC,2BAAkB;AACtB,IAAIC,qBAAe;AACnB,IAAIC,uBAAgB;AACpB,IAAIC,2BAAkB;AACtB,IAAIR,sBAAc;AAClB,IAAIS,yBAAiB;AACrB,IAAIC,qBAAe;AACnB,IAAIC,yBAAiB;AACrB,IAAIC,iCAAqB;AACzB,IAAIC,yBAAiB;AACrB,IAAIC,0BAAkB;AACtB,IAAIC,wBAAgB;AACpB,IAAIC,+BAAoB;AACxB,IAAIC,2BAAkB;AACtB,IAAIC,6BAAqB;AACzB,IAAIC,6BAAqB;AACzB,GAAG;AACH;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/integrations/tracing/index.ts"],"sourcesContent":["import type { Integration } from '@sentry/core';\nimport { instrumentOtelHttp, instrumentSentryHttp } from '../http';\nimport { amqplibIntegration, instrumentAmqplib } from './amqplib';\nimport { anthropicAIIntegration, instrumentAnthropicAi } from './anthropic-ai';\nimport { connectIntegration, instrumentConnect } from './connect';\nimport { expressIntegration, instrumentExpress } from './express';\nimport { fastifyIntegration, instrumentFastify, instrumentFastifyV3 } from './fastify';\nimport { firebaseIntegration, instrumentFirebase } from './firebase';\nimport { genericPoolIntegration, instrumentGenericPool } from './genericPool';\nimport { googleGenAIIntegration, instrumentGoogleGenAI } from './google-genai';\nimport { graphqlIntegration, instrumentGraphql } from './graphql';\nimport { hapiIntegration, instrumentHapi } from './hapi';\nimport { honoIntegration, instrumentHono } from './hono';\nimport { instrumentKafka, kafkaIntegration } from './kafka';\nimport { instrumentKoa, koaIntegration } from './koa';\nimport { instrumentLruMemoizer, lruMemoizerIntegration } from './lrumemoizer';\nimport { instrumentMongo, mongoIntegration } from './mongo';\nimport { instrumentMongoose, mongooseIntegration } from './mongoose';\nimport { instrumentMysql, mysqlIntegration } from './mysql';\nimport { instrumentMysql2, mysql2Integration } from './mysql2';\nimport { instrumentOpenAi, openAIIntegration } from './openai';\nimport { instrumentPostgres, postgresIntegration } from './postgres';\nimport { instrumentPostgresJs, postgresJsIntegration } from './postgresjs';\nimport { prismaIntegration } from './prisma';\nimport { instrumentRedis, redisIntegration } from './redis';\nimport { instrumentTedious, tediousIntegration } from './tedious';\nimport { instrumentVercelAi, vercelAIIntegration } from './vercelai';\n\n/**\n * With OTEL, all performance integrations will be added, as OTEL only initializes them when the patched package is actually required.\n */\nexport function getAutoPerformanceIntegrations(): Integration[] {\n return [\n expressIntegration(),\n fastifyIntegration(),\n graphqlIntegration(),\n honoIntegration(),\n mongoIntegration(),\n mongooseIntegration(),\n mysqlIntegration(),\n mysql2Integration(),\n redisIntegration(),\n postgresIntegration(),\n prismaIntegration(),\n hapiIntegration(),\n koaIntegration(),\n connectIntegration(),\n tediousIntegration(),\n genericPoolIntegration(),\n kafkaIntegration(),\n amqplibIntegration(),\n lruMemoizerIntegration(),\n vercelAIIntegration(),\n openAIIntegration(),\n postgresJsIntegration(),\n firebaseIntegration(),\n anthropicAIIntegration(),\n googleGenAIIntegration(),\n ];\n}\n\n/**\n * Get a list of methods to instrument OTEL, when preload instrumentation.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getOpenTelemetryInstrumentationToPreload(): (((options?: any) => void) & { id: string })[] {\n return [\n instrumentSentryHttp,\n instrumentOtelHttp,\n instrumentExpress,\n instrumentConnect,\n instrumentFastify,\n instrumentFastifyV3,\n instrumentHapi,\n instrumentHono,\n instrumentKafka,\n instrumentKoa,\n instrumentLruMemoizer,\n instrumentMongo,\n instrumentMongoose,\n instrumentMysql,\n instrumentMysql2,\n instrumentPostgres,\n instrumentHapi,\n instrumentGraphql,\n instrumentRedis,\n instrumentTedious,\n instrumentGenericPool,\n instrumentAmqplib,\n instrumentVercelAi,\n instrumentOpenAi,\n instrumentPostgresJs,\n instrumentFirebase,\n instrumentAnthropicAi,\n instrumentGoogleGenAI,\n ];\n}\n"],"names":["expressIntegration","fastifyIntegration","graphqlIntegration","honoIntegration","mongoIntegration","mongooseIntegration","mysqlIntegration","mysql2Integration","redisIntegration","postgresIntegration","prismaIntegration","hapiIntegration","koaIntegration","connectIntegration","tediousIntegration","genericPoolIntegration","kafkaIntegration","amqplibIntegration","lruMemoizerIntegration","vercelAIIntegration","openAIIntegration","postgresJsIntegration","firebaseIntegration","anthropicAIIntegration","googleGenAIIntegration","instrumentSentryHttp","instrumentOtelHttp","instrumentExpress","instrumentConnect","instrumentFastify","instrumentFastifyV3","instrumentHapi","instrumentHono","instrumentKafka","instrumentKoa","instrumentLruMemoizer","instrumentMongo","instrumentMongoose","instrumentMysql","instrumentMysql2","instrumentPostgres","instrumentGraphql","instrumentRedis","instrumentTedious","instrumentGenericPool","instrumentAmqplib","instrumentVercelAi","instrumentOpenAi","instrumentPostgresJs","instrumentFirebase","instrumentAnthropicAi","instrumentGoogleGenAI"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA;AACA;AACA;AACO,SAAS,8BAA8B,GAAkB;AAChE,EAAE,OAAO;AACT,IAAIA,0BAAkB,EAAE;AACxB,IAAIC,wBAAkB,EAAE;AACxB,IAAIC,0BAAkB,EAAE;AACxB,IAAIC,uBAAe,EAAE;AACrB,IAAIC,sBAAgB,EAAE;AACtB,IAAIC,4BAAmB,EAAE;AACzB,IAAIC,sBAAgB,EAAE;AACtB,IAAIC,wBAAiB,EAAE;AACvB,IAAIC,sBAAgB,EAAE;AACtB,IAAIC,4BAAmB,EAAE;AACzB,IAAIC,wBAAiB,EAAE;AACvB,IAAIC,uBAAe,EAAE;AACrB,IAAIC,kBAAc,EAAE;AACpB,IAAIC,0BAAkB,EAAE;AACxB,IAAIC,0BAAkB,EAAE;AACxB,IAAIC,kCAAsB,EAAE;AAC5B,IAAIC,sBAAgB,EAAE;AACtB,IAAIC,0BAAkB,EAAE;AACxB,IAAIC,kCAAsB,EAAE;AAC5B,IAAIC,2BAAmB,EAAE;AACzB,IAAIC,yBAAiB,EAAE;AACvB,IAAIC,gCAAqB,EAAE;AAC3B,IAAIC,4BAAmB,EAAE;AACzB,IAAIC,8BAAsB,EAAE;AAC5B,IAAIC,8BAAsB,EAAE;AAC5B,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACO,SAAS,wCAAwC,GAAmD;AAC3G,EAAE,OAAO;AACT,IAAIC,yBAAoB;AACxB,IAAIC,uBAAkB;AACtB,IAAIC,yBAAiB;AACrB,IAAIC,yBAAiB;AACrB,IAAIC,uBAAiB;AACrB,IAAIC,yBAAmB;AACvB,IAAIC,sBAAc;AAClB,IAAIC,sBAAc;AAClB,IAAIC,qBAAe;AACnB,IAAIC,iBAAa;AACjB,IAAIC,iCAAqB;AACzB,IAAIC,qBAAe;AACnB,IAAIC,2BAAkB;AACtB,IAAIC,qBAAe;AACnB,IAAIC,uBAAgB;AACpB,IAAIC,2BAAkB;AACtB,IAAIT,sBAAc;AAClB,IAAIU,yBAAiB;AACrB,IAAIC,qBAAe;AACnB,IAAIC,yBAAiB;AACrB,IAAIC,iCAAqB;AACzB,IAAIC,yBAAiB;AACrB,IAAIC,0BAAkB;AACtB,IAAIC,wBAAgB;AACpB,IAAIC,+BAAoB;AACxB,IAAIC,2BAAkB;AACtB,IAAIC,6BAAqB;AACzB,IAAIC,6BAAqB;AACzB,GAAG;AACH;;;;;"}
@@ -101,9 +101,9 @@ function flatten(input) {
101
101
  const flattenHelper = (input) => {
102
102
  input.forEach((el) => {
103
103
  if (Array.isArray(el)) {
104
- flattenHelper(el );
104
+ flattenHelper(el);
105
105
  } else {
106
- result.push(el );
106
+ result.push(el);
107
107
  }
108
108
  });
109
109
  };
@@ -1 +1 @@
1
- {"version":3,"file":"redisCache.js","sources":["../../../src/utils/redisCache.ts"],"sourcesContent":["import type { CommandArgs as IORedisCommandArgs } from '@opentelemetry/instrumentation-ioredis';\n\nconst SINGLE_ARG_COMMANDS = ['get', 'set', 'setex'];\n\nexport const GET_COMMANDS = ['get', 'mget'];\nexport const SET_COMMANDS = ['set', 'setex'];\n// todo: del, expire\n\n/** Checks if a given command is in the list of redis commands.\n * Useful because commands can come in lowercase or uppercase (depending on the library). */\nexport function isInCommands(redisCommands: string[], command: string): boolean {\n return redisCommands.includes(command.toLowerCase());\n}\n\n/** Determine cache operation based on redis statement */\nexport function getCacheOperation(\n command: string,\n): 'cache.get' | 'cache.put' | 'cache.remove' | 'cache.flush' | undefined {\n if (isInCommands(GET_COMMANDS, command)) {\n return 'cache.get';\n } else if (isInCommands(SET_COMMANDS, command)) {\n return 'cache.put';\n } else {\n return undefined;\n }\n}\n\nfunction keyHasPrefix(key: string, prefixes: string[]): boolean {\n return prefixes.some(prefix => key.startsWith(prefix));\n}\n\n/** Safely converts a redis key to a string (comma-separated if there are multiple keys) */\nexport function getCacheKeySafely(redisCommand: string, cmdArgs: IORedisCommandArgs): string[] | undefined {\n try {\n if (cmdArgs.length === 0) {\n return undefined;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const processArg = (arg: string | Buffer | number | any[]): string[] => {\n if (typeof arg === 'string' || typeof arg === 'number' || Buffer.isBuffer(arg)) {\n return [arg.toString()];\n } else if (Array.isArray(arg)) {\n return flatten(arg.map(arg => processArg(arg)));\n } else {\n return ['<unknown>'];\n }\n };\n\n const firstArg = cmdArgs[0];\n if (isInCommands(SINGLE_ARG_COMMANDS, redisCommand) && firstArg != null) {\n return processArg(firstArg);\n }\n\n return flatten(cmdArgs.map(arg => processArg(arg)));\n } catch {\n return undefined;\n }\n}\n\n/** Determines whether a redis operation should be considered as \"cache operation\" by checking if a key is prefixed.\n * We only support certain commands (such as 'set', 'get', 'mget'). */\nexport function shouldConsiderForCache(redisCommand: string, keys: string[], prefixes: string[]): boolean {\n if (!getCacheOperation(redisCommand)) {\n return false;\n }\n\n for (const key of keys) {\n if (keyHasPrefix(key, prefixes)) {\n return true;\n }\n }\n return false;\n}\n\n/** Calculates size based on the cache response value */\nexport function calculateCacheItemSize(response: unknown): number | undefined {\n const getSize = (value: unknown): number | undefined => {\n try {\n if (Buffer.isBuffer(value)) return value.byteLength;\n else if (typeof value === 'string') return value.length;\n else if (typeof value === 'number') return value.toString().length;\n else if (value === null || value === undefined) return 0;\n return JSON.stringify(value).length;\n } catch {\n return undefined;\n }\n };\n\n return Array.isArray(response)\n ? response.reduce((acc: number | undefined, curr) => {\n const size = getSize(curr);\n return typeof size === 'number' ? (acc !== undefined ? acc + size : size) : acc;\n }, 0)\n : getSize(response);\n}\n\ntype NestedArray<T> = Array<NestedArray<T> | T>;\n\nfunction flatten<T>(input: NestedArray<T>): T[] {\n const result: T[] = [];\n\n const flattenHelper = (input: NestedArray<T>): void => {\n input.forEach((el: T | NestedArray<T>) => {\n if (Array.isArray(el)) {\n flattenHelper(el as NestedArray<T>);\n } else {\n result.push(el as T);\n }\n });\n };\n\n flattenHelper(input);\n return result;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"redisCache.js","sources":["../../../src/utils/redisCache.ts"],"sourcesContent":["import type { CommandArgs as IORedisCommandArgs } from '@opentelemetry/instrumentation-ioredis';\n\nconst SINGLE_ARG_COMMANDS = ['get', 'set', 'setex'];\n\nexport const GET_COMMANDS = ['get', 'mget'];\nexport const SET_COMMANDS = ['set', 'setex'];\n// todo: del, expire\n\n/** Checks if a given command is in the list of redis commands.\n * Useful because commands can come in lowercase or uppercase (depending on the library). */\nexport function isInCommands(redisCommands: string[], command: string): boolean {\n return redisCommands.includes(command.toLowerCase());\n}\n\n/** Determine cache operation based on redis statement */\nexport function getCacheOperation(\n command: string,\n): 'cache.get' | 'cache.put' | 'cache.remove' | 'cache.flush' | undefined {\n if (isInCommands(GET_COMMANDS, command)) {\n return 'cache.get';\n } else if (isInCommands(SET_COMMANDS, command)) {\n return 'cache.put';\n } else {\n return undefined;\n }\n}\n\nfunction keyHasPrefix(key: string, prefixes: string[]): boolean {\n return prefixes.some(prefix => key.startsWith(prefix));\n}\n\n/** Safely converts a redis key to a string (comma-separated if there are multiple keys) */\nexport function getCacheKeySafely(redisCommand: string, cmdArgs: IORedisCommandArgs): string[] | undefined {\n try {\n if (cmdArgs.length === 0) {\n return undefined;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const processArg = (arg: string | Buffer | number | any[]): string[] => {\n if (typeof arg === 'string' || typeof arg === 'number' || Buffer.isBuffer(arg)) {\n return [arg.toString()];\n } else if (Array.isArray(arg)) {\n return flatten(arg.map(arg => processArg(arg)));\n } else {\n return ['<unknown>'];\n }\n };\n\n const firstArg = cmdArgs[0];\n if (isInCommands(SINGLE_ARG_COMMANDS, redisCommand) && firstArg != null) {\n return processArg(firstArg);\n }\n\n return flatten(cmdArgs.map(arg => processArg(arg)));\n } catch {\n return undefined;\n }\n}\n\n/** Determines whether a redis operation should be considered as \"cache operation\" by checking if a key is prefixed.\n * We only support certain commands (such as 'set', 'get', 'mget'). */\nexport function shouldConsiderForCache(redisCommand: string, keys: string[], prefixes: string[]): boolean {\n if (!getCacheOperation(redisCommand)) {\n return false;\n }\n\n for (const key of keys) {\n if (keyHasPrefix(key, prefixes)) {\n return true;\n }\n }\n return false;\n}\n\n/** Calculates size based on the cache response value */\nexport function calculateCacheItemSize(response: unknown): number | undefined {\n const getSize = (value: unknown): number | undefined => {\n try {\n if (Buffer.isBuffer(value)) return value.byteLength;\n else if (typeof value === 'string') return value.length;\n else if (typeof value === 'number') return value.toString().length;\n else if (value === null || value === undefined) return 0;\n return JSON.stringify(value).length;\n } catch {\n return undefined;\n }\n };\n\n return Array.isArray(response)\n ? response.reduce((acc: number | undefined, curr) => {\n const size = getSize(curr);\n return typeof size === 'number' ? (acc !== undefined ? acc + size : size) : acc;\n }, 0)\n : getSize(response);\n}\n\ntype NestedArray<T> = Array<NestedArray<T> | T>;\n\nfunction flatten<T>(input: NestedArray<T>): T[] {\n const result: T[] = [];\n\n const flattenHelper = (input: NestedArray<T>): void => {\n input.forEach((el: T | NestedArray<T>) => {\n if (Array.isArray(el)) {\n flattenHelper(el);\n } else {\n result.push(el);\n }\n });\n };\n\n flattenHelper(input);\n return result;\n}\n"],"names":[],"mappings":"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"}
@@ -15,6 +15,7 @@ export { postgresIntegration } from './integrations/tracing/postgres.js';
15
15
  export { postgresJsIntegration } from './integrations/tracing/postgresjs.js';
16
16
  export { prismaIntegration } from './integrations/tracing/prisma.js';
17
17
  export { hapiIntegration, setupHapiErrorHandler } from './integrations/tracing/hapi/index.js';
18
+ export { honoIntegration, setupHonoErrorHandler } from './integrations/tracing/hono/index.js';
18
19
  export { koaIntegration, setupKoaErrorHandler } from './integrations/tracing/koa.js';
19
20
  export { connectIntegration, setupConnectErrorHandler } from './integrations/tracing/connect.js';
20
21
  export { knexIntegration } from './integrations/tracing/knex.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -40,7 +40,7 @@ function getFastifyIntegration() {
40
40
  if (!client) {
41
41
  return undefined;
42
42
  } else {
43
- return client.getIntegrationByName(INTEGRATION_NAME) ;
43
+ return client.getIntegrationByName(INTEGRATION_NAME);
44
44
  }
45
45
  }
46
46
 
@@ -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 debug,\n defineIntegration,\n getClient,\n getIsolationScope,\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\n/**\n * Options for the Fastify integration.\n *\n * `shouldHandleError` - Callback method deciding whether error should be captured and sent to Sentry\n * This is used on Fastify v5 where Sentry handles errors in the diagnostics channel.\n * Fastify v3 and v4 use `setupFastifyErrorHandler` instead.\n *\n * @example\n *\n * ```javascript\n * Sentry.init({\n * integrations: [\n * Sentry.fastifyIntegration({\n * shouldHandleError(_error, _request, reply) {\n * return reply.statusCode >= 500;\n * },\n * });\n * },\n * });\n * ```\n *\n */\ninterface FastifyIntegrationOptions {\n /**\n * Callback method deciding whether error should be captured and sent to Sentry\n * This is used on Fastify v5 where Sentry handles errors in the diagnostics channel.\n * Fastify v3 and v4 use `setupFastifyErrorHandler` instead.\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 shouldHandleError: (error: Error, request: FastifyRequest, reply: FastifyReply) => boolean;\n}\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 *\n * ```javascript\n * setupFastifyErrorHandler(app, {\n * shouldHandleError(_error, _request, reply) {\n * return reply.statusCode >= 400;\n * },\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';\n\nexport const instrumentFastifyV3 = generateInstrumentOnce(\n `${INTEGRATION_NAME}.v3`,\n () => new FastifyInstrumentationV3(),\n);\n\nfunction getFastifyIntegration(): ReturnType<typeof _fastifyIntegration> | undefined {\n const client = getClient();\n if (!client) {\n return undefined;\n } else {\n return client.getIntegrationByName(INTEGRATION_NAME) as ReturnType<typeof _fastifyIntegration> | undefined;\n }\n}\n\nfunction handleFastifyError(\n this: {\n diagnosticsChannelExists?: boolean;\n },\n error: Error,\n request: FastifyRequest & { opentelemetry?: () => { span?: Span } },\n reply: FastifyReply,\n handlerOrigin: 'diagnostics-channel' | 'onError-hook',\n): void {\n const shouldHandleError = getFastifyIntegration()?.getShouldHandleError() || defaultShouldHandleError;\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 debug.warn(\n 'Fastify error handler was already registered via diagnostics channel.',\n 'You can safely remove `setupFastifyErrorHandler` call and set `shouldHandleError` on the integration options.',\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, { mechanism: { handled: false, type: 'auto.function.fastify' } });\n }\n}\n\nexport const instrumentFastify = generateInstrumentOnce(`${INTEGRATION_NAME}.v5`, () => {\n const fastifyOtelInstrumentationInstance = new FastifyOtelInstrumentation();\n const plugin = fastifyOtelInstrumentationInstance.plugin();\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 && debug.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, '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 & FastifyIntegrationOptions>;\n});\n\nconst _fastifyIntegration = (({ shouldHandleError }: Partial<FastifyIntegrationOptions>) => {\n let _shouldHandleError: (error: Error, request: FastifyRequest, reply: FastifyReply) => boolean;\n\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n _shouldHandleError = shouldHandleError || defaultShouldHandleError;\n\n instrumentFastifyV3();\n instrumentFastify();\n },\n getShouldHandleError() {\n return _shouldHandleError;\n },\n setShouldHandleError(fn: (error: Error, request: FastifyRequest, reply: FastifyReply) => boolean): void {\n _shouldHandleError = fn;\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((options: Partial<FastifyIntegrationOptions> = {}) =>\n _fastifyIntegration(options),\n);\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 if (options?.shouldHandleError) {\n getFastifyIntegration()?.setShouldHandleError(options.shouldHandleError);\n }\n\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, '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 debug,\n defineIntegration,\n getClient,\n getIsolationScope,\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\n/**\n * Options for the Fastify integration.\n *\n * `shouldHandleError` - Callback method deciding whether error should be captured and sent to Sentry\n * This is used on Fastify v5 where Sentry handles errors in the diagnostics channel.\n * Fastify v3 and v4 use `setupFastifyErrorHandler` instead.\n *\n * @example\n *\n * ```javascript\n * Sentry.init({\n * integrations: [\n * Sentry.fastifyIntegration({\n * shouldHandleError(_error, _request, reply) {\n * return reply.statusCode >= 500;\n * },\n * });\n * },\n * });\n * ```\n *\n */\ninterface FastifyIntegrationOptions {\n /**\n * Callback method deciding whether error should be captured and sent to Sentry\n * This is used on Fastify v5 where Sentry handles errors in the diagnostics channel.\n * Fastify v3 and v4 use `setupFastifyErrorHandler` instead.\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 shouldHandleError: (error: Error, request: FastifyRequest, reply: FastifyReply) => boolean;\n}\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 *\n * ```javascript\n * setupFastifyErrorHandler(app, {\n * shouldHandleError(_error, _request, reply) {\n * return reply.statusCode >= 400;\n * },\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';\n\nexport const instrumentFastifyV3 = generateInstrumentOnce(\n `${INTEGRATION_NAME}.v3`,\n () => new FastifyInstrumentationV3(),\n);\n\nfunction getFastifyIntegration(): ReturnType<typeof _fastifyIntegration> | undefined {\n const client = getClient();\n if (!client) {\n return undefined;\n } else {\n return client.getIntegrationByName(INTEGRATION_NAME);\n }\n}\n\nfunction handleFastifyError(\n this: {\n diagnosticsChannelExists?: boolean;\n },\n error: Error,\n request: FastifyRequest & { opentelemetry?: () => { span?: Span } },\n reply: FastifyReply,\n handlerOrigin: 'diagnostics-channel' | 'onError-hook',\n): void {\n const shouldHandleError = getFastifyIntegration()?.getShouldHandleError() || defaultShouldHandleError;\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 debug.warn(\n 'Fastify error handler was already registered via diagnostics channel.',\n 'You can safely remove `setupFastifyErrorHandler` call and set `shouldHandleError` on the integration options.',\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, { mechanism: { handled: false, type: 'auto.function.fastify' } });\n }\n}\n\nexport const instrumentFastify = generateInstrumentOnce(`${INTEGRATION_NAME}.v5`, () => {\n const fastifyOtelInstrumentationInstance = new FastifyOtelInstrumentation();\n const plugin = fastifyOtelInstrumentationInstance.plugin();\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 && debug.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, '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 & FastifyIntegrationOptions>;\n});\n\nconst _fastifyIntegration = (({ shouldHandleError }: Partial<FastifyIntegrationOptions>) => {\n let _shouldHandleError: (error: Error, request: FastifyRequest, reply: FastifyReply) => boolean;\n\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n _shouldHandleError = shouldHandleError || defaultShouldHandleError;\n\n instrumentFastifyV3();\n instrumentFastify();\n },\n getShouldHandleError() {\n return _shouldHandleError;\n },\n setShouldHandleError(fn: (error: Error, request: FastifyRequest, reply: FastifyReply) => boolean): void {\n _shouldHandleError = fn;\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((options: Partial<FastifyIntegrationOptions> = {}) =>\n _fastifyIntegration(options),\n);\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 if (options?.shouldHandleError) {\n getFastifyIntegration()?.setShouldHandleError(options.shouldHandleError);\n }\n\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, '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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"}
@@ -6,7 +6,7 @@ const INTEGRATION_NAME = 'Firebase';
6
6
 
7
7
  const config = {
8
8
  firestoreSpanCreationHook: span => {
9
- addOriginToSpan(span , 'auto.firebase.otel.firestore');
9
+ addOriginToSpan(span, 'auto.firebase.otel.firestore');
10
10
 
11
11
  span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'db.query');
12
12
  },
@@ -1 +1 @@
1
- {"version":3,"file":"firebase.js","sources":["../../../../../src/integrations/tracing/firebase/firebase.ts"],"sourcesContent":["import type { Span } from '@opentelemetry/api';\nimport type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration, SEMANTIC_ATTRIBUTE_SENTRY_OP } from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\nimport { type FirebaseInstrumentationConfig, FirebaseInstrumentation } from './otel';\n\nconst INTEGRATION_NAME = 'Firebase';\n\nconst config: FirebaseInstrumentationConfig = {\n firestoreSpanCreationHook: span => {\n addOriginToSpan(span as Span, 'auto.firebase.otel.firestore');\n\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'db.query');\n },\n};\n\nexport const instrumentFirebase = generateInstrumentOnce(INTEGRATION_NAME, () => new FirebaseInstrumentation(config));\n\nconst _firebaseIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentFirebase();\n },\n };\n}) satisfies IntegrationFn;\n\nexport const firebaseIntegration = defineIntegration(_firebaseIntegration);\n"],"names":[],"mappings":";;;;AAMA,MAAM,gBAAA,GAAmB,UAAU;;AAEnC,MAAM,MAAM,GAAkC;AAC9C,EAAE,yBAAyB,EAAE,IAAA,IAAQ;AACrC,IAAI,eAAe,CAAC,IAAA,GAAc,8BAA8B,CAAC;;AAEjE,IAAI,IAAI,CAAC,YAAY,CAAC,4BAA4B,EAAE,UAAU,CAAC;AAC/D,GAAG;AACH,CAAC;;AAEM,MAAM,kBAAA,GAAqB,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,IAAI,uBAAuB,CAAC,MAAM,CAAC;;AAEpH,MAAM,oBAAA,IAAwB,MAAM;AACpC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,kBAAkB,EAAE;AAC1B,KAAK;AACL,GAAG;AACH,CAAC,CAAA;;MAEY,mBAAA,GAAsB,iBAAiB,CAAC,oBAAoB;;;;"}
1
+ {"version":3,"file":"firebase.js","sources":["../../../../../src/integrations/tracing/firebase/firebase.ts"],"sourcesContent":["import type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration, SEMANTIC_ATTRIBUTE_SENTRY_OP } from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\nimport { type FirebaseInstrumentationConfig, FirebaseInstrumentation } from './otel';\n\nconst INTEGRATION_NAME = 'Firebase';\n\nconst config: FirebaseInstrumentationConfig = {\n firestoreSpanCreationHook: span => {\n addOriginToSpan(span, 'auto.firebase.otel.firestore');\n\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'db.query');\n },\n};\n\nexport const instrumentFirebase = generateInstrumentOnce(INTEGRATION_NAME, () => new FirebaseInstrumentation(config));\n\nconst _firebaseIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentFirebase();\n },\n };\n}) satisfies IntegrationFn;\n\nexport const firebaseIntegration = defineIntegration(_firebaseIntegration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,gBAAA,GAAmB,UAAU;;AAEnC,MAAM,MAAM,GAAkC;AAC9C,EAAE,yBAAyB,EAAE,IAAA,IAAQ;AACrC,IAAI,eAAe,CAAC,IAAI,EAAE,8BAA8B,CAAC;;AAEzD,IAAI,IAAI,CAAC,YAAY,CAAC,4BAA4B,EAAE,UAAU,CAAC;AAC/D,GAAG;AACH,CAAC;;AAEM,MAAM,kBAAA,GAAqB,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,IAAI,uBAAuB,CAAC,MAAM,CAAC;;AAEpH,MAAM,oBAAA,IAAwB,MAAM;AACpC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,kBAAkB,EAAE;AAC1B,KAAK;AACL,GAAG;AACH,CAAC,CAAA;;MAEY,mBAAA,GAAsB,iBAAiB,CAAC,oBAAoB;;;;"}
@@ -56,7 +56,7 @@ class SentryGoogleGenAiInstrumentation extends InstrumentationBase {
56
56
  const client = getClient();
57
57
  const defaultPii = Boolean(client?.getOptions().sendDefaultPii);
58
58
 
59
- const typedConfig = config ;
59
+ const typedConfig = config;
60
60
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
61
61
  const recordInputs = typedConfig?.recordInputs ?? defaultPii;
62
62
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/google-genai/instrumentation.ts"],"sourcesContent":["import type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport {\n type InstrumentationModuleDefinition,\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n} from '@opentelemetry/instrumentation';\nimport type { GoogleGenAIClient, GoogleGenAIOptions } from '@sentry/core';\nimport { getClient, instrumentGoogleGenAIClient, replaceExports, SDK_VERSION } from '@sentry/core';\n\nconst supportedVersions = ['>=0.10.0 <2'];\n\n/**\n * Represents the patched shape of the Google GenAI module export.\n */\ninterface PatchedModuleExports {\n [key: string]: unknown;\n GoogleGenAI?: unknown;\n}\n\ntype GoogleGenAIInstrumentationOptions = GoogleGenAIOptions & InstrumentationConfig;\n\n/**\n * Sentry Google GenAI instrumentation using OpenTelemetry.\n */\nexport class SentryGoogleGenAiInstrumentation extends InstrumentationBase<GoogleGenAIInstrumentationOptions> {\n public constructor(config: GoogleGenAIInstrumentationOptions = {}) {\n super('@sentry/instrumentation-google-genai', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n */\n public init(): InstrumentationModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition(\n '@google/genai',\n supportedVersions,\n exports => this._patch(exports),\n exports => exports,\n // In CJS, @google/genai re-exports from (dist/node/index.cjs) file.\n // Patching only the root module sometimes misses the real implementation or\n // gets overwritten when that file is loaded. We add a file-level patch so that\n // _patch runs again on the concrete implementation\n [\n new InstrumentationNodeModuleFile(\n '@google/genai/dist/node/index.cjs',\n supportedVersions,\n exports => this._patch(exports),\n exports => exports,\n ),\n ],\n );\n return module;\n }\n\n /**\n * Core patch logic applying instrumentation to the Google GenAI client constructor.\n */\n private _patch(exports: PatchedModuleExports): PatchedModuleExports | void {\n const Original = exports.GoogleGenAI;\n const config = this.getConfig();\n\n if (typeof Original !== 'function') {\n return exports;\n }\n\n const WrappedGoogleGenAI = function (this: unknown, ...args: unknown[]): GoogleGenAIClient {\n const instance = Reflect.construct(Original, args);\n const client = getClient();\n const defaultPii = Boolean(client?.getOptions().sendDefaultPii);\n\n const typedConfig = config as GoogleGenAIInstrumentationOptions;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const recordInputs = typedConfig?.recordInputs ?? defaultPii;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const recordOutputs = typedConfig?.recordOutputs ?? defaultPii;\n\n return instrumentGoogleGenAIClient(instance, {\n recordInputs,\n recordOutputs,\n });\n };\n\n // Preserve static and prototype chains\n Object.setPrototypeOf(WrappedGoogleGenAI, Original);\n Object.setPrototypeOf(WrappedGoogleGenAI.prototype, Original.prototype);\n\n for (const key of Object.getOwnPropertyNames(Original)) {\n if (!['length', 'name', 'prototype'].includes(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(Original, key);\n if (descriptor) {\n Object.defineProperty(WrappedGoogleGenAI, key, descriptor);\n }\n }\n }\n\n // Replace google genai exports with the wrapped constructor\n replaceExports(exports, 'GoogleGenAI', WrappedGoogleGenAI);\n\n return exports;\n }\n}\n"],"names":[],"mappings":";;;AAUA,MAAM,iBAAA,GAAoB,CAAC,aAAa,CAAC;;AAEzC;AACA;AACA;;AAQA;AACA;AACA;AACO,MAAM,gCAAA,SAAyC,mBAAmB,CAAoC;AAC7G,GAAS,WAAW,CAAC,MAAM,GAAsC,EAAE,EAAE;AACrE,IAAI,KAAK,CAAC,sCAAsC,EAAE,WAAW,EAAE,MAAM,CAAC;AACtE;;AAEA;AACA;AACA;AACA,GAAS,IAAI,GAAoC;AACjD,IAAI,MAAM,MAAA,GAAS,IAAI,mCAAmC;AAC1D,MAAM,eAAe;AACrB,MAAM,iBAAiB;AACvB,MAAM,WAAW,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;AACrC,MAAM,OAAA,IAAW,OAAO;AACxB;AACA;AACA;AACA;AACA,MAAM;AACN,QAAQ,IAAI,6BAA6B;AACzC,UAAU,mCAAmC;AAC7C,UAAU,iBAAiB;AAC3B,UAAU,WAAW,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;AACzC,UAAU,OAAA,IAAW,OAAO;AAC5B,SAAS;AACT,OAAO;AACP,KAAK;AACL,IAAI,OAAO,MAAM;AACjB;;AAEA;AACA;AACA;AACA,GAAU,MAAM,CAAC,OAAO,EAAqD;AAC7E,IAAI,MAAM,QAAA,GAAW,OAAO,CAAC,WAAW;AACxC,IAAI,MAAM,MAAA,GAAS,IAAI,CAAC,SAAS,EAAE;;AAEnC,IAAI,IAAI,OAAO,QAAA,KAAa,UAAU,EAAE;AACxC,MAAM,OAAO,OAAO;AACpB;;AAEA,IAAI,MAAM,qBAAqB,WAAyB,GAAG,IAAI,EAAgC;AAC/F,MAAM,MAAM,QAAA,GAAW,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC;AACxD,MAAM,MAAM,MAAA,GAAS,SAAS,EAAE;AAChC,MAAM,MAAM,UAAA,GAAa,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,cAAc,CAAC;;AAErE,MAAM,MAAM,WAAA,GAAc,MAAA;AAC1B;AACA,MAAM,MAAM,YAAA,GAAe,WAAW,EAAE,YAAA,IAAgB,UAAU;AAClE;AACA,MAAM,MAAM,aAAA,GAAgB,WAAW,EAAE,aAAA,IAAiB,UAAU;;AAEpE,MAAM,OAAO,2BAA2B,CAAC,QAAQ,EAAE;AACnD,QAAQ,YAAY;AACpB,QAAQ,aAAa;AACrB,OAAO,CAAC;AACR,KAAK;;AAEL;AACA,IAAI,MAAM,CAAC,cAAc,CAAC,kBAAkB,EAAE,QAAQ,CAAC;AACvD,IAAI,MAAM,CAAC,cAAc,CAAC,kBAAkB,CAAC,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC;;AAE3E,IAAI,KAAK,MAAM,GAAA,IAAO,MAAM,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EAAE;AAC5D,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AAC1D,QAAQ,MAAM,UAAA,GAAa,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,GAAG,CAAC;AACzE,QAAQ,IAAI,UAAU,EAAE;AACxB,UAAU,MAAM,CAAC,cAAc,CAAC,kBAAkB,EAAE,GAAG,EAAE,UAAU,CAAC;AACpE;AACA;AACA;;AAEA;AACA,IAAI,cAAc,CAAC,OAAO,EAAE,aAAa,EAAE,kBAAkB,CAAC;;AAE9D,IAAI,OAAO,OAAO;AAClB;AACA;;;;"}
1
+ {"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/google-genai/instrumentation.ts"],"sourcesContent":["import type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport {\n type InstrumentationModuleDefinition,\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n} from '@opentelemetry/instrumentation';\nimport type { GoogleGenAIClient, GoogleGenAIOptions } from '@sentry/core';\nimport { getClient, instrumentGoogleGenAIClient, replaceExports, SDK_VERSION } from '@sentry/core';\n\nconst supportedVersions = ['>=0.10.0 <2'];\n\n/**\n * Represents the patched shape of the Google GenAI module export.\n */\ninterface PatchedModuleExports {\n [key: string]: unknown;\n GoogleGenAI?: unknown;\n}\n\ntype GoogleGenAIInstrumentationOptions = GoogleGenAIOptions & InstrumentationConfig;\n\n/**\n * Sentry Google GenAI instrumentation using OpenTelemetry.\n */\nexport class SentryGoogleGenAiInstrumentation extends InstrumentationBase<GoogleGenAIInstrumentationOptions> {\n public constructor(config: GoogleGenAIInstrumentationOptions = {}) {\n super('@sentry/instrumentation-google-genai', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n */\n public init(): InstrumentationModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition(\n '@google/genai',\n supportedVersions,\n exports => this._patch(exports),\n exports => exports,\n // In CJS, @google/genai re-exports from (dist/node/index.cjs) file.\n // Patching only the root module sometimes misses the real implementation or\n // gets overwritten when that file is loaded. We add a file-level patch so that\n // _patch runs again on the concrete implementation\n [\n new InstrumentationNodeModuleFile(\n '@google/genai/dist/node/index.cjs',\n supportedVersions,\n exports => this._patch(exports),\n exports => exports,\n ),\n ],\n );\n return module;\n }\n\n /**\n * Core patch logic applying instrumentation to the Google GenAI client constructor.\n */\n private _patch(exports: PatchedModuleExports): PatchedModuleExports | void {\n const Original = exports.GoogleGenAI;\n const config = this.getConfig();\n\n if (typeof Original !== 'function') {\n return exports;\n }\n\n const WrappedGoogleGenAI = function (this: unknown, ...args: unknown[]): GoogleGenAIClient {\n const instance = Reflect.construct(Original, args);\n const client = getClient();\n const defaultPii = Boolean(client?.getOptions().sendDefaultPii);\n\n const typedConfig = config;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const recordInputs = typedConfig?.recordInputs ?? defaultPii;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const recordOutputs = typedConfig?.recordOutputs ?? defaultPii;\n\n return instrumentGoogleGenAIClient(instance, {\n recordInputs,\n recordOutputs,\n });\n };\n\n // Preserve static and prototype chains\n Object.setPrototypeOf(WrappedGoogleGenAI, Original);\n Object.setPrototypeOf(WrappedGoogleGenAI.prototype, Original.prototype);\n\n for (const key of Object.getOwnPropertyNames(Original)) {\n if (!['length', 'name', 'prototype'].includes(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(Original, key);\n if (descriptor) {\n Object.defineProperty(WrappedGoogleGenAI, key, descriptor);\n }\n }\n }\n\n // Replace google genai exports with the wrapped constructor\n replaceExports(exports, 'GoogleGenAI', WrappedGoogleGenAI);\n\n return exports;\n }\n}\n"],"names":[],"mappings":";;;AAUA,MAAM,iBAAA,GAAoB,CAAC,aAAa,CAAC;;AAEzC;AACA;AACA;;AAQA;AACA;AACA;AACO,MAAM,gCAAA,SAAyC,mBAAmB,CAAoC;AAC7G,GAAS,WAAW,CAAC,MAAM,GAAsC,EAAE,EAAE;AACrE,IAAI,KAAK,CAAC,sCAAsC,EAAE,WAAW,EAAE,MAAM,CAAC;AACtE;;AAEA;AACA;AACA;AACA,GAAS,IAAI,GAAoC;AACjD,IAAI,MAAM,MAAA,GAAS,IAAI,mCAAmC;AAC1D,MAAM,eAAe;AACrB,MAAM,iBAAiB;AACvB,MAAM,WAAW,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;AACrC,MAAM,OAAA,IAAW,OAAO;AACxB;AACA;AACA;AACA;AACA,MAAM;AACN,QAAQ,IAAI,6BAA6B;AACzC,UAAU,mCAAmC;AAC7C,UAAU,iBAAiB;AAC3B,UAAU,WAAW,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;AACzC,UAAU,OAAA,IAAW,OAAO;AAC5B,SAAS;AACT,OAAO;AACP,KAAK;AACL,IAAI,OAAO,MAAM;AACjB;;AAEA;AACA;AACA;AACA,GAAU,MAAM,CAAC,OAAO,EAAqD;AAC7E,IAAI,MAAM,QAAA,GAAW,OAAO,CAAC,WAAW;AACxC,IAAI,MAAM,MAAA,GAAS,IAAI,CAAC,SAAS,EAAE;;AAEnC,IAAI,IAAI,OAAO,QAAA,KAAa,UAAU,EAAE;AACxC,MAAM,OAAO,OAAO;AACpB;;AAEA,IAAI,MAAM,qBAAqB,WAAyB,GAAG,IAAI,EAAgC;AAC/F,MAAM,MAAM,QAAA,GAAW,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC;AACxD,MAAM,MAAM,MAAA,GAAS,SAAS,EAAE;AAChC,MAAM,MAAM,UAAA,GAAa,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,cAAc,CAAC;;AAErE,MAAM,MAAM,WAAA,GAAc,MAAM;AAChC;AACA,MAAM,MAAM,YAAA,GAAe,WAAW,EAAE,YAAA,IAAgB,UAAU;AAClE;AACA,MAAM,MAAM,aAAA,GAAgB,WAAW,EAAE,aAAA,IAAiB,UAAU;;AAEpE,MAAM,OAAO,2BAA2B,CAAC,QAAQ,EAAE;AACnD,QAAQ,YAAY;AACpB,QAAQ,aAAa;AACrB,OAAO,CAAC;AACR,KAAK;;AAEL;AACA,IAAI,MAAM,CAAC,cAAc,CAAC,kBAAkB,EAAE,QAAQ,CAAC;AACvD,IAAI,MAAM,CAAC,cAAc,CAAC,kBAAkB,CAAC,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC;;AAE3E,IAAI,KAAK,MAAM,GAAA,IAAO,MAAM,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EAAE;AAC5D,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AAC1D,QAAQ,MAAM,UAAA,GAAa,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,GAAG,CAAC;AACzE,QAAQ,IAAI,UAAU,EAAE;AACxB,UAAU,MAAM,CAAC,cAAc,CAAC,kBAAkB,EAAE,GAAG,EAAE,UAAU,CAAC;AACpE;AACA;AACA;;AAEA;AACA,IAAI,cAAc,CAAC,OAAO,EAAE,aAAa,EAAE,kBAAkB,CAAC;;AAE9D,IAAI,OAAO,OAAO;AAClB;AACA;;;;"}
@@ -0,0 +1,12 @@
1
+ const AttributeNames = {
2
+ HONO_TYPE: 'hono.type',
3
+ HONO_NAME: 'hono.name',
4
+ } ;
5
+
6
+ const HonoTypes = {
7
+ MIDDLEWARE: 'middleware',
8
+ REQUEST_HANDLER: 'request_handler',
9
+ } ;
10
+
11
+ export { AttributeNames, HonoTypes };
12
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sources":["../../../../../src/integrations/tracing/hono/constants.ts"],"sourcesContent":["export const AttributeNames = {\n HONO_TYPE: 'hono.type',\n HONO_NAME: 'hono.name',\n} as const;\n\nexport type AttributeNames = (typeof AttributeNames)[keyof typeof AttributeNames];\n\nexport const HonoTypes = {\n MIDDLEWARE: 'middleware',\n REQUEST_HANDLER: 'request_handler',\n} as const;\n\nexport type HonoTypes = (typeof HonoTypes)[keyof typeof HonoTypes];\n"],"names":[],"mappings":"AAAO,MAAM,iBAAiB;AAC9B,EAAE,SAAS,EAAE,WAAW;AACxB,EAAE,SAAS,EAAE,WAAW;AACxB,CAAA;;AAIO,MAAM,YAAY;AACzB,EAAE,UAAU,EAAE,YAAY;AAC1B,EAAE,eAAe,EAAE,iBAAiB;AACpC,CAAA;;;;"}
@@ -0,0 +1,133 @@
1
+ import { ATTR_HTTP_ROUTE, ATTR_HTTP_REQUEST_METHOD } from '@opentelemetry/semantic-conventions';
2
+ import { defineIntegration, spanToJSON, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, getIsolationScope, getDefaultIsolationScope, debug, httpRequestToRequestData, captureException } from '@sentry/core';
3
+ import { generateInstrumentOnce, ensureIsWrapped } from '@sentry/node-core';
4
+ import { DEBUG_BUILD } from '../../../debug-build.js';
5
+ import { AttributeNames } from './constants.js';
6
+ import { HonoInstrumentation } from './instrumentation.js';
7
+
8
+ const INTEGRATION_NAME = 'Hono';
9
+
10
+ function addHonoSpanAttributes(span) {
11
+ const attributes = spanToJSON(span).data;
12
+ const type = attributes[AttributeNames.HONO_TYPE];
13
+ if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] || !type) {
14
+ return;
15
+ }
16
+
17
+ span.setAttributes({
18
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.otel.hono',
19
+ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${type}.hono`,
20
+ });
21
+
22
+ const name = attributes[AttributeNames.HONO_NAME];
23
+ if (typeof name === 'string') {
24
+ span.updateName(name);
25
+ }
26
+
27
+ if (getIsolationScope() === getDefaultIsolationScope()) {
28
+ DEBUG_BUILD && debug.warn('Isolation scope is default isolation scope - skipping setting transactionName');
29
+ return;
30
+ }
31
+
32
+ const route = attributes[ATTR_HTTP_ROUTE];
33
+ const method = attributes[ATTR_HTTP_REQUEST_METHOD];
34
+ if (typeof route === 'string' && typeof method === 'string') {
35
+ getIsolationScope().setTransactionName(`${method} ${route}`);
36
+ }
37
+ }
38
+
39
+ const instrumentHono = generateInstrumentOnce(
40
+ INTEGRATION_NAME,
41
+ () =>
42
+ new HonoInstrumentation({
43
+ responseHook: span => {
44
+ addHonoSpanAttributes(span);
45
+ },
46
+ }),
47
+ );
48
+
49
+ const _honoIntegration = (() => {
50
+ return {
51
+ name: INTEGRATION_NAME,
52
+ setupOnce() {
53
+ instrumentHono();
54
+ },
55
+ };
56
+ }) ;
57
+
58
+ /**
59
+ * Adds Sentry tracing instrumentation for [Hono](https://hono.dev/).
60
+ *
61
+ * If you also want to capture errors, you need to call `setupHonoErrorHandler(app)` after you set up your Hono server.
62
+ *
63
+ * For more information, see the [hono documentation](https://docs.sentry.io/platforms/javascript/guides/hono/).
64
+ *
65
+ * @example
66
+ * ```javascript
67
+ * const Sentry = require('@sentry/node');
68
+ *
69
+ * Sentry.init({
70
+ * integrations: [Sentry.honoIntegration()],
71
+ * })
72
+ * ```
73
+ */
74
+ const honoIntegration = defineIntegration(_honoIntegration);
75
+
76
+ function honoRequestHandler() {
77
+ return async function sentryRequestMiddleware(context, next) {
78
+ const normalizedRequest = httpRequestToRequestData(context.req);
79
+ getIsolationScope().setSDKProcessingMetadata({ normalizedRequest });
80
+ await next();
81
+ };
82
+ }
83
+
84
+ function defaultShouldHandleError(context) {
85
+ const statusCode = context.res.status;
86
+ return statusCode >= 500;
87
+ }
88
+
89
+ function honoErrorHandler(options) {
90
+ return async function sentryErrorMiddleware(context, next) {
91
+ await next();
92
+
93
+ const shouldHandleError = options?.shouldHandleError || defaultShouldHandleError;
94
+ if (shouldHandleError(context)) {
95
+ (context.res ).sentry = captureException(context.error, {
96
+ mechanism: {
97
+ type: 'auto.middleware.hono',
98
+ handled: false,
99
+ },
100
+ });
101
+ }
102
+ };
103
+ }
104
+
105
+ /**
106
+ * Add a Hono error handler to capture errors to Sentry.
107
+ *
108
+ * @param app The Hono instances
109
+ * @param options Configuration options for the handler
110
+ *
111
+ * @example
112
+ * ```javascript
113
+ * const Sentry = require('@sentry/node');
114
+ * const { Hono } = require("hono");
115
+ *
116
+ * const app = new Hono();
117
+ *
118
+ * Sentry.setupHonoErrorHandler(app);
119
+ *
120
+ * // Add your routes, etc.
121
+ * ```
122
+ */
123
+ function setupHonoErrorHandler(
124
+ app,
125
+ options,
126
+ ) {
127
+ app.use(honoRequestHandler());
128
+ app.use(honoErrorHandler(options));
129
+ ensureIsWrapped(app.use, 'hono');
130
+ }
131
+
132
+ export { honoIntegration, instrumentHono, setupHonoErrorHandler };
133
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../../../src/integrations/tracing/hono/index.ts"],"sourcesContent":["import { ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport type { IntegrationFn, Span } from '@sentry/core';\nimport {\n captureException,\n debug,\n defineIntegration,\n getDefaultIsolationScope,\n getIsolationScope,\n httpRequestToRequestData,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n} from '@sentry/core';\nimport { ensureIsWrapped, generateInstrumentOnce } from '@sentry/node-core';\nimport { DEBUG_BUILD } from '../../../debug-build';\nimport { AttributeNames } from './constants';\nimport { HonoInstrumentation } from './instrumentation';\nimport type { Context, MiddlewareHandler, MiddlewareHandlerInterface, Next } from './types';\n\nconst INTEGRATION_NAME = 'Hono';\n\nfunction addHonoSpanAttributes(span: Span): void {\n const attributes = spanToJSON(span).data;\n const type = attributes[AttributeNames.HONO_TYPE];\n if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] || !type) {\n return;\n }\n\n span.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.otel.hono',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${type}.hono`,\n });\n\n const name = attributes[AttributeNames.HONO_NAME];\n if (typeof name === 'string') {\n span.updateName(name);\n }\n\n if (getIsolationScope() === getDefaultIsolationScope()) {\n DEBUG_BUILD && debug.warn('Isolation scope is default isolation scope - skipping setting transactionName');\n return;\n }\n\n const route = attributes[ATTR_HTTP_ROUTE];\n const method = attributes[ATTR_HTTP_REQUEST_METHOD];\n if (typeof route === 'string' && typeof method === 'string') {\n getIsolationScope().setTransactionName(`${method} ${route}`);\n }\n}\n\nexport const instrumentHono = generateInstrumentOnce(\n INTEGRATION_NAME,\n () =>\n new HonoInstrumentation({\n responseHook: span => {\n addHonoSpanAttributes(span);\n },\n }),\n);\n\nconst _honoIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentHono();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for [Hono](https://hono.dev/).\n *\n * If you also want to capture errors, you need to call `setupHonoErrorHandler(app)` after you set up your Hono server.\n *\n * For more information, see the [hono documentation](https://docs.sentry.io/platforms/javascript/guides/hono/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.honoIntegration()],\n * })\n * ```\n */\nexport const honoIntegration = defineIntegration(_honoIntegration);\n\ninterface HonoHandlerOptions {\n /**\n * Callback method deciding whether error should be captured and sent to Sentry\n * @param error Captured Hono error\n */\n shouldHandleError: (context: Context) => boolean;\n}\n\nfunction honoRequestHandler(): MiddlewareHandler {\n return async function sentryRequestMiddleware(context: Context, next: Next): Promise<void> {\n const normalizedRequest = httpRequestToRequestData(context.req);\n getIsolationScope().setSDKProcessingMetadata({ normalizedRequest });\n await next();\n };\n}\n\nfunction defaultShouldHandleError(context: Context): boolean {\n const statusCode = context.res.status;\n return statusCode >= 500;\n}\n\nfunction honoErrorHandler(options?: Partial<HonoHandlerOptions>): MiddlewareHandler {\n return async function sentryErrorMiddleware(context: Context, next: Next): Promise<void> {\n await next();\n\n const shouldHandleError = options?.shouldHandleError || defaultShouldHandleError;\n if (shouldHandleError(context)) {\n (context.res as { sentry?: string }).sentry = captureException(context.error, {\n mechanism: {\n type: 'auto.middleware.hono',\n handled: false,\n },\n });\n }\n };\n}\n\n/**\n * Add a Hono error handler to capture errors to Sentry.\n *\n * @param app The Hono instances\n * @param options Configuration options for the handler\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n * const { Hono } = require(\"hono\");\n *\n * const app = new Hono();\n *\n * Sentry.setupHonoErrorHandler(app);\n *\n * // Add your routes, etc.\n * ```\n */\nexport function setupHonoErrorHandler(\n app: { use: MiddlewareHandlerInterface },\n options?: Partial<HonoHandlerOptions>,\n): void {\n app.use(honoRequestHandler());\n app.use(honoErrorHandler(options));\n ensureIsWrapped(app.use, 'hono');\n}\n"],"names":[],"mappings":"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"}