@sentry/node 10.51.0 → 10.53.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 (93) hide show
  1. package/build/cjs/index.js +4 -4
  2. package/build/cjs/integrations/http.js +18 -145
  3. package/build/cjs/integrations/http.js.map +1 -1
  4. package/build/cjs/integrations/tracing/anthropic-ai/instrumentation.js +8 -8
  5. package/build/cjs/integrations/tracing/anthropic-ai/instrumentation.js.map +1 -1
  6. package/build/cjs/integrations/tracing/google-genai/instrumentation.js +9 -9
  7. package/build/cjs/integrations/tracing/google-genai/instrumentation.js.map +1 -1
  8. package/build/cjs/integrations/tracing/index.js +21 -22
  9. package/build/cjs/integrations/tracing/index.js.map +1 -1
  10. package/build/cjs/integrations/tracing/langchain/instrumentation.js +12 -12
  11. package/build/cjs/integrations/tracing/langchain/instrumentation.js.map +1 -1
  12. package/build/cjs/integrations/tracing/langgraph/instrumentation.js +12 -12
  13. package/build/cjs/integrations/tracing/langgraph/instrumentation.js.map +1 -1
  14. package/build/cjs/integrations/tracing/openai/instrumentation.js +11 -11
  15. package/build/cjs/integrations/tracing/openai/instrumentation.js.map +1 -1
  16. package/build/cjs/integrations/tracing/postgresjs.js +10 -10
  17. package/build/cjs/integrations/tracing/postgresjs.js.map +1 -1
  18. package/build/cjs/integrations/tracing/{redis.js → redis/index.js} +18 -10
  19. package/build/cjs/integrations/tracing/redis/index.js.map +1 -0
  20. package/build/cjs/integrations/tracing/redis/redis-dc-subscriber.js +186 -0
  21. package/build/cjs/integrations/tracing/redis/redis-dc-subscriber.js.map +1 -0
  22. package/build/cjs/integrations/tracing/redis/vendored/ioredis-instrumentation.js +255 -0
  23. package/build/cjs/integrations/tracing/redis/vendored/ioredis-instrumentation.js.map +1 -0
  24. package/build/cjs/integrations/tracing/redis/vendored/redis-common.js +74 -0
  25. package/build/cjs/integrations/tracing/redis/vendored/redis-common.js.map +1 -0
  26. package/build/cjs/integrations/tracing/redis/vendored/redis-instrumentation.js +685 -0
  27. package/build/cjs/integrations/tracing/redis/vendored/redis-instrumentation.js.map +1 -0
  28. package/build/cjs/integrations/tracing/redis/vendored/semconv.js +47 -0
  29. package/build/cjs/integrations/tracing/redis/vendored/semconv.js.map +1 -0
  30. package/build/cjs/utils/redisCache.js.map +1 -1
  31. package/build/esm/index.js +1 -1
  32. package/build/esm/integrations/http.js +21 -146
  33. package/build/esm/integrations/http.js.map +1 -1
  34. package/build/esm/integrations/tracing/anthropic-ai/instrumentation.js +8 -8
  35. package/build/esm/integrations/tracing/anthropic-ai/instrumentation.js.map +1 -1
  36. package/build/esm/integrations/tracing/google-genai/instrumentation.js +9 -9
  37. package/build/esm/integrations/tracing/google-genai/instrumentation.js.map +1 -1
  38. package/build/esm/integrations/tracing/index.js +2 -3
  39. package/build/esm/integrations/tracing/index.js.map +1 -1
  40. package/build/esm/integrations/tracing/langchain/instrumentation.js +12 -12
  41. package/build/esm/integrations/tracing/langchain/instrumentation.js.map +1 -1
  42. package/build/esm/integrations/tracing/langgraph/instrumentation.js +12 -12
  43. package/build/esm/integrations/tracing/langgraph/instrumentation.js.map +1 -1
  44. package/build/esm/integrations/tracing/openai/instrumentation.js +11 -11
  45. package/build/esm/integrations/tracing/openai/instrumentation.js.map +1 -1
  46. package/build/esm/integrations/tracing/postgresjs.js +10 -10
  47. package/build/esm/integrations/tracing/postgresjs.js.map +1 -1
  48. package/build/esm/integrations/tracing/{redis.js → redis/index.js} +17 -9
  49. package/build/esm/integrations/tracing/redis/index.js.map +1 -0
  50. package/build/esm/integrations/tracing/redis/redis-dc-subscriber.js +184 -0
  51. package/build/esm/integrations/tracing/redis/redis-dc-subscriber.js.map +1 -0
  52. package/build/esm/integrations/tracing/redis/vendored/ioredis-instrumentation.js +253 -0
  53. package/build/esm/integrations/tracing/redis/vendored/ioredis-instrumentation.js.map +1 -0
  54. package/build/esm/integrations/tracing/redis/vendored/redis-common.js +72 -0
  55. package/build/esm/integrations/tracing/redis/vendored/redis-common.js.map +1 -0
  56. package/build/esm/integrations/tracing/redis/vendored/redis-instrumentation.js +683 -0
  57. package/build/esm/integrations/tracing/redis/vendored/redis-instrumentation.js.map +1 -0
  58. package/build/esm/integrations/tracing/redis/vendored/semconv.js +39 -0
  59. package/build/esm/integrations/tracing/redis/vendored/semconv.js.map +1 -0
  60. package/build/esm/package.json +1 -1
  61. package/build/esm/utils/redisCache.js.map +1 -1
  62. package/build/types/integrations/http.d.ts +8 -15
  63. package/build/types/integrations/http.d.ts.map +1 -1
  64. package/build/types/integrations/tracing/index.d.ts.map +1 -1
  65. package/build/types/integrations/tracing/{redis.d.ts → redis/index.d.ts} +3 -3
  66. package/build/types/integrations/tracing/redis/index.d.ts.map +1 -0
  67. package/build/types/integrations/tracing/redis/redis-dc-subscriber.d.ts +17 -0
  68. package/build/types/integrations/tracing/redis/redis-dc-subscriber.d.ts.map +1 -0
  69. package/build/types/integrations/tracing/redis/vendored/ioredis-instrumentation.d.ts +15 -0
  70. package/build/types/integrations/tracing/redis/vendored/ioredis-instrumentation.d.ts.map +1 -0
  71. package/build/types/integrations/tracing/redis/vendored/redis-common.d.ts +6 -0
  72. package/build/types/integrations/tracing/redis/vendored/redis-common.d.ts.map +1 -0
  73. package/build/types/integrations/tracing/redis/vendored/redis-instrumentation.d.ts +16 -0
  74. package/build/types/integrations/tracing/redis/vendored/redis-instrumentation.d.ts.map +1 -0
  75. package/build/types/integrations/tracing/redis/vendored/semconv.d.ts +8 -0
  76. package/build/types/integrations/tracing/redis/vendored/semconv.d.ts.map +1 -0
  77. package/build/types/integrations/tracing/redis/vendored/types.d.ts +58 -0
  78. package/build/types/integrations/tracing/redis/vendored/types.d.ts.map +1 -0
  79. package/build/types/utils/redisCache.d.ts +1 -1
  80. package/build/types/utils/redisCache.d.ts.map +1 -1
  81. package/build/types-ts3.8/integrations/http.d.ts +8 -15
  82. package/build/types-ts3.8/integrations/tracing/{redis.d.ts → redis/index.d.ts} +3 -3
  83. package/build/types-ts3.8/integrations/tracing/redis/redis-dc-subscriber.d.ts +17 -0
  84. package/build/types-ts3.8/integrations/tracing/redis/vendored/ioredis-instrumentation.d.ts +15 -0
  85. package/build/types-ts3.8/integrations/tracing/redis/vendored/redis-common.d.ts +6 -0
  86. package/build/types-ts3.8/integrations/tracing/redis/vendored/redis-instrumentation.d.ts +16 -0
  87. package/build/types-ts3.8/integrations/tracing/redis/vendored/semconv.d.ts +8 -0
  88. package/build/types-ts3.8/integrations/tracing/redis/vendored/types.d.ts +58 -0
  89. package/build/types-ts3.8/utils/redisCache.d.ts +1 -1
  90. package/package.json +4 -6
  91. package/build/cjs/integrations/tracing/redis.js.map +0 -1
  92. package/build/esm/integrations/tracing/redis.js.map +0 -1
  93. package/build/types/integrations/tracing/redis.d.ts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-instrumentation.js","sources":["../../../../../../src/integrations/tracing/redis/vendored/redis-instrumentation.ts"],"sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * NOTICE from the Sentry authors:\n * - Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/instrumentation-redis-v0.62.0/packages/instrumentation-redis\n * - Upstream version: @opentelemetry/instrumentation-redis@0.62.0\n * - Minor TypeScript adjustments for this repository's compiler settings\n */\n/* eslint-disable -- vendored @opentelemetry/instrumentation-redis */\n\nimport { context, SpanKind, SpanStatusCode, trace } from '@opentelemetry/api';\nimport type { DiagLogger, Span, TracerProvider } from '@opentelemetry/api';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n isWrapped,\n safeExecuteInTheMiddle,\n SemconvStability,\n semconvStabilityFromStr,\n} from '@opentelemetry/instrumentation';\nimport {\n ATTR_DB_OPERATION_NAME,\n ATTR_DB_QUERY_TEXT,\n ATTR_DB_SYSTEM_NAME,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n} from '@opentelemetry/semantic-conventions';\n\nimport { defaultDbStatementSerializer } from './redis-common';\nimport {\n ATTR_DB_CONNECTION_STRING,\n ATTR_DB_STATEMENT,\n ATTR_DB_SYSTEM,\n ATTR_NET_PEER_NAME,\n ATTR_NET_PEER_PORT,\n DB_SYSTEM_NAME_VALUE_REDIS,\n DB_SYSTEM_VALUE_REDIS,\n} from './semconv';\nimport type { RedisInstrumentationConfig } from './types';\n\nconst PACKAGE_NAME = '@opentelemetry/instrumentation-redis';\nconst PACKAGE_VERSION = '0.62.0';\n\n// ---- Internal types ----\n\ninterface RedisPluginClientTypes {\n connection_options?: {\n port?: string | number;\n host?: string;\n };\n address?: string;\n}\n\ninterface RedisCommand {\n command: string;\n args: string[];\n buffer_args: boolean;\n callback: (err: Error | null, reply: unknown) => void;\n call_on_write: boolean;\n}\n\ninterface MultiErrorReply extends Error {\n replies: unknown[];\n errorIndexes: Array<number>;\n}\n\ninterface OpenSpanInfo {\n span: Span;\n commandName: string;\n commandArgs: Array<string | Buffer>;\n}\n\nconst OTEL_OPEN_SPANS = Symbol('opentelemetry.instrumentation.redis.open_spans');\nconst MULTI_COMMAND_OPTIONS = Symbol('opentelemetry.instrumentation.redis.multi_command_options');\n\n// ---- v4-v5 utils ----\n\nfunction removeCredentialsFromDBConnectionStringAttribute(\n diagLogger: DiagLogger,\n url: string | undefined,\n): string | undefined {\n if (typeof url !== 'string' || !url) {\n return undefined;\n }\n try {\n const u = new URL(url);\n u.searchParams.delete('user_pwd');\n u.username = '';\n u.password = '';\n return u.href;\n } catch (err) {\n diagLogger.error('failed to sanitize redis connection url', err);\n }\n return undefined;\n}\n\nfunction getClientAttributes(\n diagLogger: DiagLogger,\n options: any,\n semconvStability: SemconvStability,\n): Record<string, any> {\n const attributes: Record<string, any> = {};\n if (semconvStability & SemconvStability.OLD) {\n Object.assign(attributes, {\n [ATTR_DB_SYSTEM]: DB_SYSTEM_VALUE_REDIS,\n [ATTR_NET_PEER_NAME]: options?.socket?.host,\n [ATTR_NET_PEER_PORT]: options?.socket?.port,\n [ATTR_DB_CONNECTION_STRING]: removeCredentialsFromDBConnectionStringAttribute(diagLogger, options?.url),\n });\n }\n if (semconvStability & SemconvStability.STABLE) {\n Object.assign(attributes, {\n [ATTR_DB_SYSTEM_NAME]: DB_SYSTEM_NAME_VALUE_REDIS,\n [ATTR_SERVER_ADDRESS]: options?.socket?.host,\n [ATTR_SERVER_PORT]: options?.socket?.port,\n });\n }\n return attributes;\n}\n\n// ---- v2-v3 utils ----\n\nfunction endSpanV2(span: Span, err: Error | null | undefined): void {\n if (err) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: err.message,\n });\n }\n span.end();\n}\n\nfunction getTracedCreateClient(original: Function): Function {\n return function createClientTrace(this: any) {\n const client = original.apply(this, arguments);\n return context.bind(context.active(), client);\n };\n}\n\nfunction getTracedCreateStreamTrace(original: Function): Function {\n return function create_stream_trace(this: any) {\n if (!Object.prototype.hasOwnProperty.call(this, 'stream')) {\n Object.defineProperty(this, 'stream', {\n get() {\n return this._patched_redis_stream;\n },\n set(val: any) {\n context.bind(context.active(), val);\n this._patched_redis_stream = val;\n },\n });\n }\n return original.apply(this, arguments);\n };\n}\n\n// ---- RedisInstrumentationV2_V3 ----\n\nclass RedisInstrumentationV2_V3 extends InstrumentationBase<RedisInstrumentationConfig> {\n static COMPONENT = 'redis';\n _semconvStability: SemconvStability;\n\n constructor(config: RedisInstrumentationConfig = {}) {\n super(PACKAGE_NAME, PACKAGE_VERSION, config);\n this._semconvStability = config.semconvStability\n ? config.semconvStability\n : semconvStabilityFromStr('database', process.env['OTEL_SEMCONV_STABILITY_OPT_IN']);\n }\n\n override setConfig(config: RedisInstrumentationConfig = {}): void {\n super.setConfig(config);\n this._semconvStability = config.semconvStability\n ? config.semconvStability\n : semconvStabilityFromStr('database', process.env['OTEL_SEMCONV_STABILITY_OPT_IN']);\n }\n\n init() {\n return [\n new InstrumentationNodeModuleDefinition(\n 'redis',\n ['>=2.6.0 <4'],\n (moduleExports: any) => {\n if (isWrapped(moduleExports.RedisClient.prototype['internal_send_command'])) {\n this._unwrap(moduleExports.RedisClient.prototype, 'internal_send_command');\n }\n this._wrap(moduleExports.RedisClient.prototype, 'internal_send_command', this._getPatchInternalSendCommand());\n if (isWrapped(moduleExports.RedisClient.prototype['create_stream'])) {\n this._unwrap(moduleExports.RedisClient.prototype, 'create_stream');\n }\n this._wrap(moduleExports.RedisClient.prototype, 'create_stream', this._getPatchCreateStream());\n if (isWrapped(moduleExports.createClient)) {\n this._unwrap(moduleExports, 'createClient');\n }\n this._wrap(moduleExports, 'createClient', this._getPatchCreateClient());\n return moduleExports;\n },\n (moduleExports: any) => {\n if (moduleExports === undefined) return;\n this._unwrap(moduleExports.RedisClient.prototype, 'internal_send_command');\n this._unwrap(moduleExports.RedisClient.prototype, 'create_stream');\n this._unwrap(moduleExports, 'createClient');\n },\n ),\n ];\n }\n\n private _getPatchInternalSendCommand() {\n const instrumentation = this;\n return function internal_send_command(original: Function) {\n return function internal_send_command_trace(this: RedisPluginClientTypes, cmd: RedisCommand) {\n if (arguments.length !== 1 || typeof cmd !== 'object') {\n return original.apply(this, arguments);\n }\n const config = instrumentation.getConfig();\n const hasNoParentSpan = trace.getSpan(context.active()) === undefined;\n if (config.requireParentSpan === true && hasNoParentSpan) {\n return original.apply(this, arguments);\n }\n const dbStatementSerializer = config?.dbStatementSerializer || defaultDbStatementSerializer;\n const attributes: Record<string, any> = {};\n if (instrumentation._semconvStability & SemconvStability.OLD) {\n Object.assign(attributes, {\n [ATTR_DB_SYSTEM]: DB_SYSTEM_VALUE_REDIS,\n [ATTR_DB_STATEMENT]: dbStatementSerializer(cmd.command, cmd.args),\n });\n }\n if (instrumentation._semconvStability & SemconvStability.STABLE) {\n Object.assign(attributes, {\n [ATTR_DB_SYSTEM_NAME]: DB_SYSTEM_NAME_VALUE_REDIS,\n [ATTR_DB_OPERATION_NAME]: cmd.command,\n [ATTR_DB_QUERY_TEXT]: dbStatementSerializer(cmd.command, cmd.args),\n });\n }\n attributes[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] = 'auto.db.otel.redis';\n const span = instrumentation.tracer.startSpan(`${RedisInstrumentationV2_V3.COMPONENT}-${cmd.command}`, {\n kind: SpanKind.CLIENT,\n attributes,\n });\n if (this.connection_options) {\n const connectionAttributes: Record<string, any> = {};\n if (instrumentation._semconvStability & SemconvStability.OLD) {\n Object.assign(connectionAttributes, {\n [ATTR_NET_PEER_NAME]: this.connection_options.host,\n [ATTR_NET_PEER_PORT]: this.connection_options.port,\n });\n }\n if (instrumentation._semconvStability & SemconvStability.STABLE) {\n Object.assign(connectionAttributes, {\n [ATTR_SERVER_ADDRESS]: this.connection_options.host,\n [ATTR_SERVER_PORT]: this.connection_options.port,\n });\n }\n span.setAttributes(connectionAttributes);\n }\n if (this.address && instrumentation._semconvStability & SemconvStability.OLD) {\n span.setAttribute(ATTR_DB_CONNECTION_STRING, `redis://${this.address}`);\n }\n const originalCallback = arguments[0].callback;\n if (originalCallback) {\n const originalContext = context.active();\n arguments[0].callback = function callback(this: any, err: Error | null, reply: unknown) {\n if (config?.responseHook) {\n const responseHook = config.responseHook;\n safeExecuteInTheMiddle(\n () => {\n responseHook(span, cmd.command, cmd.args, reply);\n },\n (e: Error | undefined) => {\n if (e) {\n instrumentation._diag.error('Error executing responseHook', e);\n }\n },\n true,\n );\n }\n endSpanV2(span, err);\n return context.with(originalContext, originalCallback, this, ...arguments);\n };\n }\n try {\n return original.apply(this, arguments);\n } catch (rethrow) {\n endSpanV2(span, rethrow as Error);\n throw rethrow;\n }\n };\n };\n }\n\n private _getPatchCreateClient() {\n return function createClient(original: Function) {\n return getTracedCreateClient(original);\n };\n }\n\n private _getPatchCreateStream() {\n return function createReadStream(original: Function) {\n return getTracedCreateStreamTrace(original);\n };\n }\n}\n\n// ---- RedisInstrumentationV4_V5 ----\n\nclass RedisInstrumentationV4_V5 extends InstrumentationBase<RedisInstrumentationConfig> {\n static COMPONENT = 'redis';\n _semconvStability: SemconvStability;\n\n constructor(config: RedisInstrumentationConfig = {}) {\n super(PACKAGE_NAME, PACKAGE_VERSION, config);\n this._semconvStability = config.semconvStability\n ? config.semconvStability\n : semconvStabilityFromStr('database', process.env['OTEL_SEMCONV_STABILITY_OPT_IN']);\n }\n\n override setConfig(config: RedisInstrumentationConfig = {}): void {\n super.setConfig(config);\n this._semconvStability = config.semconvStability\n ? config.semconvStability\n : semconvStabilityFromStr('database', process.env['OTEL_SEMCONV_STABILITY_OPT_IN']);\n }\n\n init() {\n return [\n this._getInstrumentationNodeModuleDefinition('@redis/client'),\n this._getInstrumentationNodeModuleDefinition('@node-redis/client'),\n ];\n }\n\n private _getInstrumentationNodeModuleDefinition(basePackageName: string) {\n const commanderModuleFile = new InstrumentationNodeModuleFile(\n `${basePackageName}/dist/lib/commander.js`,\n ['^1.0.0'],\n (moduleExports: any, moduleVersion?: string) => {\n const transformCommandArguments = moduleExports.transformCommandArguments;\n if (!transformCommandArguments) {\n this._diag.error('internal instrumentation error, missing transformCommandArguments function');\n return moduleExports;\n }\n const functionToPatch = moduleVersion?.startsWith('1.0.') ? 'extendWithCommands' : 'attachCommands';\n if (isWrapped(moduleExports?.[functionToPatch])) {\n this._unwrap(moduleExports, functionToPatch);\n }\n this._wrap(moduleExports, functionToPatch, this._getPatchExtendWithCommands(transformCommandArguments));\n return moduleExports;\n },\n (moduleExports: any) => {\n if (isWrapped(moduleExports?.extendWithCommands)) {\n this._unwrap(moduleExports, 'extendWithCommands');\n }\n if (isWrapped(moduleExports?.attachCommands)) {\n this._unwrap(moduleExports, 'attachCommands');\n }\n },\n );\n\n const multiCommanderModule = new InstrumentationNodeModuleFile(\n `${basePackageName}/dist/lib/client/multi-command.js`,\n ['^1.0.0', '>=5.0.0 <5.12.0'],\n (moduleExports: any) => {\n const redisClientMultiCommandPrototype = moduleExports?.default?.prototype;\n if (isWrapped(redisClientMultiCommandPrototype?.exec)) {\n this._unwrap(redisClientMultiCommandPrototype, 'exec');\n }\n this._wrap(redisClientMultiCommandPrototype, 'exec', this._getPatchMultiCommandsExec(false));\n if (isWrapped(redisClientMultiCommandPrototype?.execAsPipeline)) {\n this._unwrap(redisClientMultiCommandPrototype, 'execAsPipeline');\n }\n this._wrap(redisClientMultiCommandPrototype, 'execAsPipeline', this._getPatchMultiCommandsExec(true));\n if (isWrapped(redisClientMultiCommandPrototype?.addCommand)) {\n this._unwrap(redisClientMultiCommandPrototype, 'addCommand');\n }\n this._wrap(redisClientMultiCommandPrototype, 'addCommand', this._getPatchMultiCommandsAddCommand());\n return moduleExports;\n },\n (moduleExports: any) => {\n const redisClientMultiCommandPrototype = moduleExports?.default?.prototype;\n if (isWrapped(redisClientMultiCommandPrototype?.exec)) {\n this._unwrap(redisClientMultiCommandPrototype, 'exec');\n }\n if (isWrapped(redisClientMultiCommandPrototype?.execAsPipeline)) {\n this._unwrap(redisClientMultiCommandPrototype, 'execAsPipeline');\n }\n if (isWrapped(redisClientMultiCommandPrototype?.addCommand)) {\n this._unwrap(redisClientMultiCommandPrototype, 'addCommand');\n }\n },\n );\n\n const clientIndexModule = new InstrumentationNodeModuleFile(\n `${basePackageName}/dist/lib/client/index.js`,\n ['^1.0.0', '>=5.0.0 <5.12.0'],\n (moduleExports: any) => {\n const redisClientPrototype = moduleExports?.default?.prototype;\n if (redisClientPrototype?.multi) {\n if (isWrapped(redisClientPrototype?.multi)) {\n this._unwrap(redisClientPrototype, 'multi');\n }\n this._wrap(redisClientPrototype, 'multi', this._getPatchRedisClientMulti());\n }\n if (redisClientPrototype?.MULTI) {\n if (isWrapped(redisClientPrototype?.MULTI)) {\n this._unwrap(redisClientPrototype, 'MULTI');\n }\n this._wrap(redisClientPrototype, 'MULTI', this._getPatchRedisClientMulti());\n }\n if (isWrapped(redisClientPrototype?.sendCommand)) {\n this._unwrap(redisClientPrototype, 'sendCommand');\n }\n this._wrap(redisClientPrototype, 'sendCommand', this._getPatchRedisClientSendCommand());\n if (isWrapped(redisClientPrototype?.connect)) {\n this._unwrap(redisClientPrototype, 'connect');\n }\n this._wrap(redisClientPrototype, 'connect', this._getPatchedClientConnect());\n return moduleExports;\n },\n (moduleExports: any) => {\n const redisClientPrototype = moduleExports?.default?.prototype;\n if (isWrapped(redisClientPrototype?.multi)) {\n this._unwrap(redisClientPrototype, 'multi');\n }\n if (isWrapped(redisClientPrototype?.MULTI)) {\n this._unwrap(redisClientPrototype, 'MULTI');\n }\n if (isWrapped(redisClientPrototype?.sendCommand)) {\n this._unwrap(redisClientPrototype, 'sendCommand');\n }\n if (isWrapped(redisClientPrototype?.connect)) {\n this._unwrap(redisClientPrototype, 'connect');\n }\n },\n );\n\n return new InstrumentationNodeModuleDefinition(\n basePackageName,\n ['^1.0.0', '>=5.0.0 <5.12.0'],\n (moduleExports: any) => moduleExports,\n () => {},\n [commanderModuleFile, multiCommanderModule, clientIndexModule],\n );\n }\n\n private _getPatchExtendWithCommands(transformCommandArguments: Function) {\n const plugin = this;\n return function extendWithCommandsPatchWrapper(original: Function) {\n return function extendWithCommandsPatch(this: any, config: any) {\n if (config?.BaseClass?.name !== 'RedisClient') {\n return original.apply(this, arguments);\n }\n const origExecutor = config.executor;\n config.executor = function (this: any, command: any, args: any) {\n const redisCommandArguments = transformCommandArguments(command, args).args;\n return plugin._traceClientCommand(origExecutor, this, arguments, redisCommandArguments);\n };\n return original.apply(this, arguments);\n };\n };\n }\n\n private _getPatchMultiCommandsExec(isPipeline: boolean) {\n const plugin = this;\n return function execPatchWrapper(original: Function) {\n return function execPatch(this: any) {\n const execRes = original.apply(this, arguments);\n if (typeof execRes?.then !== 'function') {\n plugin._diag.error('non-promise result when patching exec/execAsPipeline');\n return execRes;\n }\n return execRes\n .then((redisRes: unknown[]) => {\n const openSpans: OpenSpanInfo[] = this[OTEL_OPEN_SPANS];\n plugin._endSpansWithRedisReplies(openSpans, redisRes, isPipeline);\n return redisRes;\n })\n .catch((err: any) => {\n const openSpans: OpenSpanInfo[] = this[OTEL_OPEN_SPANS];\n if (!openSpans) {\n plugin._diag.error('cannot find open spans to end for multi/pipeline');\n } else {\n const replies =\n err.constructor.name === 'MultiErrorReply'\n ? (err as MultiErrorReply).replies\n : new Array(openSpans.length).fill(err);\n plugin._endSpansWithRedisReplies(openSpans, replies, isPipeline);\n }\n return Promise.reject(err);\n });\n };\n };\n }\n\n private _getPatchMultiCommandsAddCommand() {\n const plugin = this;\n return function addCommandWrapper(original: Function) {\n return function addCommandPatch(this: any, args: any) {\n return plugin._traceClientCommand(original, this, arguments, args);\n };\n };\n }\n\n private _getPatchRedisClientMulti() {\n return function multiPatchWrapper(original: Function) {\n return function multiPatch(this: any) {\n const multiRes: any = original.apply(this, arguments);\n multiRes[MULTI_COMMAND_OPTIONS] = this.options;\n return multiRes;\n };\n };\n }\n\n private _getPatchRedisClientSendCommand() {\n const plugin = this;\n return function sendCommandWrapper(original: Function) {\n return function sendCommandPatch(this: any, args: any) {\n return plugin._traceClientCommand(original, this, arguments, args);\n };\n };\n }\n\n private _getPatchedClientConnect() {\n const plugin = this;\n return function connectWrapper(original: Function) {\n return function patchedConnect(this: any) {\n const options = this.options;\n const attributes = getClientAttributes(plugin._diag, options, plugin._semconvStability);\n attributes[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] = 'auto.db.otel.redis';\n const span = plugin.tracer.startSpan(`${RedisInstrumentationV4_V5.COMPONENT}-connect`, {\n kind: SpanKind.CLIENT,\n attributes,\n });\n const res = context.with(trace.setSpan(context.active(), span), () => {\n return original.apply(this);\n });\n return res\n .then((result: any) => {\n span.end();\n return result;\n })\n .catch((error: Error) => {\n span.recordException(error);\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n });\n span.end();\n return Promise.reject(error);\n });\n };\n };\n }\n\n _traceClientCommand(\n origFunction: Function,\n origThis: any,\n origArguments: IArguments,\n redisCommandArguments: Array<string | Buffer>,\n ): any {\n const hasNoParentSpan = trace.getSpan(context.active()) === undefined;\n if (hasNoParentSpan && this.getConfig().requireParentSpan) {\n return origFunction.apply(origThis, origArguments);\n }\n const clientOptions = origThis.options || origThis[MULTI_COMMAND_OPTIONS];\n const commandName = redisCommandArguments[0] as string;\n const commandArgs = redisCommandArguments.slice(1);\n const dbStatementSerializer = this.getConfig().dbStatementSerializer || defaultDbStatementSerializer;\n const attributes = getClientAttributes(this._diag, clientOptions, this._semconvStability);\n if (this._semconvStability & SemconvStability.STABLE) {\n attributes[ATTR_DB_OPERATION_NAME] = commandName;\n }\n try {\n const dbStatement = dbStatementSerializer(commandName, commandArgs);\n if (dbStatement != null) {\n if (this._semconvStability & SemconvStability.OLD) {\n attributes[ATTR_DB_STATEMENT] = dbStatement;\n }\n if (this._semconvStability & SemconvStability.STABLE) {\n attributes[ATTR_DB_QUERY_TEXT] = dbStatement;\n }\n }\n } catch (e) {\n this._diag.error('dbStatementSerializer throw an exception', e, { commandName });\n }\n attributes[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] = 'auto.db.otel.redis';\n const span = this.tracer.startSpan(`${RedisInstrumentationV4_V5.COMPONENT}-${commandName}`, {\n kind: SpanKind.CLIENT,\n attributes,\n });\n const res = context.with(trace.setSpan(context.active(), span), () => {\n return origFunction.apply(origThis, origArguments);\n });\n if (typeof res?.then === 'function') {\n res.then(\n (redisRes: unknown) => {\n this._endSpanWithResponse(span, commandName, commandArgs, redisRes, undefined);\n },\n (err: Error) => {\n this._endSpanWithResponse(span, commandName, commandArgs, null, err);\n },\n );\n } else {\n const redisClientMultiCommand: any = res;\n redisClientMultiCommand[OTEL_OPEN_SPANS] = redisClientMultiCommand[OTEL_OPEN_SPANS] || [];\n redisClientMultiCommand[OTEL_OPEN_SPANS].push({\n span,\n commandName,\n commandArgs,\n });\n }\n return res;\n }\n\n _endSpansWithRedisReplies(openSpans: OpenSpanInfo[] | undefined, replies: unknown[], isPipeline = false): void {\n if (!openSpans) {\n return this._diag.error('cannot find open spans to end for redis multi/pipeline');\n }\n if (replies.length !== openSpans.length) {\n return this._diag.error('number of multi command spans does not match response from redis');\n }\n const allCommands = openSpans.map(s => s.commandName);\n const allSameCommand = allCommands.every(cmd => cmd === allCommands[0]);\n const operationName = allSameCommand\n ? (isPipeline ? 'PIPELINE ' : 'MULTI ') + allCommands[0]\n : isPipeline\n ? 'PIPELINE'\n : 'MULTI';\n for (let i = 0; i < openSpans.length; i++) {\n const { span, commandArgs } = openSpans[i]!;\n const currCommandRes = replies[i];\n const [res, err] = currCommandRes instanceof Error ? [null, currCommandRes] : [currCommandRes, undefined];\n if (this._semconvStability & SemconvStability.STABLE) {\n span.setAttribute(ATTR_DB_OPERATION_NAME, operationName);\n }\n this._endSpanWithResponse(span, allCommands[i]!, commandArgs, res, err);\n }\n }\n\n _endSpanWithResponse(\n span: Span,\n commandName: string,\n commandArgs: Array<string | Buffer>,\n response: unknown,\n error: Error | null | undefined,\n ): void {\n const { responseHook } = this.getConfig();\n if (!error && responseHook) {\n try {\n responseHook(span, commandName, commandArgs, response);\n } catch (err) {\n this._diag.error('responseHook throw an exception', err);\n }\n }\n if (error) {\n span.recordException(error);\n span.setStatus({ code: SpanStatusCode.ERROR, message: error?.message });\n }\n span.end();\n }\n}\n\n// ---- RedisInstrumentation (wrapper) ----\n\nconst DEFAULT_CONFIG: RedisInstrumentationConfig = {\n requireParentSpan: false,\n};\n\nexport class RedisInstrumentation extends InstrumentationBase<RedisInstrumentationConfig> {\n private instrumentationV2_V3: RedisInstrumentationV2_V3;\n private instrumentationV4_V5: RedisInstrumentationV4_V5;\n private initialized = false;\n\n constructor(config: RedisInstrumentationConfig = {}) {\n const resolvedConfig = { ...DEFAULT_CONFIG, ...config };\n super(PACKAGE_NAME, PACKAGE_VERSION, resolvedConfig);\n this.instrumentationV2_V3 = new RedisInstrumentationV2_V3(this.getConfig());\n this.instrumentationV4_V5 = new RedisInstrumentationV4_V5(this.getConfig());\n this.initialized = true;\n }\n\n override setConfig(config: RedisInstrumentationConfig = {}): void {\n const newConfig = { ...DEFAULT_CONFIG, ...config };\n super.setConfig(newConfig);\n if (!this.initialized) {\n return;\n }\n this.instrumentationV2_V3.setConfig(newConfig);\n this.instrumentationV4_V5.setConfig(newConfig);\n }\n\n init() {}\n\n override getModuleDefinitions() {\n return [...this.instrumentationV2_V3.getModuleDefinitions(), ...this.instrumentationV4_V5.getModuleDefinitions()];\n }\n\n override setTracerProvider(tracerProvider: TracerProvider): void {\n super.setTracerProvider(tracerProvider);\n if (!this.initialized) {\n return;\n }\n this.instrumentationV2_V3.setTracerProvider(tracerProvider);\n this.instrumentationV4_V5.setTracerProvider(tracerProvider);\n }\n\n override enable(): void {\n super.enable();\n if (!this.initialized) {\n return;\n }\n this.instrumentationV2_V3.enable();\n this.instrumentationV4_V5.enable();\n }\n\n override disable(): void {\n super.disable();\n if (!this.initialized) {\n return;\n }\n this.instrumentationV2_V3.disable();\n this.instrumentationV4_V5.disable();\n }\n}\n"],"names":["SemconvStability","ATTR_DB_SYSTEM","DB_SYSTEM_VALUE_REDIS","ATTR_NET_PEER_NAME","ATTR_NET_PEER_PORT","ATTR_DB_CONNECTION_STRING","ATTR_DB_SYSTEM_NAME","DB_SYSTEM_NAME_VALUE_REDIS","ATTR_SERVER_ADDRESS","ATTR_SERVER_PORT","SpanStatusCode","context","InstrumentationBase","semconvStabilityFromStr","InstrumentationNodeModuleDefinition","isWrapped","instrumentation","trace","defaultDbStatementSerializer","ATTR_DB_STATEMENT","ATTR_DB_OPERATION_NAME","ATTR_DB_QUERY_TEXT","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SpanKind","safeExecuteInTheMiddle","InstrumentationNodeModuleFile"],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ /*
4
+ * Copyright The OpenTelemetry Authors
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * https://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ *
18
+ * NOTICE from the Sentry authors:
19
+ * - Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/instrumentation-redis-v0.62.0/packages/instrumentation-redis
20
+ * - Upstream version: @opentelemetry/instrumentation-redis@0.62.0
21
+ * - Minor TypeScript adjustments for this repository's compiler settings
22
+ */
23
+ /* eslint-disable -- vendored @opentelemetry/instrumentation-redis */
24
+
25
+ /*
26
+ * This file contains a copy of unstable semantic convention definitions
27
+ * used by the vendored redis/ioredis instrumentations.
28
+ * @see https://github.com/open-telemetry/opentelemetry-js/tree/main/semantic-conventions#unstable-semconv
29
+ */
30
+
31
+ // Deprecated constants kept for backwards compatibility with older semconv
32
+ const ATTR_DB_CONNECTION_STRING = 'db.connection_string';
33
+ const ATTR_DB_STATEMENT = 'db.statement';
34
+ const ATTR_DB_SYSTEM = 'db.system';
35
+ const ATTR_NET_PEER_NAME = 'net.peer.name';
36
+ const ATTR_NET_PEER_PORT = 'net.peer.port';
37
+ const DB_SYSTEM_NAME_VALUE_REDIS = 'redis';
38
+ const DB_SYSTEM_VALUE_REDIS = 'redis';
39
+
40
+ exports.ATTR_DB_CONNECTION_STRING = ATTR_DB_CONNECTION_STRING;
41
+ exports.ATTR_DB_STATEMENT = ATTR_DB_STATEMENT;
42
+ exports.ATTR_DB_SYSTEM = ATTR_DB_SYSTEM;
43
+ exports.ATTR_NET_PEER_NAME = ATTR_NET_PEER_NAME;
44
+ exports.ATTR_NET_PEER_PORT = ATTR_NET_PEER_PORT;
45
+ exports.DB_SYSTEM_NAME_VALUE_REDIS = DB_SYSTEM_NAME_VALUE_REDIS;
46
+ exports.DB_SYSTEM_VALUE_REDIS = DB_SYSTEM_VALUE_REDIS;
47
+ //# sourceMappingURL=semconv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semconv.js","sources":["../../../../../../src/integrations/tracing/redis/vendored/semconv.ts"],"sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * NOTICE from the Sentry authors:\n * - Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/instrumentation-redis-v0.62.0/packages/instrumentation-redis\n * - Upstream version: @opentelemetry/instrumentation-redis@0.62.0\n * - Minor TypeScript adjustments for this repository's compiler settings\n */\n/* eslint-disable -- vendored @opentelemetry/instrumentation-redis */\n\n/*\n * This file contains a copy of unstable semantic convention definitions\n * used by the vendored redis/ioredis instrumentations.\n * @see https://github.com/open-telemetry/opentelemetry-js/tree/main/semantic-conventions#unstable-semconv\n */\n\n// Deprecated constants kept for backwards compatibility with older semconv\nexport const ATTR_DB_CONNECTION_STRING = 'db.connection_string';\nexport const ATTR_DB_STATEMENT = 'db.statement';\nexport const ATTR_DB_SYSTEM = 'db.system';\nexport const ATTR_NET_PEER_NAME = 'net.peer.name';\nexport const ATTR_NET_PEER_PORT = 'net.peer.port';\nexport const DB_SYSTEM_NAME_VALUE_REDIS = 'redis';\nexport const DB_SYSTEM_VALUE_REDIS = 'redis';\n"],"names":[],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACO,MAAM,yBAAA,GAA4B;AAClC,MAAM,iBAAA,GAAoB;AAC1B,MAAM,cAAA,GAAiB;AACvB,MAAM,kBAAA,GAAqB;AAC3B,MAAM,kBAAA,GAAqB;AAC3B,MAAM,0BAAA,GAA6B;AACnC,MAAM,qBAAA,GAAwB;;;;;;;;;;"}
@@ -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);\n } else {\n result.push(el);\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":["export type IORedisCommandArgs = Array<string | Buffer | number | unknown[]>;\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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"}
@@ -10,7 +10,7 @@ export { mongoIntegration } from './integrations/tracing/mongo.js';
10
10
  export { mongooseIntegration } from './integrations/tracing/mongoose.js';
11
11
  export { mysqlIntegration } from './integrations/tracing/mysql.js';
12
12
  export { mysql2Integration } from './integrations/tracing/mysql2.js';
13
- export { redisIntegration } from './integrations/tracing/redis.js';
13
+ export { redisIntegration } from './integrations/tracing/redis/index.js';
14
14
  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';
@@ -1,18 +1,10 @@
1
- import { diag } from '@opentelemetry/api';
2
- import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
3
- import { defineIntegration, getClient, hasSpansEnabled, stripDataUrlContent, SEMANTIC_ATTRIBUTE_URL_FULL } from '@sentry/core';
4
- import { NODE_VERSION, generateInstrumentOnce, SentryHttpInstrumentation, httpServerIntegration, httpServerSpansIntegration, getRequestUrl, addOriginToSpan } from '@sentry/node-core';
1
+ import { defineIntegration, hasSpansEnabled, getRequestUrlFromClientRequest, stripDataUrlContent, SEMANTIC_ATTRIBUTE_URL_FULL } from '@sentry/core';
2
+ import { generateInstrumentOnce, SentryHttpInstrumentation, httpServerIntegration, httpServerSpansIntegration } from '@sentry/node-core';
5
3
 
6
4
  const INTEGRATION_NAME = 'Http';
7
5
 
8
- const INSTRUMENTATION_NAME = '@opentelemetry_sentry-patched/instrumentation-http';
9
-
10
- // The `http.client.request.created` diagnostics channel, needed for trace propagation,
11
- // was added in Node 22.12.0 (backported from 23.2.0). Earlier 22.x versions don't have it.
12
- const FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL =
13
- (NODE_VERSION.major === 22 && NODE_VERSION.minor >= 12) ||
14
- (NODE_VERSION.major === 23 && NODE_VERSION.minor >= 2) ||
15
- NODE_VERSION.major >= 24;
6
+ // TODO(v11): Consolidate all the various HTTP integration options into one,
7
+ // and deprecate the duplicated and aliased options.
16
8
 
17
9
  const instrumentSentryHttp = generateInstrumentOnce(
18
10
  `${INTEGRATION_NAME}.sentry`,
@@ -21,65 +13,6 @@ const instrumentSentryHttp = generateInstrumentOnce(
21
13
  },
22
14
  );
23
15
 
24
- const instrumentOtelHttp = generateInstrumentOnce(INTEGRATION_NAME, config => {
25
- const instrumentation = new HttpInstrumentation({
26
- ...config,
27
- // This is hard-coded and can never be overridden by the user
28
- disableIncomingRequestInstrumentation: true,
29
- });
30
-
31
- // We want to update the logger namespace so we can better identify what is happening here
32
- try {
33
- instrumentation['_diag'] = diag.createComponentLogger({
34
- namespace: INSTRUMENTATION_NAME,
35
- });
36
- // @ts-expect-error We are writing a read-only property here...
37
- instrumentation.instrumentationName = INSTRUMENTATION_NAME;
38
- } catch {
39
- // ignore errors here...
40
- }
41
-
42
- // The OTel HttpInstrumentation (>=0.213.0) has a guard (`_httpPatched`/`_httpsPatched`)
43
- // that prevents patching `http`/`https` when loaded by both CJS `require()` and ESM `import`.
44
- // In environments like AWS Lambda, the runtime loads `http` via CJS first (for the Runtime API),
45
- // and then the user's ESM handler imports `node:http`. The guard blocks ESM patching after CJS,
46
- // which breaks HTTP spans for ESM handlers. We disable this guard to allow both to be patched.
47
- // TODO(andrei): Remove once https://github.com/open-telemetry/opentelemetry-js/issues/6489 is fixed.
48
- try {
49
- const noopDescriptor = { get: () => false, set: () => {} };
50
- Object.defineProperty(instrumentation, '_httpPatched', noopDescriptor);
51
- Object.defineProperty(instrumentation, '_httpsPatched', noopDescriptor);
52
- } catch {
53
- // ignore errors here...
54
- }
55
-
56
- return instrumentation;
57
- });
58
-
59
- /** Exported only for tests. */
60
- function _shouldUseOtelHttpInstrumentation(
61
- options,
62
- clientOptions = {},
63
- ) {
64
- // If `spans` is passed in, it takes precedence
65
- // Else, we by default emit spans, unless `skipOpenTelemetrySetup` is set to `true` or spans are not enabled
66
- if (typeof options.spans === 'boolean') {
67
- return options.spans;
68
- }
69
-
70
- if (clientOptions.skipOpenTelemetrySetup) {
71
- return false;
72
- }
73
-
74
- // IMPORTANT: We only disable span instrumentation when spans are not enabled _and_ we are on a Node version
75
- // that fully supports the necessary diagnostics channels for trace propagation
76
- if (!hasSpansEnabled(clientOptions) && FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL) {
77
- return false;
78
- }
79
-
80
- return true;
81
- }
82
-
83
16
  /**
84
17
  * The http integration instruments Node's internal http and https modules.
85
18
  * It creates breadcrumbs and spans for outgoing HTTP requests which will be attached to the currently active span.
@@ -87,6 +20,7 @@ function _shouldUseOtelHttpInstrumentation(
87
20
  const httpIntegration = defineIntegration((options = {}) => {
88
21
  const spans = options.spans ?? true;
89
22
  const disableIncomingRequestSpans = options.disableIncomingRequestSpans;
23
+ const enableServerSpans = spans && !disableIncomingRequestSpans;
90
24
 
91
25
  const serverOptions = {
92
26
  sessions: options.trackIncomingRequestsAsSessions,
@@ -101,13 +35,11 @@ const httpIntegration = defineIntegration((options = {}) => {
101
35
  ignoreStatusCodes: options.dropSpansForIncomingRequestStatusCodes,
102
36
  instrumentation: options.instrumentation,
103
37
  onSpanCreated: options.incomingRequestSpanHook,
104
- } ;
38
+ };
105
39
 
106
40
  const server = httpServerIntegration(serverOptions);
107
41
  const serverSpans = httpServerSpansIntegration(serverSpansOptions);
108
42
 
109
- const enableServerSpans = spans && !disableIncomingRequestSpans;
110
-
111
43
  return {
112
44
  name: INTEGRATION_NAME,
113
45
  setup(client) {
@@ -118,102 +50,45 @@ const httpIntegration = defineIntegration((options = {}) => {
118
50
  }
119
51
  },
120
52
  setupOnce() {
121
- const clientOptions = (getClient()?.getOptions() || {}) ;
122
- const useOtelHttpInstrumentation = _shouldUseOtelHttpInstrumentation(options, clientOptions);
123
-
124
53
  server.setupOnce();
125
54
 
126
55
  const sentryHttpInstrumentationOptions = {
127
56
  breadcrumbs: options.breadcrumbs,
128
- propagateTraceInOutgoingRequests:
129
- typeof options.tracePropagation === 'boolean'
130
- ? options.tracePropagation
131
- : FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL || !useOtelHttpInstrumentation,
132
- createSpansForOutgoingRequests: FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL,
133
- spans: options.spans,
57
+ spans,
58
+ propagateTraceInOutgoingRequests: options.tracePropagation ?? true,
59
+ createSpansForOutgoingRequests: spans,
134
60
  ignoreOutgoingRequests: options.ignoreOutgoingRequests,
135
61
  outgoingRequestHook: (span, request) => {
136
62
  // Sanitize data URLs to prevent long base64 strings in span attributes
137
- const url = getRequestUrl(request);
63
+ const url = getRequestUrlFromClientRequest(request);
138
64
  if (url.startsWith('data:')) {
139
65
  const sanitizedUrl = stripDataUrlContent(url);
66
+ // TODO(v11): Update these to the Sentry semantic attributes.
67
+ // https://getsentry.github.io/sentry-conventions/attributes/
140
68
  span.setAttribute('http.url', sanitizedUrl);
141
69
  span.setAttribute(SEMANTIC_ATTRIBUTE_URL_FULL, sanitizedUrl);
142
70
  span.updateName(`${request.method || 'GET'} ${sanitizedUrl}`);
143
71
  }
144
-
145
72
  options.instrumentation?.requestHook?.(span, request);
146
73
  },
147
74
  outgoingResponseHook: options.instrumentation?.responseHook,
148
75
  outgoingRequestApplyCustomAttributes: options.instrumentation?.applyCustomAttributesOnSpan,
149
- } ;
76
+ };
150
77
 
151
- // This is Sentry-specific instrumentation for outgoing request breadcrumbs & trace propagation
78
+ // This is Sentry-specific instrumentation for outgoing request
79
+ // breadcrumbs & trace propagation. It uses the diagnostic channels on
80
+ // node versions that support it, falling back to monkey-patching when
81
+ // needed.
152
82
  instrumentSentryHttp(sentryHttpInstrumentationOptions);
153
-
154
- // This is the "regular" OTEL instrumentation that emits outgoing request spans
155
- if (useOtelHttpInstrumentation) {
156
- const instrumentationConfig = getConfigWithDefaults(options);
157
- instrumentOtelHttp(instrumentationConfig);
158
- }
159
83
  },
160
84
  processEvent(event) {
161
- // Note: We always run this, even if spans are disabled
162
- // The reason being that e.g. the remix integration disables span creation here but still wants to use the ignore status codes option
85
+ // Always run this, even if spans are disabled
86
+ // The reason being that e.g. the remix integration disables span
87
+ // creation here but still wants to use the ignore status codes option
163
88
  return serverSpans.processEvent(event);
164
89
  },
165
90
  };
166
91
  });
167
92
 
168
- function getConfigWithDefaults(options = {}) {
169
- const instrumentationConfig = {
170
- // This is handled by the SentryHttpInstrumentation on Node 22+
171
- disableOutgoingRequestInstrumentation: FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL,
172
-
173
- ignoreOutgoingRequestHook: request => {
174
- const url = getRequestUrl(request);
175
-
176
- if (!url) {
177
- return false;
178
- }
179
-
180
- const _ignoreOutgoingRequests = options.ignoreOutgoingRequests;
181
- if (_ignoreOutgoingRequests?.(url, request)) {
182
- return true;
183
- }
184
-
185
- return false;
186
- },
187
-
188
- requireParentforOutgoingSpans: false,
189
- requestHook: (span, req) => {
190
- addOriginToSpan(span, 'auto.http.otel.http');
191
-
192
- // Sanitize data URLs to prevent long base64 strings in span attributes
193
- const url = getRequestUrl(req );
194
- if (url.startsWith('data:')) {
195
- const sanitizedUrl = stripDataUrlContent(url);
196
- span.setAttribute('http.url', sanitizedUrl);
197
- span.setAttribute(SEMANTIC_ATTRIBUTE_URL_FULL, sanitizedUrl);
198
- span.updateName(`${(req ).method || 'GET'} ${sanitizedUrl}`);
199
- }
200
-
201
- options.instrumentation?.requestHook?.(span, req);
202
- },
203
- responseHook: (span, res) => {
204
- options.instrumentation?.responseHook?.(span, res);
205
- },
206
- applyCustomAttributesOnSpan: (
207
- span,
208
- request,
209
- response,
210
- ) => {
211
- options.instrumentation?.applyCustomAttributesOnSpan?.(span, request, response);
212
- },
213
- } ;
214
-
215
- return instrumentationConfig;
216
- }
217
-
218
- export { _shouldUseOtelHttpInstrumentation, httpIntegration, instrumentOtelHttp, instrumentSentryHttp };
93
+ export { httpIntegration, instrumentSentryHttp };
219
94
  //# sourceMappingURL=http.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sources":["../../../src/integrations/http.ts"],"sourcesContent":["import type { ClientRequest, IncomingMessage, RequestOptions, ServerResponse } from 'node:http';\nimport { diag } from '@opentelemetry/api';\nimport type { HttpInstrumentationConfig } from '@opentelemetry/instrumentation-http';\nimport { HttpInstrumentation } from '@opentelemetry/instrumentation-http';\nimport type { Span } from '@sentry/core';\nimport {\n defineIntegration,\n getClient,\n hasSpansEnabled,\n SEMANTIC_ATTRIBUTE_URL_FULL,\n stripDataUrlContent,\n} from '@sentry/core';\nimport type { HTTPModuleRequestIncomingMessage, NodeClient, SentryHttpInstrumentationOptions } from '@sentry/node-core';\nimport {\n addOriginToSpan,\n generateInstrumentOnce,\n getRequestUrl,\n httpServerIntegration,\n httpServerSpansIntegration,\n NODE_VERSION,\n SentryHttpInstrumentation,\n} from '@sentry/node-core';\nimport type { NodeClientOptions } from '../types';\n\nconst INTEGRATION_NAME = 'Http';\n\nconst INSTRUMENTATION_NAME = '@opentelemetry_sentry-patched/instrumentation-http';\n\n// The `http.client.request.created` diagnostics channel, needed for trace propagation,\n// was added in Node 22.12.0 (backported from 23.2.0). Earlier 22.x versions don't have it.\nconst FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL =\n (NODE_VERSION.major === 22 && NODE_VERSION.minor >= 12) ||\n (NODE_VERSION.major === 23 && NODE_VERSION.minor >= 2) ||\n NODE_VERSION.major >= 24;\n\ninterface HttpOptions {\n /**\n * Whether breadcrumbs should be recorded for outgoing requests.\n * Defaults to true\n */\n breadcrumbs?: boolean;\n\n /**\n * If set to false, do not emit any spans.\n * This will ensure that the default HttpInstrumentation from OpenTelemetry is not setup,\n * only the Sentry-specific instrumentation for request isolation is applied.\n *\n * If `skipOpenTelemetrySetup: true` is configured, this defaults to `false`, otherwise it defaults to `true`.\n */\n spans?: boolean;\n\n /**\n * Whether the integration should create [Sessions](https://docs.sentry.io/product/releases/health/#sessions) for incoming requests to track the health and crash-free rate of your releases in Sentry.\n * Read more about Release Health: https://docs.sentry.io/product/releases/health/\n *\n * Defaults to `true`.\n */\n trackIncomingRequestsAsSessions?: boolean;\n\n /**\n * Number of milliseconds until sessions tracked with `trackIncomingRequestsAsSessions` will be flushed as a session aggregate.\n *\n * Defaults to `60000` (60s).\n */\n sessionFlushingDelayMS?: number;\n\n /**\n * Whether to inject trace propagation headers (sentry-trace, baggage, traceparent) into outgoing HTTP requests.\n *\n * When set to `false`, Sentry will not inject any trace propagation headers, but will still create breadcrumbs\n * (if `breadcrumbs` is enabled). This is useful when `skipOpenTelemetrySetup: true` is configured and you want\n * to avoid duplicate trace headers being injected by both Sentry and OpenTelemetry's HttpInstrumentation.\n *\n * @default `true`\n */\n tracePropagation?: boolean;\n\n /**\n * Do not capture spans or breadcrumbs for outgoing HTTP requests to URLs where the given callback returns `true`.\n * This controls both span & breadcrumb creation - spans will be non recording if tracing is disabled.\n *\n * The `url` param contains the entire URL, including query string (if any), protocol, host, etc. of the outgoing request.\n * For example: `'https://someService.com/users/details?id=123'`\n *\n * The `request` param contains the original {@type RequestOptions} object used to make the outgoing request.\n * You can use it to filter on additional properties like method, headers, etc.\n */\n ignoreOutgoingRequests?: (url: string, request: RequestOptions) => boolean;\n\n /**\n * Do not capture spans for incoming HTTP requests to URLs where the given callback returns `true`.\n * Spans will be non recording if tracing is disabled.\n *\n * The `urlPath` param consists of the URL path and query string (if any) of the incoming request.\n * For example: `'/users/details?id=123'`\n *\n * The `request` param contains the original {@type IncomingMessage} object of the incoming request.\n * You can use it to filter on additional properties like method, headers, etc.\n */\n ignoreIncomingRequests?: (urlPath: string, request: IncomingMessage) => boolean;\n\n /**\n * A hook that can be used to mutate the span for incoming requests.\n * This is triggered after the span is created, but before it is recorded.\n */\n incomingRequestSpanHook?: (span: Span, request: IncomingMessage, response: ServerResponse) => void;\n\n /**\n * Whether to automatically ignore common static asset requests like favicon.ico, robots.txt, etc.\n * This helps reduce noise in your transactions.\n *\n * @default `true`\n */\n ignoreStaticAssets?: boolean;\n\n /**\n * Do not capture spans for incoming HTTP requests with the given status codes.\n * By default, spans with some 3xx and 4xx status codes are ignored (see @default).\n * Expects an array of status codes or a range of status codes, e.g. [[300,399], 404] would ignore 3xx and 404 status codes.\n *\n * @default `[[401, 404], [301, 303], [305, 399]]`\n */\n dropSpansForIncomingRequestStatusCodes?: (number | [number, number])[];\n\n /**\n * Do not capture the request body for incoming HTTP requests to URLs where the given callback returns `true`.\n * This can be useful for long running requests where the body is not needed and we want to avoid capturing it.\n *\n * @param url Contains the entire URL, including query string (if any), protocol, host, etc. of the incoming request.\n * @param request Contains the {@type RequestOptions} object used to make the incoming request.\n */\n ignoreIncomingRequestBody?: (url: string, request: RequestOptions) => boolean;\n\n /**\n * Controls the maximum size of incoming HTTP request bodies attached to events.\n *\n * Available options:\n * - 'none': No request bodies will be attached\n * - 'small': Request bodies up to 1,000 bytes will be attached\n * - 'medium': Request bodies up to 10,000 bytes will be attached (default)\n * - 'always': Request bodies will always be attached\n *\n * Note that even with 'always' setting, bodies exceeding 1MB will never be attached\n * for performance and security reasons.\n *\n * @default 'medium'\n */\n maxIncomingRequestBodySize?: 'none' | 'small' | 'medium' | 'always';\n\n /**\n * If true, do not generate spans for incoming requests at all.\n * This is used by Remix to avoid generating spans for incoming requests, as it generates its own spans.\n */\n disableIncomingRequestSpans?: boolean;\n\n /**\n * Additional instrumentation options that are passed to the underlying HttpInstrumentation.\n */\n instrumentation?: {\n requestHook?: (span: Span, req: ClientRequest | HTTPModuleRequestIncomingMessage) => void;\n responseHook?: (span: Span, response: HTTPModuleRequestIncomingMessage | ServerResponse) => void;\n applyCustomAttributesOnSpan?: (\n span: Span,\n request: ClientRequest | HTTPModuleRequestIncomingMessage,\n response: HTTPModuleRequestIncomingMessage | ServerResponse,\n ) => void;\n };\n}\n\nexport const instrumentSentryHttp = generateInstrumentOnce<SentryHttpInstrumentationOptions>(\n `${INTEGRATION_NAME}.sentry`,\n options => {\n return new SentryHttpInstrumentation(options);\n },\n);\n\nexport const instrumentOtelHttp = generateInstrumentOnce<HttpInstrumentationConfig>(INTEGRATION_NAME, config => {\n const instrumentation = new HttpInstrumentation({\n ...config,\n // This is hard-coded and can never be overridden by the user\n disableIncomingRequestInstrumentation: true,\n });\n\n // We want to update the logger namespace so we can better identify what is happening here\n try {\n instrumentation['_diag'] = diag.createComponentLogger({\n namespace: INSTRUMENTATION_NAME,\n });\n // @ts-expect-error We are writing a read-only property here...\n instrumentation.instrumentationName = INSTRUMENTATION_NAME;\n } catch {\n // ignore errors here...\n }\n\n // The OTel HttpInstrumentation (>=0.213.0) has a guard (`_httpPatched`/`_httpsPatched`)\n // that prevents patching `http`/`https` when loaded by both CJS `require()` and ESM `import`.\n // In environments like AWS Lambda, the runtime loads `http` via CJS first (for the Runtime API),\n // and then the user's ESM handler imports `node:http`. The guard blocks ESM patching after CJS,\n // which breaks HTTP spans for ESM handlers. We disable this guard to allow both to be patched.\n // TODO(andrei): Remove once https://github.com/open-telemetry/opentelemetry-js/issues/6489 is fixed.\n try {\n const noopDescriptor = { get: () => false, set: () => {} };\n Object.defineProperty(instrumentation, '_httpPatched', noopDescriptor);\n Object.defineProperty(instrumentation, '_httpsPatched', noopDescriptor);\n } catch {\n // ignore errors here...\n }\n\n return instrumentation;\n});\n\n/** Exported only for tests. */\nexport function _shouldUseOtelHttpInstrumentation(\n options: HttpOptions,\n clientOptions: Partial<NodeClientOptions> = {},\n): boolean {\n // If `spans` is passed in, it takes precedence\n // Else, we by default emit spans, unless `skipOpenTelemetrySetup` is set to `true` or spans are not enabled\n if (typeof options.spans === 'boolean') {\n return options.spans;\n }\n\n if (clientOptions.skipOpenTelemetrySetup) {\n return false;\n }\n\n // IMPORTANT: We only disable span instrumentation when spans are not enabled _and_ we are on a Node version\n // that fully supports the necessary diagnostics channels for trace propagation\n if (!hasSpansEnabled(clientOptions) && FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL) {\n return false;\n }\n\n return true;\n}\n\n/**\n * The http integration instruments Node's internal http and https modules.\n * It creates breadcrumbs and spans for outgoing HTTP requests which will be attached to the currently active span.\n */\nexport const httpIntegration = defineIntegration((options: HttpOptions = {}) => {\n const spans = options.spans ?? true;\n const disableIncomingRequestSpans = options.disableIncomingRequestSpans;\n\n const serverOptions = {\n sessions: options.trackIncomingRequestsAsSessions,\n sessionFlushingDelayMS: options.sessionFlushingDelayMS,\n ignoreRequestBody: options.ignoreIncomingRequestBody,\n maxRequestBodySize: options.maxIncomingRequestBodySize,\n } satisfies Parameters<typeof httpServerIntegration>[0];\n\n const serverSpansOptions = {\n ignoreIncomingRequests: options.ignoreIncomingRequests,\n ignoreStaticAssets: options.ignoreStaticAssets,\n ignoreStatusCodes: options.dropSpansForIncomingRequestStatusCodes,\n instrumentation: options.instrumentation,\n onSpanCreated: options.incomingRequestSpanHook,\n } satisfies Parameters<typeof httpServerSpansIntegration>[0];\n\n const server = httpServerIntegration(serverOptions);\n const serverSpans = httpServerSpansIntegration(serverSpansOptions);\n\n const enableServerSpans = spans && !disableIncomingRequestSpans;\n\n return {\n name: INTEGRATION_NAME,\n setup(client: NodeClient) {\n const clientOptions = client.getOptions();\n\n if (enableServerSpans && hasSpansEnabled(clientOptions)) {\n serverSpans.setup(client);\n }\n },\n setupOnce() {\n const clientOptions = (getClient<NodeClient>()?.getOptions() || {}) satisfies Partial<NodeClientOptions>;\n const useOtelHttpInstrumentation = _shouldUseOtelHttpInstrumentation(options, clientOptions);\n\n server.setupOnce();\n\n const sentryHttpInstrumentationOptions = {\n breadcrumbs: options.breadcrumbs,\n propagateTraceInOutgoingRequests:\n typeof options.tracePropagation === 'boolean'\n ? options.tracePropagation\n : FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL || !useOtelHttpInstrumentation,\n createSpansForOutgoingRequests: FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL,\n spans: options.spans,\n ignoreOutgoingRequests: options.ignoreOutgoingRequests,\n outgoingRequestHook: (span: Span, request: ClientRequest) => {\n // Sanitize data URLs to prevent long base64 strings in span attributes\n const url = getRequestUrl(request);\n if (url.startsWith('data:')) {\n const sanitizedUrl = stripDataUrlContent(url);\n span.setAttribute('http.url', sanitizedUrl);\n span.setAttribute(SEMANTIC_ATTRIBUTE_URL_FULL, sanitizedUrl);\n span.updateName(`${request.method || 'GET'} ${sanitizedUrl}`);\n }\n\n options.instrumentation?.requestHook?.(span, request);\n },\n outgoingResponseHook: options.instrumentation?.responseHook,\n outgoingRequestApplyCustomAttributes: options.instrumentation?.applyCustomAttributesOnSpan,\n } satisfies SentryHttpInstrumentationOptions;\n\n // This is Sentry-specific instrumentation for outgoing request breadcrumbs & trace propagation\n instrumentSentryHttp(sentryHttpInstrumentationOptions);\n\n // This is the \"regular\" OTEL instrumentation that emits outgoing request spans\n if (useOtelHttpInstrumentation) {\n const instrumentationConfig = getConfigWithDefaults(options);\n instrumentOtelHttp(instrumentationConfig);\n }\n },\n processEvent(event) {\n // Note: We always run this, even if spans are disabled\n // The reason being that e.g. the remix integration disables span creation here but still wants to use the ignore status codes option\n return serverSpans.processEvent(event);\n },\n };\n});\n\nfunction getConfigWithDefaults(options: Partial<HttpOptions> = {}): HttpInstrumentationConfig {\n const instrumentationConfig = {\n // This is handled by the SentryHttpInstrumentation on Node 22+\n disableOutgoingRequestInstrumentation: FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL,\n\n ignoreOutgoingRequestHook: request => {\n const url = getRequestUrl(request);\n\n if (!url) {\n return false;\n }\n\n const _ignoreOutgoingRequests = options.ignoreOutgoingRequests;\n if (_ignoreOutgoingRequests?.(url, request)) {\n return true;\n }\n\n return false;\n },\n\n requireParentforOutgoingSpans: false,\n requestHook: (span, req) => {\n addOriginToSpan(span, 'auto.http.otel.http');\n\n // Sanitize data URLs to prevent long base64 strings in span attributes\n const url = getRequestUrl(req as ClientRequest);\n if (url.startsWith('data:')) {\n const sanitizedUrl = stripDataUrlContent(url);\n span.setAttribute('http.url', sanitizedUrl);\n span.setAttribute(SEMANTIC_ATTRIBUTE_URL_FULL, sanitizedUrl);\n span.updateName(`${(req as ClientRequest).method || 'GET'} ${sanitizedUrl}`);\n }\n\n options.instrumentation?.requestHook?.(span, req);\n },\n responseHook: (span, res) => {\n options.instrumentation?.responseHook?.(span, res);\n },\n applyCustomAttributesOnSpan: (\n span: Span,\n request: ClientRequest | HTTPModuleRequestIncomingMessage,\n response: HTTPModuleRequestIncomingMessage | ServerResponse,\n ) => {\n options.instrumentation?.applyCustomAttributesOnSpan?.(span, request, response);\n },\n } satisfies HttpInstrumentationConfig;\n\n return instrumentationConfig;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"http.js","sources":["../../../src/integrations/http.ts"],"sourcesContent":["import type { RequestOptions } from 'node:http';\nimport type { HttpClientRequest, HttpIncomingMessage, HttpServerResponse, Span } from '@sentry/core';\nimport {\n defineIntegration,\n hasSpansEnabled,\n SEMANTIC_ATTRIBUTE_URL_FULL,\n stripDataUrlContent,\n getRequestUrlFromClientRequest,\n} from '@sentry/core';\nimport type {\n NodeClient,\n SentryHttpInstrumentationOptions,\n HttpServerIntegrationOptions,\n HttpServerSpansIntegrationOptions,\n} from '@sentry/node-core';\nimport {\n generateInstrumentOnce,\n httpServerIntegration,\n httpServerSpansIntegration,\n SentryHttpInstrumentation,\n} from '@sentry/node-core';\n\nconst INTEGRATION_NAME = 'Http';\n\n// TODO(v11): Consolidate all the various HTTP integration options into one,\n// and deprecate the duplicated and aliased options.\ninterface HttpOptions {\n /**\n * Whether breadcrumbs should be recorded for outgoing requests.\n * Defaults to true\n */\n breadcrumbs?: boolean;\n\n /**\n * If set to false, do not emit any spans.\n * This will ensure that the default HttpInstrumentation from OpenTelemetry is not setup,\n * only the Sentry-specific instrumentation for request isolation is applied.\n *\n * If `skipOpenTelemetrySetup: true` is configured, this defaults to `false`, otherwise it defaults to `true`.\n */\n spans?: boolean;\n\n /**\n * Whether the integration should create [Sessions](https://docs.sentry.io/product/releases/health/#sessions) for incoming requests to track the health and crash-free rate of your releases in Sentry.\n * Read more about Release Health: https://docs.sentry.io/product/releases/health/\n *\n * Defaults to `true`.\n */\n trackIncomingRequestsAsSessions?: boolean;\n\n /**\n * Number of milliseconds until sessions tracked with `trackIncomingRequestsAsSessions` will be flushed as a session aggregate.\n *\n * Defaults to `60000` (60s).\n */\n sessionFlushingDelayMS?: number;\n\n /**\n * Whether to inject trace propagation headers (sentry-trace, baggage, traceparent) into outgoing HTTP requests.\n *\n * When set to `false`, Sentry will not inject any trace propagation headers, but will still create breadcrumbs\n * (if `breadcrumbs` is enabled). This is useful when `skipOpenTelemetrySetup: true` is configured and you want\n * to avoid duplicate trace headers being injected by both Sentry and OpenTelemetry's HttpInstrumentation.\n *\n * @default `true`\n */\n tracePropagation?: boolean;\n\n /**\n * Do not capture spans or breadcrumbs for outgoing HTTP requests to URLs where the given callback returns `true`.\n * This controls both span & breadcrumb creation - spans will be non recording if tracing is disabled.\n *\n * The `url` param contains the entire URL, including query string (if any), protocol, host, etc. of the outgoing request.\n * For example: `'https://someService.com/users/details?id=123'`\n *\n * The `request` param contains the original {@type RequestOptions} object used to make the outgoing request.\n * You can use it to filter on additional properties like method, headers, etc.\n */\n ignoreOutgoingRequests?: (url: string, request: RequestOptions) => boolean;\n\n /**\n * Do not capture spans for incoming HTTP requests to URLs where the given callback returns `true`.\n * Spans will be non recording if tracing is disabled.\n *\n * The `urlPath` param consists of the URL path and query string (if any) of the incoming request.\n * For example: `'/users/details?id=123'`\n *\n * The `request` param contains the original {@type IncomingMessage} object of the incoming request.\n * You can use it to filter on additional properties like method, headers, etc.\n */\n ignoreIncomingRequests?: (urlPath: string, request: HttpIncomingMessage) => boolean;\n\n /**\n * A hook that can be used to mutate the span for incoming requests.\n * This is triggered after the span is created, but before it is recorded.\n */\n incomingRequestSpanHook?: (span: Span, request: HttpIncomingMessage, response: HttpServerResponse) => void;\n\n /**\n * Whether to automatically ignore common static asset requests like favicon.ico, robots.txt, etc.\n * This helps reduce noise in your transactions.\n *\n * @default `true`\n */\n ignoreStaticAssets?: boolean;\n\n /**\n * Do not capture spans for incoming HTTP requests with the given status codes.\n * By default, spans with some 3xx and 4xx status codes are ignored (see @default).\n * Expects an array of status codes or a range of status codes, e.g. [[300,399], 404] would ignore 3xx and 404 status codes.\n *\n * @default `[[401, 404], [301, 303], [305, 399]]`\n */\n dropSpansForIncomingRequestStatusCodes?: (number | [number, number])[];\n\n /**\n * Do not capture the request body for incoming HTTP requests to URLs where the given callback returns `true`.\n * This can be useful for long running requests where the body is not needed and we want to avoid capturing it.\n *\n * @param url Contains the entire URL, including query string (if any), protocol, host, etc. of the incoming request.\n * @param request Contains the {@type RequestOptions} object used to make the incoming request.\n */\n ignoreIncomingRequestBody?: (url: string, request: RequestOptions) => boolean;\n\n /**\n * Controls the maximum size of incoming HTTP request bodies attached to events.\n *\n * Available options:\n * - 'none': No request bodies will be attached\n * - 'small': Request bodies up to 1,000 bytes will be attached\n * - 'medium': Request bodies up to 10,000 bytes will be attached (default)\n * - 'always': Request bodies will always be attached\n *\n * Note that even with 'always' setting, bodies exceeding 1MB will never be attached\n * for performance and security reasons.\n *\n * @default 'medium'\n */\n maxIncomingRequestBodySize?: 'none' | 'small' | 'medium' | 'always';\n\n /**\n * If true, do not generate spans for incoming requests at all.\n * This is used by Remix to avoid generating spans for incoming requests, as it generates its own spans.\n */\n disableIncomingRequestSpans?: boolean;\n\n /**\n * Additional instrumentation options that are passed to the underlying HttpInstrumentation.\n */\n instrumentation?: {\n requestHook?: (span: Span, req: HttpIncomingMessage | HttpClientRequest) => void;\n responseHook?: (span: Span, response: HttpIncomingMessage | HttpServerResponse) => void;\n applyCustomAttributesOnSpan?: (\n span: Span,\n request: HttpIncomingMessage | HttpClientRequest,\n response: HttpIncomingMessage | HttpServerResponse,\n ) => void;\n };\n}\n\nexport const instrumentSentryHttp = generateInstrumentOnce<SentryHttpInstrumentationOptions>(\n `${INTEGRATION_NAME}.sentry`,\n options => {\n return new SentryHttpInstrumentation(options);\n },\n);\n\n/**\n * The http integration instruments Node's internal http and https modules.\n * It creates breadcrumbs and spans for outgoing HTTP requests which will be attached to the currently active span.\n */\nexport const httpIntegration = defineIntegration((options: HttpOptions = {}) => {\n const spans = options.spans ?? true;\n const disableIncomingRequestSpans = options.disableIncomingRequestSpans;\n const enableServerSpans = spans && !disableIncomingRequestSpans;\n\n const serverOptions = {\n sessions: options.trackIncomingRequestsAsSessions,\n sessionFlushingDelayMS: options.sessionFlushingDelayMS,\n ignoreRequestBody: options.ignoreIncomingRequestBody,\n maxRequestBodySize: options.maxIncomingRequestBodySize,\n } satisfies HttpServerIntegrationOptions;\n\n const serverSpansOptions: HttpServerSpansIntegrationOptions = {\n ignoreIncomingRequests: options.ignoreIncomingRequests,\n ignoreStaticAssets: options.ignoreStaticAssets,\n ignoreStatusCodes: options.dropSpansForIncomingRequestStatusCodes,\n instrumentation: options.instrumentation,\n onSpanCreated: options.incomingRequestSpanHook,\n };\n\n const server = httpServerIntegration(serverOptions);\n const serverSpans = httpServerSpansIntegration(serverSpansOptions);\n\n return {\n name: INTEGRATION_NAME,\n setup(client: NodeClient) {\n const clientOptions = client.getOptions();\n\n if (enableServerSpans && hasSpansEnabled(clientOptions)) {\n serverSpans.setup(client);\n }\n },\n setupOnce() {\n server.setupOnce();\n\n const sentryHttpInstrumentationOptions: SentryHttpInstrumentationOptions = {\n breadcrumbs: options.breadcrumbs,\n spans,\n propagateTraceInOutgoingRequests: options.tracePropagation ?? true,\n createSpansForOutgoingRequests: spans,\n ignoreOutgoingRequests: options.ignoreOutgoingRequests,\n outgoingRequestHook: (span: Span, request: HttpClientRequest) => {\n // Sanitize data URLs to prevent long base64 strings in span attributes\n const url = getRequestUrlFromClientRequest(request);\n if (url.startsWith('data:')) {\n const sanitizedUrl = stripDataUrlContent(url);\n // TODO(v11): Update these to the Sentry semantic attributes.\n // https://getsentry.github.io/sentry-conventions/attributes/\n span.setAttribute('http.url', sanitizedUrl);\n span.setAttribute(SEMANTIC_ATTRIBUTE_URL_FULL, sanitizedUrl);\n span.updateName(`${request.method || 'GET'} ${sanitizedUrl}`);\n }\n options.instrumentation?.requestHook?.(span, request);\n },\n outgoingResponseHook: options.instrumentation?.responseHook,\n outgoingRequestApplyCustomAttributes: options.instrumentation?.applyCustomAttributesOnSpan,\n };\n\n // This is Sentry-specific instrumentation for outgoing request\n // breadcrumbs & trace propagation. It uses the diagnostic channels on\n // node versions that support it, falling back to monkey-patching when\n // needed.\n instrumentSentryHttp(sentryHttpInstrumentationOptions);\n },\n processEvent(event) {\n // Always run this, even if spans are disabled\n // The reason being that e.g. the remix integration disables span\n // creation here but still wants to use the ignore status codes option\n return serverSpans.processEvent(event);\n },\n };\n});\n"],"names":[],"mappings":"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"}
@@ -26,8 +26,8 @@ class SentryAnthropicAiInstrumentation extends InstrumentationBase {
26
26
  /**
27
27
  * Core patch logic applying instrumentation to the Anthropic AI client constructor.
28
28
  */
29
- _patch(exports$1) {
30
- const Original = exports$1.Anthropic;
29
+ _patch(exports) {
30
+ const Original = exports.Anthropic;
31
31
 
32
32
  const config = this.getConfig();
33
33
 
@@ -58,10 +58,10 @@ class SentryAnthropicAiInstrumentation extends InstrumentationBase {
58
58
  // Constructor replacement - handle read-only properties
59
59
  // The Anthropic property might have only a getter, so use defineProperty
60
60
  try {
61
- exports$1.Anthropic = WrappedAnthropic;
61
+ exports.Anthropic = WrappedAnthropic;
62
62
  } catch {
63
63
  // If direct assignment fails, override the property descriptor
64
- Object.defineProperty(exports$1, 'Anthropic', {
64
+ Object.defineProperty(exports, 'Anthropic', {
65
65
  value: WrappedAnthropic,
66
66
  writable: true,
67
67
  configurable: true,
@@ -72,12 +72,12 @@ class SentryAnthropicAiInstrumentation extends InstrumentationBase {
72
72
  // Wrap the default export if it points to the original constructor
73
73
  // Constructor replacement - handle read-only properties
74
74
  // The Anthropic property might have only a getter, so use defineProperty
75
- if (exports$1.default === Original) {
75
+ if (exports.default === Original) {
76
76
  try {
77
- exports$1.default = WrappedAnthropic;
77
+ exports.default = WrappedAnthropic;
78
78
  } catch {
79
79
  // If direct assignment fails, override the property descriptor
80
- Object.defineProperty(exports$1, 'default', {
80
+ Object.defineProperty(exports, 'default', {
81
81
  value: WrappedAnthropic,
82
82
  writable: true,
83
83
  configurable: true,
@@ -85,7 +85,7 @@ class SentryAnthropicAiInstrumentation extends InstrumentationBase {
85
85
  });
86
86
  }
87
87
  }
88
- return exports$1;
88
+ return exports;
89
89
  }
90
90
  }
91
91
 
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/anthropic-ai/instrumentation.ts"],"sourcesContent":["import {\n InstrumentationBase,\n type InstrumentationConfig,\n type InstrumentationModuleDefinition,\n InstrumentationNodeModuleDefinition,\n} from '@opentelemetry/instrumentation';\nimport type { AnthropicAiClient, AnthropicAiOptions } from '@sentry/core';\nimport {\n _INTERNAL_shouldSkipAiProviderWrapping,\n ANTHROPIC_AI_INTEGRATION_NAME,\n instrumentAnthropicAiClient,\n SDK_VERSION,\n} from '@sentry/core';\n\nconst supportedVersions = ['>=0.19.2 <1.0.0'];\n\ntype AnthropicAiInstrumentationOptions = InstrumentationConfig & AnthropicAiOptions;\n\n/**\n * Represents the patched shape of the Anthropic AI module export.\n */\ninterface PatchedModuleExports {\n [key: string]: unknown;\n Anthropic: abstract new (...args: unknown[]) => AnthropicAiClient;\n}\n\n/**\n * Sentry Anthropic AI instrumentation using OpenTelemetry.\n */\nexport class SentryAnthropicAiInstrumentation extends InstrumentationBase<AnthropicAiInstrumentationOptions> {\n public constructor(config: AnthropicAiInstrumentationOptions = {}) {\n super('@sentry/instrumentation-anthropic-ai', 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 '@anthropic-ai/sdk',\n supportedVersions,\n this._patch.bind(this),\n );\n return module;\n }\n\n /**\n * Core patch logic applying instrumentation to the Anthropic AI client constructor.\n */\n private _patch(exports: PatchedModuleExports): PatchedModuleExports | void {\n const Original = exports.Anthropic;\n\n const config = this.getConfig();\n\n const WrappedAnthropic = function (this: unknown, ...args: unknown[]) {\n // Check if wrapping should be skipped (e.g., when LangChain is handling instrumentation)\n if (_INTERNAL_shouldSkipAiProviderWrapping(ANTHROPIC_AI_INTEGRATION_NAME)) {\n return Reflect.construct(Original, args) as AnthropicAiClient;\n }\n\n const instance = Reflect.construct(Original, args);\n\n return instrumentAnthropicAiClient(instance as AnthropicAiClient, config);\n } as unknown as abstract new (...args: unknown[]) => AnthropicAiClient;\n\n // Preserve static and prototype chains\n Object.setPrototypeOf(WrappedAnthropic, Original);\n Object.setPrototypeOf(WrappedAnthropic.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(WrappedAnthropic, key, descriptor);\n }\n }\n }\n\n // Constructor replacement - handle read-only properties\n // The Anthropic property might have only a getter, so use defineProperty\n try {\n exports.Anthropic = WrappedAnthropic;\n } catch {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, 'Anthropic', {\n value: WrappedAnthropic,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n\n // Wrap the default export if it points to the original constructor\n // Constructor replacement - handle read-only properties\n // The Anthropic property might have only a getter, so use defineProperty\n if (exports.default === Original) {\n try {\n exports.default = WrappedAnthropic;\n } catch {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, 'default', {\n value: WrappedAnthropic,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n }\n return exports;\n }\n}\n"],"names":["exports"],"mappings":";;;AAcA,MAAM,iBAAA,GAAoB,CAAC,iBAAiB,CAAC;;AAY7C;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,EAAE;;AAEF;AACA;AACA;AACA,GAAS,IAAI,GAAoC;AACjD,IAAI,MAAM,MAAA,GAAS,IAAI,mCAAmC;AAC1D,MAAM,mBAAmB;AACzB,MAAM,iBAAiB;AACvB,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AAC5B,KAAK;AACL,IAAI,OAAO,MAAM;AACjB,EAAE;;AAEF;AACA;AACA;AACA,GAAU,MAAM,CAACA,SAAO,EAAqD;AAC7E,IAAI,MAAM,QAAA,GAAWA,SAAO,CAAC,SAAS;;AAEtC,IAAI,MAAM,MAAA,GAAS,IAAI,CAAC,SAAS,EAAE;;AAEnC,IAAI,MAAM,mBAAmB,WAAyB,GAAG,IAAI,EAAa;AAC1E;AACA,MAAM,IAAI,sCAAsC,CAAC,6BAA6B,CAAC,EAAE;AACjF,QAAQ,OAAO,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAA;AAC/C,MAAM;;AAEN,MAAM,MAAM,QAAA,GAAW,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC;;AAExD,MAAM,OAAO,2BAA2B,CAAC,QAAA,GAA+B,MAAM,CAAC;AAC/E,IAAI,CAAA;;AAEJ;AACA,IAAI,MAAM,CAAC,cAAc,CAAC,gBAAgB,EAAE,QAAQ,CAAC;AACrD,IAAI,MAAM,CAAC,cAAc,CAAC,gBAAgB,CAAC,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC;;AAEzE,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,gBAAgB,EAAE,GAAG,EAAE,UAAU,CAAC;AAClE,QAAQ;AACR,MAAM;AACN,IAAI;;AAEJ;AACA;AACA,IAAI,IAAI;AACR,MAAMA,SAAO,CAAC,SAAA,GAAY,gBAAgB;AAC1C,IAAI,EAAE,MAAM;AACZ;AACA,MAAM,MAAM,CAAC,cAAc,CAACA,SAAO,EAAE,WAAW,EAAE;AAClD,QAAQ,KAAK,EAAE,gBAAgB;AAC/B,QAAQ,QAAQ,EAAE,IAAI;AACtB,QAAQ,YAAY,EAAE,IAAI;AAC1B,QAAQ,UAAU,EAAE,IAAI;AACxB,OAAO,CAAC;AACR,IAAI;;AAEJ;AACA;AACA;AACA,IAAI,IAAIA,SAAO,CAAC,OAAA,KAAY,QAAQ,EAAE;AACtC,MAAM,IAAI;AACV,QAAQA,SAAO,CAAC,OAAA,GAAU,gBAAgB;AAC1C,MAAM,EAAE,MAAM;AACd;AACA,QAAQ,MAAM,CAAC,cAAc,CAACA,SAAO,EAAE,SAAS,EAAE;AAClD,UAAU,KAAK,EAAE,gBAAgB;AACjC,UAAU,QAAQ,EAAE,IAAI;AACxB,UAAU,YAAY,EAAE,IAAI;AAC5B,UAAU,UAAU,EAAE,IAAI;AAC1B,SAAS,CAAC;AACV,MAAM;AACN,IAAI;AACJ,IAAI,OAAOA,SAAO;AAClB,EAAE;AACF;;;;"}
1
+ {"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/anthropic-ai/instrumentation.ts"],"sourcesContent":["import {\n InstrumentationBase,\n type InstrumentationConfig,\n type InstrumentationModuleDefinition,\n InstrumentationNodeModuleDefinition,\n} from '@opentelemetry/instrumentation';\nimport type { AnthropicAiClient, AnthropicAiOptions } from '@sentry/core';\nimport {\n _INTERNAL_shouldSkipAiProviderWrapping,\n ANTHROPIC_AI_INTEGRATION_NAME,\n instrumentAnthropicAiClient,\n SDK_VERSION,\n} from '@sentry/core';\n\nconst supportedVersions = ['>=0.19.2 <1.0.0'];\n\ntype AnthropicAiInstrumentationOptions = InstrumentationConfig & AnthropicAiOptions;\n\n/**\n * Represents the patched shape of the Anthropic AI module export.\n */\ninterface PatchedModuleExports {\n [key: string]: unknown;\n Anthropic: abstract new (...args: unknown[]) => AnthropicAiClient;\n}\n\n/**\n * Sentry Anthropic AI instrumentation using OpenTelemetry.\n */\nexport class SentryAnthropicAiInstrumentation extends InstrumentationBase<AnthropicAiInstrumentationOptions> {\n public constructor(config: AnthropicAiInstrumentationOptions = {}) {\n super('@sentry/instrumentation-anthropic-ai', 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 '@anthropic-ai/sdk',\n supportedVersions,\n this._patch.bind(this),\n );\n return module;\n }\n\n /**\n * Core patch logic applying instrumentation to the Anthropic AI client constructor.\n */\n private _patch(exports: PatchedModuleExports): PatchedModuleExports | void {\n const Original = exports.Anthropic;\n\n const config = this.getConfig();\n\n const WrappedAnthropic = function (this: unknown, ...args: unknown[]) {\n // Check if wrapping should be skipped (e.g., when LangChain is handling instrumentation)\n if (_INTERNAL_shouldSkipAiProviderWrapping(ANTHROPIC_AI_INTEGRATION_NAME)) {\n return Reflect.construct(Original, args) as AnthropicAiClient;\n }\n\n const instance = Reflect.construct(Original, args);\n\n return instrumentAnthropicAiClient(instance as AnthropicAiClient, config);\n } as unknown as abstract new (...args: unknown[]) => AnthropicAiClient;\n\n // Preserve static and prototype chains\n Object.setPrototypeOf(WrappedAnthropic, Original);\n Object.setPrototypeOf(WrappedAnthropic.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(WrappedAnthropic, key, descriptor);\n }\n }\n }\n\n // Constructor replacement - handle read-only properties\n // The Anthropic property might have only a getter, so use defineProperty\n try {\n exports.Anthropic = WrappedAnthropic;\n } catch {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, 'Anthropic', {\n value: WrappedAnthropic,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n\n // Wrap the default export if it points to the original constructor\n // Constructor replacement - handle read-only properties\n // The Anthropic property might have only a getter, so use defineProperty\n if (exports.default === Original) {\n try {\n exports.default = WrappedAnthropic;\n } catch {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, 'default', {\n value: WrappedAnthropic,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n }\n return exports;\n }\n}\n"],"names":[],"mappings":";;;AAcA,MAAM,iBAAA,GAAoB,CAAC,iBAAiB,CAAC;;AAY7C;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,EAAE;;AAEF;AACA;AACA;AACA,GAAS,IAAI,GAAoC;AACjD,IAAI,MAAM,MAAA,GAAS,IAAI,mCAAmC;AAC1D,MAAM,mBAAmB;AACzB,MAAM,iBAAiB;AACvB,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AAC5B,KAAK;AACL,IAAI,OAAO,MAAM;AACjB,EAAE;;AAEF;AACA;AACA;AACA,GAAU,MAAM,CAAC,OAAO,EAAqD;AAC7E,IAAI,MAAM,QAAA,GAAW,OAAO,CAAC,SAAS;;AAEtC,IAAI,MAAM,MAAA,GAAS,IAAI,CAAC,SAAS,EAAE;;AAEnC,IAAI,MAAM,mBAAmB,WAAyB,GAAG,IAAI,EAAa;AAC1E;AACA,MAAM,IAAI,sCAAsC,CAAC,6BAA6B,CAAC,EAAE;AACjF,QAAQ,OAAO,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAA;AAC/C,MAAM;;AAEN,MAAM,MAAM,QAAA,GAAW,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC;;AAExD,MAAM,OAAO,2BAA2B,CAAC,QAAA,GAA+B,MAAM,CAAC;AAC/E,IAAI,CAAA;;AAEJ;AACA,IAAI,MAAM,CAAC,cAAc,CAAC,gBAAgB,EAAE,QAAQ,CAAC;AACrD,IAAI,MAAM,CAAC,cAAc,CAAC,gBAAgB,CAAC,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC;;AAEzE,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,gBAAgB,EAAE,GAAG,EAAE,UAAU,CAAC;AAClE,QAAQ;AACR,MAAM;AACN,IAAI;;AAEJ;AACA;AACA,IAAI,IAAI;AACR,MAAM,OAAO,CAAC,SAAA,GAAY,gBAAgB;AAC1C,IAAI,EAAE,MAAM;AACZ;AACA,MAAM,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE;AAClD,QAAQ,KAAK,EAAE,gBAAgB;AAC/B,QAAQ,QAAQ,EAAE,IAAI;AACtB,QAAQ,YAAY,EAAE,IAAI;AAC1B,QAAQ,UAAU,EAAE,IAAI;AACxB,OAAO,CAAC;AACR,IAAI;;AAEJ;AACA;AACA;AACA,IAAI,IAAI,OAAO,CAAC,OAAA,KAAY,QAAQ,EAAE;AACtC,MAAM,IAAI;AACV,QAAQ,OAAO,CAAC,OAAA,GAAU,gBAAgB;AAC1C,MAAM,EAAE,MAAM;AACd;AACA,QAAQ,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,SAAS,EAAE;AAClD,UAAU,KAAK,EAAE,gBAAgB;AACjC,UAAU,QAAQ,EAAE,IAAI;AACxB,UAAU,YAAY,EAAE,IAAI;AAC5B,UAAU,UAAU,EAAE,IAAI;AAC1B,SAAS,CAAC;AACV,MAAM;AACN,IAAI;AACJ,IAAI,OAAO,OAAO;AAClB,EAAE;AACF;;;;"}