@sentry/node 10.61.0 → 10.62.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 (99) hide show
  1. package/build/cjs/integrations/tracing/amqplib/index.js +2 -10
  2. package/build/cjs/integrations/tracing/amqplib/index.js.map +1 -1
  3. package/build/cjs/integrations/tracing/amqplib/vendored/instrumentation.js +117 -0
  4. package/build/cjs/integrations/tracing/amqplib/vendored/instrumentation.js.map +1 -0
  5. package/build/cjs/integrations/tracing/amqplib/vendored/patches.js +185 -0
  6. package/build/cjs/integrations/tracing/amqplib/vendored/patches.js.map +1 -0
  7. package/build/cjs/integrations/tracing/amqplib/vendored/semconv.js +21 -1
  8. package/build/cjs/integrations/tracing/amqplib/vendored/semconv.js.map +1 -1
  9. package/build/cjs/integrations/tracing/amqplib/vendored/types.js +0 -6
  10. package/build/cjs/integrations/tracing/amqplib/vendored/types.js.map +1 -1
  11. package/build/cjs/integrations/tracing/amqplib/vendored/utils.js +71 -80
  12. package/build/cjs/integrations/tracing/amqplib/vendored/utils.js.map +1 -1
  13. package/build/cjs/integrations/tracing/firebase/firebase.js +1 -24
  14. package/build/cjs/integrations/tracing/firebase/firebase.js.map +1 -1
  15. package/build/cjs/integrations/tracing/firebase/otel/firebaseInstrumentation.js +3 -11
  16. package/build/cjs/integrations/tracing/firebase/otel/firebaseInstrumentation.js.map +1 -1
  17. package/build/cjs/integrations/tracing/firebase/otel/patches/firestore.js +33 -72
  18. package/build/cjs/integrations/tracing/firebase/otel/patches/firestore.js.map +1 -1
  19. package/build/cjs/integrations/tracing/firebase/otel/patches/functions.js +46 -105
  20. package/build/cjs/integrations/tracing/firebase/otel/patches/functions.js.map +1 -1
  21. package/build/cjs/integrations/tracing/redis/index.js +5 -3
  22. package/build/cjs/integrations/tracing/redis/index.js.map +1 -1
  23. package/build/cjs/integrations/tracing/vercelai/index.js +3 -0
  24. package/build/cjs/integrations/tracing/vercelai/index.js.map +1 -1
  25. package/build/esm/integrations/tracing/amqplib/index.js +3 -11
  26. package/build/esm/integrations/tracing/amqplib/index.js.map +1 -1
  27. package/build/esm/integrations/tracing/amqplib/vendored/instrumentation.js +115 -0
  28. package/build/esm/integrations/tracing/amqplib/vendored/instrumentation.js.map +1 -0
  29. package/build/esm/integrations/tracing/amqplib/vendored/patches.js +177 -0
  30. package/build/esm/integrations/tracing/amqplib/vendored/patches.js.map +1 -0
  31. package/build/esm/integrations/tracing/amqplib/vendored/semconv.js +12 -2
  32. package/build/esm/integrations/tracing/amqplib/vendored/semconv.js.map +1 -1
  33. package/build/esm/integrations/tracing/amqplib/vendored/types.js +1 -6
  34. package/build/esm/integrations/tracing/amqplib/vendored/types.js.map +1 -1
  35. package/build/esm/integrations/tracing/amqplib/vendored/utils.js +68 -78
  36. package/build/esm/integrations/tracing/amqplib/vendored/utils.js.map +1 -1
  37. package/build/esm/integrations/tracing/firebase/firebase.js +3 -26
  38. package/build/esm/integrations/tracing/firebase/firebase.js.map +1 -1
  39. package/build/esm/integrations/tracing/firebase/otel/firebaseInstrumentation.js +3 -11
  40. package/build/esm/integrations/tracing/firebase/otel/firebaseInstrumentation.js.map +1 -1
  41. package/build/esm/integrations/tracing/firebase/otel/patches/firestore.js +34 -73
  42. package/build/esm/integrations/tracing/firebase/otel/patches/firestore.js.map +1 -1
  43. package/build/esm/integrations/tracing/firebase/otel/patches/functions.js +47 -106
  44. package/build/esm/integrations/tracing/firebase/otel/patches/functions.js.map +1 -1
  45. package/build/esm/integrations/tracing/redis/index.js +6 -4
  46. package/build/esm/integrations/tracing/redis/index.js.map +1 -1
  47. package/build/esm/integrations/tracing/vercelai/index.js +3 -0
  48. package/build/esm/integrations/tracing/vercelai/index.js.map +1 -1
  49. package/build/esm/package.json +1 -1
  50. package/build/types/integrations/tracing/amqplib/index.d.ts +1 -1
  51. package/build/types/integrations/tracing/amqplib/index.d.ts.map +1 -1
  52. package/build/types/integrations/tracing/amqplib/vendored/instrumentation.d.ts +11 -0
  53. package/build/types/integrations/tracing/amqplib/vendored/instrumentation.d.ts.map +1 -0
  54. package/build/types/integrations/tracing/amqplib/vendored/patches.d.ts +11 -0
  55. package/build/types/integrations/tracing/amqplib/vendored/patches.d.ts.map +1 -0
  56. package/build/types/integrations/tracing/amqplib/vendored/semconv.d.ts +25 -37
  57. package/build/types/integrations/tracing/amqplib/vendored/semconv.d.ts.map +1 -1
  58. package/build/types/integrations/tracing/amqplib/vendored/types.d.ts +0 -81
  59. package/build/types/integrations/tracing/amqplib/vendored/types.d.ts.map +1 -1
  60. package/build/types/integrations/tracing/amqplib/vendored/utils.d.ts +16 -9
  61. package/build/types/integrations/tracing/amqplib/vendored/utils.d.ts.map +1 -1
  62. package/build/types/integrations/tracing/firebase/firebase.d.ts.map +1 -1
  63. package/build/types/integrations/tracing/firebase/otel/firebaseInstrumentation.d.ts +4 -9
  64. package/build/types/integrations/tracing/firebase/otel/firebaseInstrumentation.d.ts.map +1 -1
  65. package/build/types/integrations/tracing/firebase/otel/patches/firestore.d.ts +2 -5
  66. package/build/types/integrations/tracing/firebase/otel/patches/firestore.d.ts.map +1 -1
  67. package/build/types/integrations/tracing/firebase/otel/patches/functions.d.ts +3 -8
  68. package/build/types/integrations/tracing/firebase/otel/patches/functions.d.ts.map +1 -1
  69. package/build/types/integrations/tracing/firebase/otel/types.d.ts +0 -20
  70. package/build/types/integrations/tracing/firebase/otel/types.d.ts.map +1 -1
  71. package/build/types/integrations/tracing/redis/index.d.ts.map +1 -1
  72. package/build/types/integrations/tracing/vercelai/index.d.ts +0 -1
  73. package/build/types/integrations/tracing/vercelai/index.d.ts.map +1 -1
  74. package/build/types-ts3.8/integrations/tracing/amqplib/index.d.ts +1 -1
  75. package/build/types-ts3.8/integrations/tracing/amqplib/vendored/instrumentation.d.ts +11 -0
  76. package/build/types-ts3.8/integrations/tracing/amqplib/vendored/patches.d.ts +11 -0
  77. package/build/types-ts3.8/integrations/tracing/amqplib/vendored/semconv.d.ts +25 -37
  78. package/build/types-ts3.8/integrations/tracing/amqplib/vendored/types.d.ts +0 -81
  79. package/build/types-ts3.8/integrations/tracing/amqplib/vendored/utils.d.ts +16 -9
  80. package/build/types-ts3.8/integrations/tracing/firebase/otel/firebaseInstrumentation.d.ts +4 -9
  81. package/build/types-ts3.8/integrations/tracing/firebase/otel/patches/firestore.d.ts +2 -5
  82. package/build/types-ts3.8/integrations/tracing/firebase/otel/patches/functions.d.ts +3 -8
  83. package/build/types-ts3.8/integrations/tracing/firebase/otel/types.d.ts +0 -20
  84. package/build/types-ts3.8/integrations/tracing/vercelai/index.d.ts +0 -1
  85. package/package.json +5 -5
  86. package/build/cjs/integrations/tracing/amqplib/vendored/amqplib.js +0 -452
  87. package/build/cjs/integrations/tracing/amqplib/vendored/amqplib.js.map +0 -1
  88. package/build/cjs/integrations/tracing/amqplib/vendored/semconv-obsolete.js +0 -24
  89. package/build/cjs/integrations/tracing/amqplib/vendored/semconv-obsolete.js.map +0 -1
  90. package/build/esm/integrations/tracing/amqplib/vendored/amqplib.js +0 -450
  91. package/build/esm/integrations/tracing/amqplib/vendored/amqplib.js.map +0 -1
  92. package/build/esm/integrations/tracing/amqplib/vendored/semconv-obsolete.js +0 -13
  93. package/build/esm/integrations/tracing/amqplib/vendored/semconv-obsolete.js.map +0 -1
  94. package/build/types/integrations/tracing/amqplib/vendored/amqplib.d.ts +0 -26
  95. package/build/types/integrations/tracing/amqplib/vendored/amqplib.d.ts.map +0 -1
  96. package/build/types/integrations/tracing/amqplib/vendored/semconv-obsolete.d.ts +0 -63
  97. package/build/types/integrations/tracing/amqplib/vendored/semconv-obsolete.d.ts.map +0 -1
  98. package/build/types-ts3.8/integrations/tracing/amqplib/vendored/amqplib.d.ts +0 -26
  99. package/build/types-ts3.8/integrations/tracing/amqplib/vendored/semconv-obsolete.d.ts +0 -63
@@ -1,45 +1,10 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
- const api = require('@opentelemetry/api');
4
3
  const instrumentation = require('@opentelemetry/instrumentation');
5
4
  const InstrumentationNodeModuleFile = require('../../../InstrumentationNodeModuleFile.js');
5
+ const core = require('@sentry/core');
6
6
 
7
- function patchFunctions(tracer, functionsSupportedVersions, wrap, unwrap, config) {
8
- let requestHook = () => {
9
- };
10
- let responseHook = () => {
11
- };
12
- const errorHook = config.functions?.errorHook;
13
- const configRequestHook = config.functions?.requestHook;
14
- const configResponseHook = config.functions?.responseHook;
15
- if (typeof configResponseHook === "function") {
16
- responseHook = (span, err) => {
17
- instrumentation.safeExecuteInTheMiddle(
18
- () => configResponseHook(span, err),
19
- (error) => {
20
- if (!error) {
21
- return;
22
- }
23
- api.diag.error(error?.message);
24
- },
25
- true
26
- );
27
- };
28
- }
29
- if (typeof configRequestHook === "function") {
30
- requestHook = (span) => {
31
- instrumentation.safeExecuteInTheMiddle(
32
- () => configRequestHook(span),
33
- (error) => {
34
- if (!error) {
35
- return;
36
- }
37
- api.diag.error(error?.message);
38
- },
39
- true
40
- );
41
- };
42
- }
7
+ function patchFunctions(functionsSupportedVersions, wrap, unwrap) {
43
8
  const moduleFunctionsCJS = new instrumentation.InstrumentationNodeModuleDefinition("firebase-functions", functionsSupportedVersions);
44
9
  const modulesToInstrument = [
45
10
  { name: "firebase-functions/lib/v2/providers/https.js", triggerType: "function" },
@@ -52,21 +17,14 @@ function patchFunctions(tracer, functionsSupportedVersions, wrap, unwrap, config
52
17
  new InstrumentationNodeModuleFile.InstrumentationNodeModuleFile(
53
18
  name,
54
19
  functionsSupportedVersions,
55
- (moduleExports) => wrapCommonFunctions(
56
- moduleExports,
57
- wrap,
58
- unwrap,
59
- tracer,
60
- { requestHook, responseHook, errorHook },
61
- triggerType
62
- ),
20
+ (moduleExports) => wrapCommonFunctions(moduleExports, wrap, unwrap, triggerType),
63
21
  (moduleExports) => unwrapCommonFunctions(moduleExports, unwrap)
64
22
  )
65
23
  );
66
24
  });
67
25
  return moduleFunctionsCJS;
68
26
  }
69
- function patchV2Functions(tracer, functionsConfig, triggerType) {
27
+ function patchV2Functions(triggerType) {
70
28
  return function v2FunctionsWrapper(original) {
71
29
  return function(...args) {
72
30
  const handler = typeof args[0] === "function" ? args[0] : args[1];
@@ -76,10 +34,8 @@ function patchV2Functions(tracer, functionsConfig, triggerType) {
76
34
  }
77
35
  const wrappedHandler = async function(...handlerArgs) {
78
36
  const functionName = process.env.FUNCTION_TARGET || process.env.K_SERVICE || "unknown";
79
- const span = tracer.startSpan(`firebase.function.${triggerType}`, {
80
- kind: api.SpanKind.SERVER
81
- });
82
37
  const attributes = {
38
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.firebase.otel.functions",
83
39
  "faas.name": functionName,
84
40
  "faas.trigger": triggerType,
85
41
  "faas.provider": "firebase"
@@ -90,27 +46,32 @@ function patchV2Functions(tracer, functionsConfig, triggerType) {
90
46
  if (process.env.EVENTARC_CLOUD_EVENT_SOURCE) {
91
47
  attributes["cloud.event_source"] = process.env.EVENTARC_CLOUD_EVENT_SOURCE;
92
48
  }
93
- span.setAttributes(attributes);
94
- functionsConfig?.requestHook?.(span);
95
- return api.context.with(api.trace.setSpan(api.context.active(), span), async () => {
96
- let error;
97
- let result;
98
- try {
99
- result = await handler.apply(this, handlerArgs);
100
- } catch (e) {
101
- error = e;
102
- }
103
- functionsConfig?.responseHook?.(span, error);
104
- if (error) {
105
- span.recordException(error);
106
- }
107
- span.end();
108
- if (error) {
109
- await functionsConfig?.errorHook?.(span, error);
110
- throw error;
49
+ return core.startSpanManual(
50
+ {
51
+ name: `firebase.function.${triggerType}`,
52
+ op: "http.request",
53
+ kind: core.SPAN_KIND.SERVER,
54
+ attributes
55
+ },
56
+ async (span) => {
57
+ try {
58
+ const result = await handler.apply(this, handlerArgs);
59
+ span.end();
60
+ return result;
61
+ } catch (error) {
62
+ span.setStatus({ code: core.SPAN_STATUS_ERROR });
63
+ core.captureException(error, {
64
+ mechanism: {
65
+ type: "auto.firebase.otel.functions",
66
+ handled: false
67
+ }
68
+ });
69
+ span.end();
70
+ await core.flush(2e3);
71
+ throw error;
72
+ }
111
73
  }
112
- return result;
113
- });
74
+ );
114
75
  };
115
76
  if (documentOrOptions) {
116
77
  return original.call(this, documentOrOptions, wrappedHandler);
@@ -120,51 +81,31 @@ function patchV2Functions(tracer, functionsConfig, triggerType) {
120
81
  };
121
82
  };
122
83
  }
123
- function wrapCommonFunctions(moduleExports, wrap, unwrap, tracer, functionsConfig, triggerType) {
84
+ function wrapCommonFunctions(moduleExports, wrap, unwrap, triggerType) {
124
85
  unwrapCommonFunctions(moduleExports, unwrap);
125
86
  switch (triggerType) {
126
87
  case "function":
127
- wrap(moduleExports, "onRequest", patchV2Functions(tracer, functionsConfig, "http.request"));
128
- wrap(moduleExports, "onCall", patchV2Functions(tracer, functionsConfig, "http.call"));
88
+ wrap(moduleExports, "onRequest", patchV2Functions("http.request"));
89
+ wrap(moduleExports, "onCall", patchV2Functions("http.call"));
129
90
  break;
130
91
  case "firestore":
131
- wrap(moduleExports, "onDocumentCreated", patchV2Functions(tracer, functionsConfig, "firestore.document.created"));
132
- wrap(moduleExports, "onDocumentUpdated", patchV2Functions(tracer, functionsConfig, "firestore.document.updated"));
133
- wrap(moduleExports, "onDocumentDeleted", patchV2Functions(tracer, functionsConfig, "firestore.document.deleted"));
134
- wrap(moduleExports, "onDocumentWritten", patchV2Functions(tracer, functionsConfig, "firestore.document.written"));
135
- wrap(
136
- moduleExports,
137
- "onDocumentCreatedWithAuthContext",
138
- patchV2Functions(tracer, functionsConfig, "firestore.document.created")
139
- );
140
- wrap(
141
- moduleExports,
142
- "onDocumentUpdatedWithAuthContext",
143
- patchV2Functions(tracer, functionsConfig, "firestore.document.updated")
144
- );
145
- wrap(
146
- moduleExports,
147
- "onDocumentDeletedWithAuthContext",
148
- patchV2Functions(tracer, functionsConfig, "firestore.document.deleted")
149
- );
150
- wrap(
151
- moduleExports,
152
- "onDocumentWrittenWithAuthContext",
153
- patchV2Functions(tracer, functionsConfig, "firestore.document.written")
154
- );
92
+ wrap(moduleExports, "onDocumentCreated", patchV2Functions("firestore.document.created"));
93
+ wrap(moduleExports, "onDocumentUpdated", patchV2Functions("firestore.document.updated"));
94
+ wrap(moduleExports, "onDocumentDeleted", patchV2Functions("firestore.document.deleted"));
95
+ wrap(moduleExports, "onDocumentWritten", patchV2Functions("firestore.document.written"));
96
+ wrap(moduleExports, "onDocumentCreatedWithAuthContext", patchV2Functions("firestore.document.created"));
97
+ wrap(moduleExports, "onDocumentUpdatedWithAuthContext", patchV2Functions("firestore.document.updated"));
98
+ wrap(moduleExports, "onDocumentDeletedWithAuthContext", patchV2Functions("firestore.document.deleted"));
99
+ wrap(moduleExports, "onDocumentWrittenWithAuthContext", patchV2Functions("firestore.document.written"));
155
100
  break;
156
101
  case "scheduler":
157
- wrap(moduleExports, "onSchedule", patchV2Functions(tracer, functionsConfig, "scheduler.scheduled"));
102
+ wrap(moduleExports, "onSchedule", patchV2Functions("scheduler.scheduled"));
158
103
  break;
159
104
  case "storage":
160
- wrap(moduleExports, "onObjectFinalized", patchV2Functions(tracer, functionsConfig, "storage.object.finalized"));
161
- wrap(moduleExports, "onObjectArchived", patchV2Functions(tracer, functionsConfig, "storage.object.archived"));
162
- wrap(moduleExports, "onObjectDeleted", patchV2Functions(tracer, functionsConfig, "storage.object.deleted"));
163
- wrap(
164
- moduleExports,
165
- "onObjectMetadataUpdated",
166
- patchV2Functions(tracer, functionsConfig, "storage.object.metadataUpdated")
167
- );
105
+ wrap(moduleExports, "onObjectFinalized", patchV2Functions("storage.object.finalized"));
106
+ wrap(moduleExports, "onObjectArchived", patchV2Functions("storage.object.archived"));
107
+ wrap(moduleExports, "onObjectDeleted", patchV2Functions("storage.object.deleted"));
108
+ wrap(moduleExports, "onObjectMetadataUpdated", patchV2Functions("storage.object.metadataUpdated"));
168
109
  break;
169
110
  }
170
111
  return moduleExports;
@@ -1 +1 @@
1
- {"version":3,"file":"functions.js","sources":["../../../../../../../src/integrations/tracing/firebase/otel/patches/functions.ts"],"sourcesContent":["import type { Span, Tracer } from '@opentelemetry/api';\nimport { context, diag, SpanKind, trace } from '@opentelemetry/api';\nimport type { InstrumentationBase } from '@opentelemetry/instrumentation';\nimport { InstrumentationNodeModuleDefinition, isWrapped, safeExecuteInTheMiddle } from '@opentelemetry/instrumentation';\nimport { InstrumentationNodeModuleFile } from '../../../InstrumentationNodeModuleFile';\nimport type { SpanAttributes } from '@sentry/core';\nimport type { FirebaseInstrumentation } from '../firebaseInstrumentation';\nimport type {\n AvailableFirebaseFunctions,\n FirebaseFunctions,\n FirebaseInstrumentationConfig,\n OverloadedParameters,\n RequestHook,\n ResponseHook,\n} from '../types';\n\n/**\n * Patches Firebase Functions v2 to add OpenTelemetry instrumentation\n * @param tracer - Opentelemetry Tracer\n * @param functionsSupportedVersions - supported versions of firebase-functions\n * @param wrap - reference to native instrumentation wrap function\n * @param unwrap - reference to native instrumentation unwrap function\n * @param config - Firebase instrumentation config\n */\nexport function patchFunctions(\n tracer: Tracer,\n functionsSupportedVersions: string[],\n wrap: InstrumentationBase['_wrap'],\n unwrap: InstrumentationBase['_unwrap'],\n config: FirebaseInstrumentationConfig,\n): InstrumentationNodeModuleDefinition {\n let requestHook: RequestHook = () => {};\n let responseHook: ResponseHook = () => {};\n const errorHook = config.functions?.errorHook;\n const configRequestHook = config.functions?.requestHook;\n const configResponseHook = config.functions?.responseHook;\n\n if (typeof configResponseHook === 'function') {\n responseHook = (span: Span, err: unknown) => {\n safeExecuteInTheMiddle(\n () => configResponseHook(span, err),\n error => {\n if (!error) {\n return;\n }\n diag.error(error?.message);\n },\n true,\n );\n };\n }\n if (typeof configRequestHook === 'function') {\n requestHook = (span: Span) => {\n safeExecuteInTheMiddle(\n () => configRequestHook(span),\n error => {\n if (!error) {\n return;\n }\n diag.error(error?.message);\n },\n true,\n );\n };\n }\n\n const moduleFunctionsCJS = new InstrumentationNodeModuleDefinition('firebase-functions', functionsSupportedVersions);\n const modulesToInstrument = [\n { name: 'firebase-functions/lib/v2/providers/https.js', triggerType: 'function' },\n { name: 'firebase-functions/lib/v2/providers/firestore.js', triggerType: 'firestore' },\n { name: 'firebase-functions/lib/v2/providers/scheduler.js', triggerType: 'scheduler' },\n { name: 'firebase-functions/lib/v2/storage.js', triggerType: 'storage' },\n ] as const;\n\n modulesToInstrument.forEach(({ name, triggerType }) => {\n moduleFunctionsCJS.files.push(\n new InstrumentationNodeModuleFile(\n name,\n functionsSupportedVersions,\n moduleExports =>\n wrapCommonFunctions(\n moduleExports,\n wrap,\n unwrap,\n tracer,\n { requestHook, responseHook, errorHook },\n triggerType,\n ),\n moduleExports => unwrapCommonFunctions(moduleExports, unwrap),\n ),\n );\n });\n\n return moduleFunctionsCJS;\n}\n\n/**\n * Patches Cloud Functions for Firebase (v2) to add OpenTelemetry instrumentation\n *\n * @param tracer - Opentelemetry Tracer\n * @param functionsConfig - Firebase instrumentation config\n * @param triggerType - Type of trigger\n * @returns A function that patches the function\n */\nexport function patchV2Functions<T extends FirebaseFunctions = FirebaseFunctions>(\n tracer: Tracer,\n functionsConfig: FirebaseInstrumentationConfig['functions'],\n triggerType: string,\n): (original: T) => (...args: OverloadedParameters<T>) => ReturnType<T> {\n return function v2FunctionsWrapper(original: T): (...args: OverloadedParameters<T>) => ReturnType<T> {\n return function (this: FirebaseInstrumentation, ...args: OverloadedParameters<T>): ReturnType<T> {\n const handler = typeof args[0] === 'function' ? args[0] : args[1];\n const documentOrOptions = typeof args[0] === 'function' ? undefined : args[0];\n\n if (!handler) {\n return original.call(this, ...args);\n }\n\n const wrappedHandler = async function (this: unknown, ...handlerArgs: unknown[]): Promise<unknown> {\n const functionName = process.env.FUNCTION_TARGET || process.env.K_SERVICE || 'unknown';\n const span = tracer.startSpan(`firebase.function.${triggerType}`, {\n kind: SpanKind.SERVER,\n });\n\n const attributes: SpanAttributes = {\n 'faas.name': functionName,\n 'faas.trigger': triggerType,\n 'faas.provider': 'firebase',\n };\n\n if (process.env.GCLOUD_PROJECT) {\n attributes['cloud.project_id'] = process.env.GCLOUD_PROJECT;\n }\n\n if (process.env.EVENTARC_CLOUD_EVENT_SOURCE) {\n attributes['cloud.event_source'] = process.env.EVENTARC_CLOUD_EVENT_SOURCE;\n }\n\n span.setAttributes(attributes);\n functionsConfig?.requestHook?.(span);\n\n // Can be changed to safeExecuteInTheMiddleAsync once following is merged and released\n // https://github.com/open-telemetry/opentelemetry-js/pull/6032\n return context.with(trace.setSpan(context.active(), span), async () => {\n let error: Error | undefined;\n let result: T | undefined;\n\n try {\n result = await handler.apply(this, handlerArgs);\n } catch (e) {\n error = e as Error;\n }\n\n functionsConfig?.responseHook?.(span, error);\n\n if (error) {\n span.recordException(error);\n }\n\n span.end();\n\n if (error) {\n await functionsConfig?.errorHook?.(span, error);\n throw error;\n }\n\n return result;\n });\n };\n\n if (documentOrOptions) {\n return original.call(this, documentOrOptions, wrappedHandler);\n } else {\n return original.call(this, wrappedHandler);\n }\n };\n };\n}\n\nfunction wrapCommonFunctions(\n moduleExports: AvailableFirebaseFunctions,\n wrap: InstrumentationBase<FirebaseInstrumentationConfig>['_wrap'],\n unwrap: InstrumentationBase<FirebaseInstrumentationConfig>['_unwrap'],\n tracer: Tracer,\n functionsConfig: FirebaseInstrumentationConfig['functions'],\n triggerType: 'function' | 'firestore' | 'scheduler' | 'storage',\n): AvailableFirebaseFunctions {\n unwrapCommonFunctions(moduleExports, unwrap);\n\n switch (triggerType) {\n case 'function':\n wrap(moduleExports, 'onRequest', patchV2Functions(tracer, functionsConfig, 'http.request'));\n wrap(moduleExports, 'onCall', patchV2Functions(tracer, functionsConfig, 'http.call'));\n break;\n\n case 'firestore':\n wrap(moduleExports, 'onDocumentCreated', patchV2Functions(tracer, functionsConfig, 'firestore.document.created'));\n wrap(moduleExports, 'onDocumentUpdated', patchV2Functions(tracer, functionsConfig, 'firestore.document.updated'));\n wrap(moduleExports, 'onDocumentDeleted', patchV2Functions(tracer, functionsConfig, 'firestore.document.deleted'));\n wrap(moduleExports, 'onDocumentWritten', patchV2Functions(tracer, functionsConfig, 'firestore.document.written'));\n wrap(\n moduleExports,\n 'onDocumentCreatedWithAuthContext',\n patchV2Functions(tracer, functionsConfig, 'firestore.document.created'),\n );\n wrap(\n moduleExports,\n 'onDocumentUpdatedWithAuthContext',\n patchV2Functions(tracer, functionsConfig, 'firestore.document.updated'),\n );\n\n wrap(\n moduleExports,\n 'onDocumentDeletedWithAuthContext',\n patchV2Functions(tracer, functionsConfig, 'firestore.document.deleted'),\n );\n\n wrap(\n moduleExports,\n 'onDocumentWrittenWithAuthContext',\n patchV2Functions(tracer, functionsConfig, 'firestore.document.written'),\n );\n break;\n\n case 'scheduler':\n wrap(moduleExports, 'onSchedule', patchV2Functions(tracer, functionsConfig, 'scheduler.scheduled'));\n break;\n\n case 'storage':\n wrap(moduleExports, 'onObjectFinalized', patchV2Functions(tracer, functionsConfig, 'storage.object.finalized'));\n wrap(moduleExports, 'onObjectArchived', patchV2Functions(tracer, functionsConfig, 'storage.object.archived'));\n wrap(moduleExports, 'onObjectDeleted', patchV2Functions(tracer, functionsConfig, 'storage.object.deleted'));\n wrap(\n moduleExports,\n 'onObjectMetadataUpdated',\n patchV2Functions(tracer, functionsConfig, 'storage.object.metadataUpdated'),\n );\n break;\n }\n\n return moduleExports;\n}\n\nfunction unwrapCommonFunctions(\n moduleExports: AvailableFirebaseFunctions,\n unwrap: InstrumentationBase<FirebaseInstrumentationConfig>['_unwrap'],\n): AvailableFirebaseFunctions {\n const methods: (keyof AvailableFirebaseFunctions)[] = [\n 'onSchedule',\n 'onRequest',\n 'onCall',\n 'onObjectFinalized',\n 'onObjectArchived',\n 'onObjectDeleted',\n 'onObjectMetadataUpdated',\n 'onDocumentCreated',\n 'onDocumentUpdated',\n 'onDocumentDeleted',\n 'onDocumentWritten',\n 'onDocumentCreatedWithAuthContext',\n 'onDocumentUpdatedWithAuthContext',\n 'onDocumentDeletedWithAuthContext',\n 'onDocumentWrittenWithAuthContext',\n ];\n\n for (const method of methods) {\n if (isWrapped(moduleExports[method])) {\n unwrap(moduleExports, method);\n }\n }\n return moduleExports;\n}\n"],"names":["safeExecuteInTheMiddle","diag","InstrumentationNodeModuleDefinition","InstrumentationNodeModuleFile","SpanKind","context","trace","isWrapped"],"mappings":";;;;;;AAwBO,SAAS,cAAA,CACd,MAAA,EACA,0BAAA,EACA,IAAA,EACA,QACA,MAAA,EACqC;AACrC,EAAA,IAAI,cAA2B,MAAM;AAAA,EAAC,CAAA;AACtC,EAAA,IAAI,eAA6B,MAAM;AAAA,EAAC,CAAA;AACxC,EAAA,MAAM,SAAA,GAAY,OAAO,SAAA,EAAW,SAAA;AACpC,EAAA,MAAM,iBAAA,GAAoB,OAAO,SAAA,EAAW,WAAA;AAC5C,EAAA,MAAM,kBAAA,GAAqB,OAAO,SAAA,EAAW,YAAA;AAE7C,EAAA,IAAI,OAAO,uBAAuB,UAAA,EAAY;AAC5C,IAAA,YAAA,GAAe,CAAC,MAAY,GAAA,KAAiB;AAC3C,MAAAA,sCAAA;AAAA,QACE,MAAM,kBAAA,CAAmB,IAAA,EAAM,GAAG,CAAA;AAAA,QAClC,CAAA,KAAA,KAAS;AACP,UAAA,IAAI,CAAC,KAAA,EAAO;AACV,YAAA;AAAA,UACF;AACA,UAAAC,QAAA,CAAK,KAAA,CAAM,OAAO,OAAO,CAAA;AAAA,QAC3B,CAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,CAAA;AAAA,EACF;AACA,EAAA,IAAI,OAAO,sBAAsB,UAAA,EAAY;AAC3C,IAAA,WAAA,GAAc,CAAC,IAAA,KAAe;AAC5B,MAAAD,sCAAA;AAAA,QACE,MAAM,kBAAkB,IAAI,CAAA;AAAA,QAC5B,CAAA,KAAA,KAAS;AACP,UAAA,IAAI,CAAC,KAAA,EAAO;AACV,YAAA;AAAA,UACF;AACA,UAAAC,QAAA,CAAK,KAAA,CAAM,OAAO,OAAO,CAAA;AAAA,QAC3B,CAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,CAAA;AAAA,EACF;AAEA,EAAA,MAAM,kBAAA,GAAqB,IAAIC,mDAAA,CAAoC,oBAAA,EAAsB,0BAA0B,CAAA;AACnH,EAAA,MAAM,mBAAA,GAAsB;AAAA,IAC1B,EAAE,IAAA,EAAM,8CAAA,EAAgD,WAAA,EAAa,UAAA,EAAW;AAAA,IAChF,EAAE,IAAA,EAAM,kDAAA,EAAoD,WAAA,EAAa,WAAA,EAAY;AAAA,IACrF,EAAE,IAAA,EAAM,kDAAA,EAAoD,WAAA,EAAa,WAAA,EAAY;AAAA,IACrF,EAAE,IAAA,EAAM,sCAAA,EAAwC,WAAA,EAAa,SAAA;AAAU,GACzE;AAEA,EAAA,mBAAA,CAAoB,OAAA,CAAQ,CAAC,EAAE,IAAA,EAAM,aAAY,KAAM;AACrD,IAAA,kBAAA,CAAmB,KAAA,CAAM,IAAA;AAAA,MACvB,IAAIC,2DAAA;AAAA,QACF,IAAA;AAAA,QACA,0BAAA;AAAA,QACA,CAAA,aAAA,KACE,mBAAA;AAAA,UACE,aAAA;AAAA,UACA,IAAA;AAAA,UACA,MAAA;AAAA,UACA,MAAA;AAAA,UACA,EAAE,WAAA,EAAa,YAAA,EAAc,SAAA,EAAU;AAAA,UACvC;AAAA,SACF;AAAA,QACF,CAAA,aAAA,KAAiB,qBAAA,CAAsB,aAAA,EAAe,MAAM;AAAA;AAC9D,KACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO,kBAAA;AACT;AAUO,SAAS,gBAAA,CACd,MAAA,EACA,eAAA,EACA,WAAA,EACsE;AACtE,EAAA,OAAO,SAAS,mBAAmB,QAAA,EAAkE;AACnG,IAAA,OAAO,YAA4C,IAAA,EAA8C;AAC/F,MAAA,MAAM,OAAA,GAAU,OAAO,IAAA,CAAK,CAAC,CAAA,KAAM,aAAa,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA,CAAK,CAAC,CAAA;AAChE,MAAA,MAAM,iBAAA,GAAoB,OAAO,IAAA,CAAK,CAAC,MAAM,UAAA,GAAa,MAAA,GAAY,KAAK,CAAC,CAAA;AAE5E,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,OAAO,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,GAAG,IAAI,CAAA;AAAA,MACpC;AAEA,MAAA,MAAM,cAAA,GAAiB,kBAAkC,WAAA,EAA0C;AACjG,QAAA,MAAM,eAAe,OAAA,CAAQ,GAAA,CAAI,eAAA,IAAmB,OAAA,CAAQ,IAAI,SAAA,IAAa,SAAA;AAC7E,QAAA,MAAM,IAAA,GAAO,MAAA,CAAO,SAAA,CAAU,CAAA,kBAAA,EAAqB,WAAW,CAAA,CAAA,EAAI;AAAA,UAChE,MAAMC,YAAA,CAAS;AAAA,SAChB,CAAA;AAED,QAAA,MAAM,UAAA,GAA6B;AAAA,UACjC,WAAA,EAAa,YAAA;AAAA,UACb,cAAA,EAAgB,WAAA;AAAA,UAChB,eAAA,EAAiB;AAAA,SACnB;AAEA,QAAA,IAAI,OAAA,CAAQ,IAAI,cAAA,EAAgB;AAC9B,UAAA,UAAA,CAAW,kBAAkB,CAAA,GAAI,OAAA,CAAQ,GAAA,CAAI,cAAA;AAAA,QAC/C;AAEA,QAAA,IAAI,OAAA,CAAQ,IAAI,2BAAA,EAA6B;AAC3C,UAAA,UAAA,CAAW,oBAAoB,CAAA,GAAI,OAAA,CAAQ,GAAA,CAAI,2BAAA;AAAA,QACjD;AAEA,QAAA,IAAA,CAAK,cAAc,UAAU,CAAA;AAC7B,QAAA,eAAA,EAAiB,cAAc,IAAI,CAAA;AAInC,QAAA,OAAOC,WAAA,CAAQ,KAAKC,SAAA,CAAM,OAAA,CAAQD,YAAQ,MAAA,EAAO,EAAG,IAAI,CAAA,EAAG,YAAY;AACrE,UAAA,IAAI,KAAA;AACJ,UAAA,IAAI,MAAA;AAEJ,UAAA,IAAI;AACF,YAAA,MAAA,GAAS,MAAM,OAAA,CAAQ,KAAA,CAAM,IAAA,EAAM,WAAW,CAAA;AAAA,UAChD,SAAS,CAAA,EAAG;AACV,YAAA,KAAA,GAAQ,CAAA;AAAA,UACV;AAEA,UAAA,eAAA,EAAiB,YAAA,GAAe,MAAM,KAAK,CAAA;AAE3C,UAAA,IAAI,KAAA,EAAO;AACT,YAAA,IAAA,CAAK,gBAAgB,KAAK,CAAA;AAAA,UAC5B;AAEA,UAAA,IAAA,CAAK,GAAA,EAAI;AAET,UAAA,IAAI,KAAA,EAAO;AACT,YAAA,MAAM,eAAA,EAAiB,SAAA,GAAY,IAAA,EAAM,KAAK,CAAA;AAC9C,YAAA,MAAM,KAAA;AAAA,UACR;AAEA,UAAA,OAAO,MAAA;AAAA,QACT,CAAC,CAAA;AAAA,MACH,CAAA;AAEA,MAAA,IAAI,iBAAA,EAAmB;AACrB,QAAA,OAAO,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,iBAAA,EAAmB,cAAc,CAAA;AAAA,MAC9D,CAAA,MAAO;AACL,QAAA,OAAO,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,cAAc,CAAA;AAAA,MAC3C;AAAA,IACF,CAAA;AAAA,EACF,CAAA;AACF;AAEA,SAAS,oBACP,aAAA,EACA,IAAA,EACA,MAAA,EACA,MAAA,EACA,iBACA,WAAA,EAC4B;AAC5B,EAAA,qBAAA,CAAsB,eAAe,MAAM,CAAA;AAE3C,EAAA,QAAQ,WAAA;AAAa,IACnB,KAAK,UAAA;AACH,MAAA,IAAA,CAAK,eAAe,WAAA,EAAa,gBAAA,CAAiB,MAAA,EAAQ,eAAA,EAAiB,cAAc,CAAC,CAAA;AAC1F,MAAA,IAAA,CAAK,eAAe,QAAA,EAAU,gBAAA,CAAiB,MAAA,EAAQ,eAAA,EAAiB,WAAW,CAAC,CAAA;AACpF,MAAA;AAAA,IAEF,KAAK,WAAA;AACH,MAAA,IAAA,CAAK,eAAe,mBAAA,EAAqB,gBAAA,CAAiB,MAAA,EAAQ,eAAA,EAAiB,4BAA4B,CAAC,CAAA;AAChH,MAAA,IAAA,CAAK,eAAe,mBAAA,EAAqB,gBAAA,CAAiB,MAAA,EAAQ,eAAA,EAAiB,4BAA4B,CAAC,CAAA;AAChH,MAAA,IAAA,CAAK,eAAe,mBAAA,EAAqB,gBAAA,CAAiB,MAAA,EAAQ,eAAA,EAAiB,4BAA4B,CAAC,CAAA;AAChH,MAAA,IAAA,CAAK,eAAe,mBAAA,EAAqB,gBAAA,CAAiB,MAAA,EAAQ,eAAA,EAAiB,4BAA4B,CAAC,CAAA;AAChH,MAAA,IAAA;AAAA,QACE,aAAA;AAAA,QACA,kCAAA;AAAA,QACA,gBAAA,CAAiB,MAAA,EAAQ,eAAA,EAAiB,4BAA4B;AAAA,OACxE;AACA,MAAA,IAAA;AAAA,QACE,aAAA;AAAA,QACA,kCAAA;AAAA,QACA,gBAAA,CAAiB,MAAA,EAAQ,eAAA,EAAiB,4BAA4B;AAAA,OACxE;AAEA,MAAA,IAAA;AAAA,QACE,aAAA;AAAA,QACA,kCAAA;AAAA,QACA,gBAAA,CAAiB,MAAA,EAAQ,eAAA,EAAiB,4BAA4B;AAAA,OACxE;AAEA,MAAA,IAAA;AAAA,QACE,aAAA;AAAA,QACA,kCAAA;AAAA,QACA,gBAAA,CAAiB,MAAA,EAAQ,eAAA,EAAiB,4BAA4B;AAAA,OACxE;AACA,MAAA;AAAA,IAEF,KAAK,WAAA;AACH,MAAA,IAAA,CAAK,eAAe,YAAA,EAAc,gBAAA,CAAiB,MAAA,EAAQ,eAAA,EAAiB,qBAAqB,CAAC,CAAA;AAClG,MAAA;AAAA,IAEF,KAAK,SAAA;AACH,MAAA,IAAA,CAAK,eAAe,mBAAA,EAAqB,gBAAA,CAAiB,MAAA,EAAQ,eAAA,EAAiB,0BAA0B,CAAC,CAAA;AAC9G,MAAA,IAAA,CAAK,eAAe,kBAAA,EAAoB,gBAAA,CAAiB,MAAA,EAAQ,eAAA,EAAiB,yBAAyB,CAAC,CAAA;AAC5G,MAAA,IAAA,CAAK,eAAe,iBAAA,EAAmB,gBAAA,CAAiB,MAAA,EAAQ,eAAA,EAAiB,wBAAwB,CAAC,CAAA;AAC1G,MAAA,IAAA;AAAA,QACE,aAAA;AAAA,QACA,yBAAA;AAAA,QACA,gBAAA,CAAiB,MAAA,EAAQ,eAAA,EAAiB,gCAAgC;AAAA,OAC5E;AACA,MAAA;AAAA;AAGJ,EAAA,OAAO,aAAA;AACT;AAEA,SAAS,qBAAA,CACP,eACA,MAAA,EAC4B;AAC5B,EAAA,MAAM,OAAA,GAAgD;AAAA,IACpD,YAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA;AAAA,IACA,mBAAA;AAAA,IACA,kBAAA;AAAA,IACA,iBAAA;AAAA,IACA,yBAAA;AAAA,IACA,mBAAA;AAAA,IACA,mBAAA;AAAA,IACA,mBAAA;AAAA,IACA,mBAAA;AAAA,IACA,kCAAA;AAAA,IACA,kCAAA;AAAA,IACA,kCAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,IAAIE,yBAAA,CAAU,aAAA,CAAc,MAAM,CAAC,CAAA,EAAG;AACpC,MAAA,MAAA,CAAO,eAAe,MAAM,CAAA;AAAA,IAC9B;AAAA,EACF;AACA,EAAA,OAAO,aAAA;AACT;;;;;"}
1
+ {"version":3,"file":"functions.js","sources":["../../../../../../../src/integrations/tracing/firebase/otel/patches/functions.ts"],"sourcesContent":["import type { InstrumentationBase } from '@opentelemetry/instrumentation';\nimport { InstrumentationNodeModuleDefinition, isWrapped } from '@opentelemetry/instrumentation';\nimport { InstrumentationNodeModuleFile } from '../../../InstrumentationNodeModuleFile';\nimport type { SpanAttributes } from '@sentry/core';\nimport {\n captureException,\n flush,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SPAN_KIND,\n SPAN_STATUS_ERROR,\n startSpanManual,\n} from '@sentry/core';\nimport type { FirebaseInstrumentation } from '../firebaseInstrumentation';\nimport type { AvailableFirebaseFunctions, FirebaseFunctions, OverloadedParameters } from '../types';\n\n/**\n * Patches Firebase Functions v2 to add OpenTelemetry instrumentation\n * @param functionsSupportedVersions - supported versions of firebase-functions\n * @param wrap - reference to native instrumentation wrap function\n * @param unwrap - reference to native instrumentation unwrap function\n */\nexport function patchFunctions(\n functionsSupportedVersions: string[],\n wrap: InstrumentationBase['_wrap'],\n unwrap: InstrumentationBase['_unwrap'],\n): InstrumentationNodeModuleDefinition {\n const moduleFunctionsCJS = new InstrumentationNodeModuleDefinition('firebase-functions', functionsSupportedVersions);\n const modulesToInstrument = [\n { name: 'firebase-functions/lib/v2/providers/https.js', triggerType: 'function' },\n { name: 'firebase-functions/lib/v2/providers/firestore.js', triggerType: 'firestore' },\n { name: 'firebase-functions/lib/v2/providers/scheduler.js', triggerType: 'scheduler' },\n { name: 'firebase-functions/lib/v2/storage.js', triggerType: 'storage' },\n ] as const;\n\n modulesToInstrument.forEach(({ name, triggerType }) => {\n moduleFunctionsCJS.files.push(\n new InstrumentationNodeModuleFile(\n name,\n functionsSupportedVersions,\n moduleExports => wrapCommonFunctions(moduleExports, wrap, unwrap, triggerType),\n moduleExports => unwrapCommonFunctions(moduleExports, unwrap),\n ),\n );\n });\n\n return moduleFunctionsCJS;\n}\n\n/**\n * Patches Cloud Functions for Firebase (v2) to add OpenTelemetry instrumentation\n *\n * @param triggerType - Type of trigger\n * @returns A function that patches the function\n */\nexport function patchV2Functions<T extends FirebaseFunctions = FirebaseFunctions>(\n triggerType: string,\n): (original: T) => (...args: OverloadedParameters<T>) => ReturnType<T> {\n return function v2FunctionsWrapper(original: T): (...args: OverloadedParameters<T>) => ReturnType<T> {\n return function (this: FirebaseInstrumentation, ...args: OverloadedParameters<T>): ReturnType<T> {\n const handler = typeof args[0] === 'function' ? args[0] : args[1];\n const documentOrOptions = typeof args[0] === 'function' ? undefined : args[0];\n\n if (!handler) {\n return original.call(this, ...args);\n }\n\n const wrappedHandler = async function (this: unknown, ...handlerArgs: unknown[]): Promise<unknown> {\n const functionName = process.env.FUNCTION_TARGET || process.env.K_SERVICE || 'unknown';\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.firebase.otel.functions',\n 'faas.name': functionName,\n 'faas.trigger': triggerType,\n 'faas.provider': 'firebase',\n };\n\n if (process.env.GCLOUD_PROJECT) {\n attributes['cloud.project_id'] = process.env.GCLOUD_PROJECT;\n }\n\n if (process.env.EVENTARC_CLOUD_EVENT_SOURCE) {\n attributes['cloud.event_source'] = process.env.EVENTARC_CLOUD_EVENT_SOURCE;\n }\n\n // `startSpanManual` to keep the span active but while still allowing us to end it before flushing on error.\n return startSpanManual(\n {\n name: `firebase.function.${triggerType}`,\n op: 'http.request',\n kind: SPAN_KIND.SERVER,\n attributes,\n },\n async span => {\n try {\n const result = await handler.apply(this, handlerArgs);\n span.end();\n return result;\n } catch (error) {\n span.setStatus({ code: SPAN_STATUS_ERROR });\n captureException(error, {\n mechanism: {\n type: 'auto.firebase.otel.functions',\n handled: false,\n },\n });\n span.end();\n await flush(2000);\n throw error;\n }\n },\n );\n };\n\n if (documentOrOptions) {\n return original.call(this, documentOrOptions, wrappedHandler);\n } else {\n return original.call(this, wrappedHandler);\n }\n };\n };\n}\n\nfunction wrapCommonFunctions(\n moduleExports: AvailableFirebaseFunctions,\n wrap: InstrumentationBase['_wrap'],\n unwrap: InstrumentationBase['_unwrap'],\n triggerType: 'function' | 'firestore' | 'scheduler' | 'storage',\n): AvailableFirebaseFunctions {\n unwrapCommonFunctions(moduleExports, unwrap);\n\n switch (triggerType) {\n case 'function':\n wrap(moduleExports, 'onRequest', patchV2Functions('http.request'));\n wrap(moduleExports, 'onCall', patchV2Functions('http.call'));\n break;\n\n case 'firestore':\n wrap(moduleExports, 'onDocumentCreated', patchV2Functions('firestore.document.created'));\n wrap(moduleExports, 'onDocumentUpdated', patchV2Functions('firestore.document.updated'));\n wrap(moduleExports, 'onDocumentDeleted', patchV2Functions('firestore.document.deleted'));\n wrap(moduleExports, 'onDocumentWritten', patchV2Functions('firestore.document.written'));\n wrap(moduleExports, 'onDocumentCreatedWithAuthContext', patchV2Functions('firestore.document.created'));\n wrap(moduleExports, 'onDocumentUpdatedWithAuthContext', patchV2Functions('firestore.document.updated'));\n wrap(moduleExports, 'onDocumentDeletedWithAuthContext', patchV2Functions('firestore.document.deleted'));\n wrap(moduleExports, 'onDocumentWrittenWithAuthContext', patchV2Functions('firestore.document.written'));\n break;\n\n case 'scheduler':\n wrap(moduleExports, 'onSchedule', patchV2Functions('scheduler.scheduled'));\n break;\n\n case 'storage':\n wrap(moduleExports, 'onObjectFinalized', patchV2Functions('storage.object.finalized'));\n wrap(moduleExports, 'onObjectArchived', patchV2Functions('storage.object.archived'));\n wrap(moduleExports, 'onObjectDeleted', patchV2Functions('storage.object.deleted'));\n wrap(moduleExports, 'onObjectMetadataUpdated', patchV2Functions('storage.object.metadataUpdated'));\n break;\n }\n\n return moduleExports;\n}\n\nfunction unwrapCommonFunctions(\n moduleExports: AvailableFirebaseFunctions,\n unwrap: InstrumentationBase['_unwrap'],\n): AvailableFirebaseFunctions {\n const methods: (keyof AvailableFirebaseFunctions)[] = [\n 'onSchedule',\n 'onRequest',\n 'onCall',\n 'onObjectFinalized',\n 'onObjectArchived',\n 'onObjectDeleted',\n 'onObjectMetadataUpdated',\n 'onDocumentCreated',\n 'onDocumentUpdated',\n 'onDocumentDeleted',\n 'onDocumentWritten',\n 'onDocumentCreatedWithAuthContext',\n 'onDocumentUpdatedWithAuthContext',\n 'onDocumentDeletedWithAuthContext',\n 'onDocumentWrittenWithAuthContext',\n ];\n\n for (const method of methods) {\n if (isWrapped(moduleExports[method])) {\n unwrap(moduleExports, method);\n }\n }\n return moduleExports;\n}\n"],"names":["InstrumentationNodeModuleDefinition","InstrumentationNodeModuleFile","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","startSpanManual","SPAN_KIND","SPAN_STATUS_ERROR","captureException","flush","isWrapped"],"mappings":";;;;;;AAqBO,SAAS,cAAA,CACd,0BAAA,EACA,IAAA,EACA,MAAA,EACqC;AACrC,EAAA,MAAM,kBAAA,GAAqB,IAAIA,mDAAA,CAAoC,oBAAA,EAAsB,0BAA0B,CAAA;AACnH,EAAA,MAAM,mBAAA,GAAsB;AAAA,IAC1B,EAAE,IAAA,EAAM,8CAAA,EAAgD,WAAA,EAAa,UAAA,EAAW;AAAA,IAChF,EAAE,IAAA,EAAM,kDAAA,EAAoD,WAAA,EAAa,WAAA,EAAY;AAAA,IACrF,EAAE,IAAA,EAAM,kDAAA,EAAoD,WAAA,EAAa,WAAA,EAAY;AAAA,IACrF,EAAE,IAAA,EAAM,sCAAA,EAAwC,WAAA,EAAa,SAAA;AAAU,GACzE;AAEA,EAAA,mBAAA,CAAoB,OAAA,CAAQ,CAAC,EAAE,IAAA,EAAM,aAAY,KAAM;AACrD,IAAA,kBAAA,CAAmB,KAAA,CAAM,IAAA;AAAA,MACvB,IAAIC,2DAAA;AAAA,QACF,IAAA;AAAA,QACA,0BAAA;AAAA,QACA,CAAA,aAAA,KAAiB,mBAAA,CAAoB,aAAA,EAAe,IAAA,EAAM,QAAQ,WAAW,CAAA;AAAA,QAC7E,CAAA,aAAA,KAAiB,qBAAA,CAAsB,aAAA,EAAe,MAAM;AAAA;AAC9D,KACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO,kBAAA;AACT;AAQO,SAAS,iBACd,WAAA,EACsE;AACtE,EAAA,OAAO,SAAS,mBAAmB,QAAA,EAAkE;AACnG,IAAA,OAAO,YAA4C,IAAA,EAA8C;AAC/F,MAAA,MAAM,OAAA,GAAU,OAAO,IAAA,CAAK,CAAC,CAAA,KAAM,aAAa,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA,CAAK,CAAC,CAAA;AAChE,MAAA,MAAM,iBAAA,GAAoB,OAAO,IAAA,CAAK,CAAC,MAAM,UAAA,GAAa,MAAA,GAAY,KAAK,CAAC,CAAA;AAE5E,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,OAAO,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,GAAG,IAAI,CAAA;AAAA,MACpC;AAEA,MAAA,MAAM,cAAA,GAAiB,kBAAkC,WAAA,EAA0C;AACjG,QAAA,MAAM,eAAe,OAAA,CAAQ,GAAA,CAAI,eAAA,IAAmB,OAAA,CAAQ,IAAI,SAAA,IAAa,SAAA;AAE7E,QAAA,MAAM,UAAA,GAA6B;AAAA,UACjC,CAACC,qCAAgC,GAAG,8BAAA;AAAA,UACpC,WAAA,EAAa,YAAA;AAAA,UACb,cAAA,EAAgB,WAAA;AAAA,UAChB,eAAA,EAAiB;AAAA,SACnB;AAEA,QAAA,IAAI,OAAA,CAAQ,IAAI,cAAA,EAAgB;AAC9B,UAAA,UAAA,CAAW,kBAAkB,CAAA,GAAI,OAAA,CAAQ,GAAA,CAAI,cAAA;AAAA,QAC/C;AAEA,QAAA,IAAI,OAAA,CAAQ,IAAI,2BAAA,EAA6B;AAC3C,UAAA,UAAA,CAAW,oBAAoB,CAAA,GAAI,OAAA,CAAQ,GAAA,CAAI,2BAAA;AAAA,QACjD;AAGA,QAAA,OAAOC,oBAAA;AAAA,UACL;AAAA,YACE,IAAA,EAAM,qBAAqB,WAAW,CAAA,CAAA;AAAA,YACtC,EAAA,EAAI,cAAA;AAAA,YACJ,MAAMC,cAAA,CAAU,MAAA;AAAA,YAChB;AAAA,WACF;AAAA,UACA,OAAM,IAAA,KAAQ;AACZ,YAAA,IAAI;AACF,cAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,KAAA,CAAM,MAAM,WAAW,CAAA;AACpD,cAAA,IAAA,CAAK,GAAA,EAAI;AACT,cAAA,OAAO,MAAA;AAAA,YACT,SAAS,KAAA,EAAO;AACd,cAAA,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAMC,sBAAA,EAAmB,CAAA;AAC1C,cAAAC,qBAAA,CAAiB,KAAA,EAAO;AAAA,gBACtB,SAAA,EAAW;AAAA,kBACT,IAAA,EAAM,8BAAA;AAAA,kBACN,OAAA,EAAS;AAAA;AACX,eACD,CAAA;AACD,cAAA,IAAA,CAAK,GAAA,EAAI;AACT,cAAA,MAAMC,WAAM,GAAI,CAAA;AAChB,cAAA,MAAM,KAAA;AAAA,YACR;AAAA,UACF;AAAA,SACF;AAAA,MACF,CAAA;AAEA,MAAA,IAAI,iBAAA,EAAmB;AACrB,QAAA,OAAO,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,iBAAA,EAAmB,cAAc,CAAA;AAAA,MAC9D,CAAA,MAAO;AACL,QAAA,OAAO,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,cAAc,CAAA;AAAA,MAC3C;AAAA,IACF,CAAA;AAAA,EACF,CAAA;AACF;AAEA,SAAS,mBAAA,CACP,aAAA,EACA,IAAA,EACA,MAAA,EACA,WAAA,EAC4B;AAC5B,EAAA,qBAAA,CAAsB,eAAe,MAAM,CAAA;AAE3C,EAAA,QAAQ,WAAA;AAAa,IACnB,KAAK,UAAA;AACH,MAAA,IAAA,CAAK,aAAA,EAAe,WAAA,EAAa,gBAAA,CAAiB,cAAc,CAAC,CAAA;AACjE,MAAA,IAAA,CAAK,aAAA,EAAe,QAAA,EAAU,gBAAA,CAAiB,WAAW,CAAC,CAAA;AAC3D,MAAA;AAAA,IAEF,KAAK,WAAA;AACH,MAAA,IAAA,CAAK,aAAA,EAAe,mBAAA,EAAqB,gBAAA,CAAiB,4BAA4B,CAAC,CAAA;AACvF,MAAA,IAAA,CAAK,aAAA,EAAe,mBAAA,EAAqB,gBAAA,CAAiB,4BAA4B,CAAC,CAAA;AACvF,MAAA,IAAA,CAAK,aAAA,EAAe,mBAAA,EAAqB,gBAAA,CAAiB,4BAA4B,CAAC,CAAA;AACvF,MAAA,IAAA,CAAK,aAAA,EAAe,mBAAA,EAAqB,gBAAA,CAAiB,4BAA4B,CAAC,CAAA;AACvF,MAAA,IAAA,CAAK,aAAA,EAAe,kCAAA,EAAoC,gBAAA,CAAiB,4BAA4B,CAAC,CAAA;AACtG,MAAA,IAAA,CAAK,aAAA,EAAe,kCAAA,EAAoC,gBAAA,CAAiB,4BAA4B,CAAC,CAAA;AACtG,MAAA,IAAA,CAAK,aAAA,EAAe,kCAAA,EAAoC,gBAAA,CAAiB,4BAA4B,CAAC,CAAA;AACtG,MAAA,IAAA,CAAK,aAAA,EAAe,kCAAA,EAAoC,gBAAA,CAAiB,4BAA4B,CAAC,CAAA;AACtG,MAAA;AAAA,IAEF,KAAK,WAAA;AACH,MAAA,IAAA,CAAK,aAAA,EAAe,YAAA,EAAc,gBAAA,CAAiB,qBAAqB,CAAC,CAAA;AACzE,MAAA;AAAA,IAEF,KAAK,SAAA;AACH,MAAA,IAAA,CAAK,aAAA,EAAe,mBAAA,EAAqB,gBAAA,CAAiB,0BAA0B,CAAC,CAAA;AACrF,MAAA,IAAA,CAAK,aAAA,EAAe,kBAAA,EAAoB,gBAAA,CAAiB,yBAAyB,CAAC,CAAA;AACnF,MAAA,IAAA,CAAK,aAAA,EAAe,iBAAA,EAAmB,gBAAA,CAAiB,wBAAwB,CAAC,CAAA;AACjF,MAAA,IAAA,CAAK,aAAA,EAAe,yBAAA,EAA2B,gBAAA,CAAiB,gCAAgC,CAAC,CAAA;AACjG,MAAA;AAAA;AAGJ,EAAA,OAAO,aAAA;AACT;AAEA,SAAS,qBAAA,CACP,eACA,MAAA,EAC4B;AAC5B,EAAA,MAAM,OAAA,GAAgD;AAAA,IACpD,YAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA;AAAA,IACA,mBAAA;AAAA,IACA,kBAAA;AAAA,IACA,iBAAA;AAAA,IACA,yBAAA;AAAA,IACA,mBAAA;AAAA,IACA,mBAAA;AAAA,IACA,mBAAA;AAAA,IACA,mBAAA;AAAA,IACA,kCAAA;AAAA,IACA,kCAAA;AAAA,IACA,kCAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,IAAIC,yBAAA,CAAU,aAAA,CAAc,MAAM,CAAC,CAAA,EAAG;AACpC,MAAA,MAAA,CAAO,eAAe,MAAM,CAAA;AAAA,IAC9B;AAAA,EACF;AACA,EAAA,OAAO,aAAA;AACT;;;;;"}
@@ -52,9 +52,11 @@ const instrumentRedis = Object.assign(
52
52
  () => {
53
53
  instrumentIORedis();
54
54
  instrumentRedisModule();
55
- void Promise.resolve().then(
56
- () => serverUtils.subscribeRedisDiagnosticChannels(dc.tracingChannel, cacheResponseHook)
57
- );
55
+ if (dc.tracingChannel) {
56
+ void Promise.resolve().then(
57
+ () => serverUtils.subscribeRedisDiagnosticChannels(dc.tracingChannel, cacheResponseHook)
58
+ );
59
+ }
58
60
  },
59
61
  { id: INTEGRATION_NAME }
60
62
  );
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../../src/integrations/tracing/redis/index.ts"],"sourcesContent":["import type { IntegrationFn, Span } from '@sentry/core';\nimport {\n defineIntegration,\n SEMANTIC_ATTRIBUTE_CACHE_HIT,\n SEMANTIC_ATTRIBUTE_CACHE_ITEM_SIZE,\n SEMANTIC_ATTRIBUTE_CACHE_KEY,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n spanToJSON,\n truncate,\n} from '@sentry/core';\nimport { tracingChannel } from 'node:diagnostics_channel';\nimport { subscribeRedisDiagnosticChannels, type RedisTracingChannelFactory } from '@sentry/server-utils';\nimport { generateInstrumentOnce } from '@sentry/node-core';\nimport type { IORedisCommandArgs } from '../../../utils/redisCache';\nimport {\n calculateCacheItemSize,\n GET_COMMANDS,\n getCacheKeySafely,\n getCacheOperation,\n isInCommands,\n shouldConsiderForCache,\n} from '../../../utils/redisCache';\nimport type { IORedisResponseCustomAttributeFunction } from './vendored/types';\nimport { IORedisInstrumentation } from './vendored/ioredis-instrumentation';\nimport { RedisInstrumentation } from './vendored/redis-instrumentation';\n\ninterface RedisOptions {\n /**\n * Define cache prefixes for cache keys that should be captured as a cache span.\n *\n * Setting this to, for example, `['user:']` will capture cache keys that start with `user:`.\n */\n cachePrefixes?: string[];\n /**\n * Maximum length of the cache key added to the span description. If the key exceeds this length, it will be truncated.\n *\n * Passing `0` will use the full cache key without truncation.\n *\n * By default, the full cache key is used.\n */\n maxCacheKeyLength?: number;\n}\n\nconst INTEGRATION_NAME = 'Redis';\n\n/* Only exported for testing purposes */\nexport let _redisOptions: RedisOptions = {};\n\n/* Only exported for testing purposes */\nexport const cacheResponseHook: IORedisResponseCustomAttributeFunction = (\n span: Span,\n redisCommand: string,\n cmdArgs: IORedisCommandArgs,\n response: unknown,\n) => {\n const safeKey = getCacheKeySafely(redisCommand, cmdArgs);\n const cacheOperation = getCacheOperation(redisCommand);\n\n if (\n !safeKey ||\n !cacheOperation ||\n !_redisOptions.cachePrefixes ||\n !shouldConsiderForCache(redisCommand, safeKey, _redisOptions.cachePrefixes)\n ) {\n // not relevant for cache\n return;\n }\n\n // otel/ioredis seems to be using the old standard, as there was a change to those params: https://github.com/open-telemetry/opentelemetry-specification/issues/3199\n // We are using params based on the docs: https://opentelemetry.io/docs/specs/semconv/attributes-registry/network/\n // Fall back to stable semconv attributes (server.address/server.port) when\n // old-semconv ones are absent, eg OTEL_SEMCONV_STABILITY_OPT_IN=database\n // set for node-redis v4/v5.\n const spanData = spanToJSON(span).data;\n const networkPeerAddress = spanData['net.peer.name'] ?? spanData['server.address'];\n const networkPeerPort = spanData['net.peer.port'] ?? spanData['server.port'];\n if (networkPeerPort && networkPeerAddress) {\n span.setAttributes({ 'network.peer.address': networkPeerAddress, 'network.peer.port': networkPeerPort });\n }\n\n const cacheItemSize = calculateCacheItemSize(response);\n\n if (cacheItemSize) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_CACHE_ITEM_SIZE, cacheItemSize);\n }\n\n if (isInCommands(GET_COMMANDS, redisCommand) && cacheItemSize !== undefined) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_CACHE_HIT, cacheItemSize > 0);\n }\n\n span.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: cacheOperation,\n [SEMANTIC_ATTRIBUTE_CACHE_KEY]: safeKey,\n });\n\n // todo: change to string[] once EAP supports it\n const spanDescription = safeKey.join(', ');\n\n span.updateName(\n _redisOptions.maxCacheKeyLength ? truncate(spanDescription, _redisOptions.maxCacheKeyLength) : spanDescription,\n );\n};\n\nconst instrumentIORedis = generateInstrumentOnce(`${INTEGRATION_NAME}.IORedis`, () => {\n return new IORedisInstrumentation({\n responseHook: cacheResponseHook,\n });\n});\n\nconst instrumentRedisModule = generateInstrumentOnce(`${INTEGRATION_NAME}.Redis`, () => {\n return new RedisInstrumentation({\n responseHook: cacheResponseHook,\n });\n});\n\n/**\n * To be able to preload all Redis OTel instrumentations with just one ID\n * (\"Redis\"), all the instrumentations are generated in this one function\n */\nexport const instrumentRedis = Object.assign(\n (): void => {\n instrumentIORedis();\n instrumentRedisModule();\n // node-redis >= 5.12.0 and ioredis >= 5.11.0 publish via diagnostics_channel.\n // `bindTracingChannelToSpan` (inside the subscriber) makes the span the active\n // OTel context via `bindStore`, which needs the Sentry OTel context manager to\n // be registered — `initOpenTelemetry()` does that after integration `setupOnce`,\n // so defer to the next tick.\n void Promise.resolve().then(() =>\n subscribeRedisDiagnosticChannels(tracingChannel as RedisTracingChannelFactory, cacheResponseHook),\n );\n\n // todo: implement them gradually\n // new LegacyRedisInstrumentation({}),\n },\n { id: INTEGRATION_NAME },\n);\n\nconst _redisIntegration = ((options: RedisOptions = {}) => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n _redisOptions = options;\n instrumentRedis();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [redis](https://www.npmjs.com/package/redis) and\n * [ioredis](https://www.npmjs.com/package/ioredis) libraries.\n *\n * For more information, see the [`redisIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/redis/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.redisIntegration()],\n * });\n * ```\n */\nexport const redisIntegration = defineIntegration(_redisIntegration);\n"],"names":["_redisOptions","getCacheKeySafely","getCacheOperation","shouldConsiderForCache","spanToJSON","calculateCacheItemSize","SEMANTIC_ATTRIBUTE_CACHE_ITEM_SIZE","isInCommands","GET_COMMANDS","SEMANTIC_ATTRIBUTE_CACHE_HIT","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_CACHE_KEY","truncate","generateInstrumentOnce","IORedisInstrumentation","RedisInstrumentation","subscribeRedisDiagnosticChannels","tracingChannel","defineIntegration"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../../src/integrations/tracing/redis/index.ts"],"sourcesContent":["import type { IntegrationFn, Span } from '@sentry/core';\nimport {\n defineIntegration,\n SEMANTIC_ATTRIBUTE_CACHE_HIT,\n SEMANTIC_ATTRIBUTE_CACHE_ITEM_SIZE,\n SEMANTIC_ATTRIBUTE_CACHE_KEY,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n spanToJSON,\n truncate,\n} from '@sentry/core';\nimport * as dc from 'node:diagnostics_channel';\nimport { subscribeRedisDiagnosticChannels, type RedisTracingChannelFactory } from '@sentry/server-utils';\nimport { generateInstrumentOnce } from '@sentry/node-core';\nimport type { IORedisCommandArgs } from '../../../utils/redisCache';\nimport {\n calculateCacheItemSize,\n GET_COMMANDS,\n getCacheKeySafely,\n getCacheOperation,\n isInCommands,\n shouldConsiderForCache,\n} from '../../../utils/redisCache';\nimport type { IORedisResponseCustomAttributeFunction } from './vendored/types';\nimport { IORedisInstrumentation } from './vendored/ioredis-instrumentation';\nimport { RedisInstrumentation } from './vendored/redis-instrumentation';\n\ninterface RedisOptions {\n /**\n * Define cache prefixes for cache keys that should be captured as a cache span.\n *\n * Setting this to, for example, `['user:']` will capture cache keys that start with `user:`.\n */\n cachePrefixes?: string[];\n /**\n * Maximum length of the cache key added to the span description. If the key exceeds this length, it will be truncated.\n *\n * Passing `0` will use the full cache key without truncation.\n *\n * By default, the full cache key is used.\n */\n maxCacheKeyLength?: number;\n}\n\nconst INTEGRATION_NAME = 'Redis';\n\n/* Only exported for testing purposes */\nexport let _redisOptions: RedisOptions = {};\n\n/* Only exported for testing purposes */\nexport const cacheResponseHook: IORedisResponseCustomAttributeFunction = (\n span: Span,\n redisCommand: string,\n cmdArgs: IORedisCommandArgs,\n response: unknown,\n) => {\n const safeKey = getCacheKeySafely(redisCommand, cmdArgs);\n const cacheOperation = getCacheOperation(redisCommand);\n\n if (\n !safeKey ||\n !cacheOperation ||\n !_redisOptions.cachePrefixes ||\n !shouldConsiderForCache(redisCommand, safeKey, _redisOptions.cachePrefixes)\n ) {\n // not relevant for cache\n return;\n }\n\n // otel/ioredis seems to be using the old standard, as there was a change to those params: https://github.com/open-telemetry/opentelemetry-specification/issues/3199\n // We are using params based on the docs: https://opentelemetry.io/docs/specs/semconv/attributes-registry/network/\n // Fall back to stable semconv attributes (server.address/server.port) when\n // old-semconv ones are absent, eg OTEL_SEMCONV_STABILITY_OPT_IN=database\n // set for node-redis v4/v5.\n const spanData = spanToJSON(span).data;\n const networkPeerAddress = spanData['net.peer.name'] ?? spanData['server.address'];\n const networkPeerPort = spanData['net.peer.port'] ?? spanData['server.port'];\n if (networkPeerPort && networkPeerAddress) {\n span.setAttributes({ 'network.peer.address': networkPeerAddress, 'network.peer.port': networkPeerPort });\n }\n\n const cacheItemSize = calculateCacheItemSize(response);\n\n if (cacheItemSize) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_CACHE_ITEM_SIZE, cacheItemSize);\n }\n\n if (isInCommands(GET_COMMANDS, redisCommand) && cacheItemSize !== undefined) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_CACHE_HIT, cacheItemSize > 0);\n }\n\n span.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: cacheOperation,\n [SEMANTIC_ATTRIBUTE_CACHE_KEY]: safeKey,\n });\n\n // todo: change to string[] once EAP supports it\n const spanDescription = safeKey.join(', ');\n\n span.updateName(\n _redisOptions.maxCacheKeyLength ? truncate(spanDescription, _redisOptions.maxCacheKeyLength) : spanDescription,\n );\n};\n\nconst instrumentIORedis = generateInstrumentOnce(`${INTEGRATION_NAME}.IORedis`, () => {\n return new IORedisInstrumentation({\n responseHook: cacheResponseHook,\n });\n});\n\nconst instrumentRedisModule = generateInstrumentOnce(`${INTEGRATION_NAME}.Redis`, () => {\n return new RedisInstrumentation({\n responseHook: cacheResponseHook,\n });\n});\n\n/**\n * To be able to preload all Redis OTel instrumentations with just one ID\n * (\"Redis\"), all the instrumentations are generated in this one function\n */\nexport const instrumentRedis = Object.assign(\n (): void => {\n instrumentIORedis();\n instrumentRedisModule();\n // node-redis >= 5.12.0 and ioredis >= 5.11.0 publish via diagnostics_channel.\n // `bindTracingChannelToSpan` (inside the subscriber) makes the span the active\n // OTel context via `bindStore`, which needs the Sentry OTel context manager to\n // be registered — `initOpenTelemetry()` does that after integration `setupOnce`,\n // so defer to the next tick.\n // Check this here to ensure this does not fail at runtime for Node <= 18.18.0\n if (dc.tracingChannel) {\n void Promise.resolve().then(() =>\n subscribeRedisDiagnosticChannels(dc.tracingChannel as RedisTracingChannelFactory, cacheResponseHook),\n );\n }\n\n // todo: implement them gradually\n // new LegacyRedisInstrumentation({}),\n },\n { id: INTEGRATION_NAME },\n);\n\nconst _redisIntegration = ((options: RedisOptions = {}) => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n _redisOptions = options;\n instrumentRedis();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [redis](https://www.npmjs.com/package/redis) and\n * [ioredis](https://www.npmjs.com/package/ioredis) libraries.\n *\n * For more information, see the [`redisIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/redis/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.redisIntegration()],\n * });\n * ```\n */\nexport const redisIntegration = defineIntegration(_redisIntegration);\n"],"names":["_redisOptions","getCacheKeySafely","getCacheOperation","shouldConsiderForCache","spanToJSON","calculateCacheItemSize","SEMANTIC_ATTRIBUTE_CACHE_ITEM_SIZE","isInCommands","GET_COMMANDS","SEMANTIC_ATTRIBUTE_CACHE_HIT","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_CACHE_KEY","truncate","generateInstrumentOnce","IORedisInstrumentation","RedisInstrumentation","subscribeRedisDiagnosticChannels","defineIntegration"],"mappings":"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"}
@@ -2,6 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const core = require('@sentry/core');
4
4
  const nodeCore = require('@sentry/node-core');
5
+ const serverUtils = require('@sentry/server-utils');
5
6
  const constants = require('./constants.js');
6
7
  const instrumentation = require('./instrumentation.js');
7
8
 
@@ -12,11 +13,13 @@ function shouldForceIntegration(client) {
12
13
  }
13
14
  const _vercelAIIntegration = ((options = {}) => {
14
15
  let instrumentation;
16
+ const parentIntegration = serverUtils.vercelAiIntegration(options);
15
17
  return {
16
18
  name: constants.INTEGRATION_NAME,
17
19
  options,
18
20
  setupOnce() {
19
21
  instrumentation = instrumentVercelAi();
22
+ parentIntegration.setupOnce?.();
20
23
  },
21
24
  afterAllSetup(client) {
22
25
  const shouldForce = options.force ?? shouldForceIntegration(client);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../../src/integrations/tracing/vercelai/index.ts"],"sourcesContent":["import type { Client, IntegrationFn } from '@sentry/core';\nimport { addVercelAiProcessors, defineIntegration } from '@sentry/core';\nimport { generateInstrumentOnce, type modulesIntegration } from '@sentry/node-core';\nimport { INTEGRATION_NAME } from './constants';\nimport { SentryVercelAiInstrumentation } from './instrumentation';\nimport type { VercelAiOptions } from './types';\n\nexport const instrumentVercelAi = generateInstrumentOnce(INTEGRATION_NAME, () => new SentryVercelAiInstrumentation({}));\n\n/**\n * Determines if the integration should be forced based on environment and package availability.\n * Returns true if the 'ai' package is available.\n */\nfunction shouldForceIntegration(client: Client): boolean {\n const modules = client.getIntegrationByName<ReturnType<typeof modulesIntegration>>('Modules');\n return !!modules?.getModules?.()?.ai;\n}\n\nconst _vercelAIIntegration = ((options: VercelAiOptions = {}) => {\n let instrumentation: undefined | SentryVercelAiInstrumentation;\n\n return {\n name: INTEGRATION_NAME,\n options,\n setupOnce() {\n instrumentation = instrumentVercelAi();\n },\n afterAllSetup(client) {\n // Auto-detect if we should force the integration when running with 'ai' package available\n // Note that this can only be detected if the 'Modules' integration is available, and running in CJS mode\n const shouldForce = options.force ?? shouldForceIntegration(client);\n\n if (shouldForce) {\n addVercelAiProcessors(client);\n } else {\n instrumentation?.callWhenPatched(() => addVercelAiProcessors(client));\n }\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [ai](https://www.npmjs.com/package/ai) library.\n * This integration is not enabled by default, you need to manually add it.\n *\n * For more information, see the [`ai` documentation](https://sdk.vercel.ai/docs/ai-sdk-core/telemetry).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.vercelAIIntegration()],\n * });\n * ```\n *\n * This integration adds tracing support to all `ai` function calls.\n * You need to opt-in to collecting spans for a specific call,\n * you can do so by setting `experimental_telemetry.isEnabled` to `true` in the first argument of the function call.\n *\n * ```javascript\n * const result = await generateText({\n * model: openai('gpt-4-turbo'),\n * experimental_telemetry: { isEnabled: true },\n * });\n * ```\n *\n * If you want to collect inputs and outputs for a specific call, you must specifically opt-in to each\n * function call by setting `experimental_telemetry.recordInputs` and `experimental_telemetry.recordOutputs`\n * to `true`.\n *\n * ```javascript\n * const result = await generateText({\n * model: openai('gpt-4-turbo'),\n * experimental_telemetry: { isEnabled: true, recordInputs: true, recordOutputs: true },\n * });\n */\nexport const vercelAIIntegration = defineIntegration(_vercelAIIntegration);\n"],"names":["generateInstrumentOnce","INTEGRATION_NAME","SentryVercelAiInstrumentation","addVercelAiProcessors","defineIntegration"],"mappings":";;;;;;;AAOO,MAAM,kBAAA,GAAqBA,gCAAuBC,0BAAA,EAAkB,MAAM,IAAIC,6CAAA,CAA8B,EAAE,CAAC;AAMtH,SAAS,uBAAuB,MAAA,EAAyB;AACvD,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,oBAAA,CAA4D,SAAS,CAAA;AAC5F,EAAA,OAAO,CAAC,CAAC,OAAA,EAAS,UAAA,IAAa,EAAG,EAAA;AACpC;AAEA,MAAM,oBAAA,IAAwB,CAAC,OAAA,GAA2B,EAAC,KAAM;AAC/D,EAAA,IAAI,eAAA;AAEJ,EAAA,OAAO;AAAA,IACL,IAAA,EAAMD,0BAAA;AAAA,IACN,OAAA;AAAA,IACA,SAAA,GAAY;AACV,MAAA,eAAA,GAAkB,kBAAA,EAAmB;AAAA,IACvC,CAAA;AAAA,IACA,cAAc,MAAA,EAAQ;AAGpB,MAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,KAAA,IAAS,sBAAA,CAAuB,MAAM,CAAA;AAElE,MAAA,IAAI,WAAA,EAAa;AACf,QAAAE,0BAAA,CAAsB,MAAM,CAAA;AAAA,MAC9B,CAAA,MAAO;AACL,QAAA,eAAA,EAAiB,eAAA,CAAgB,MAAMA,0BAAA,CAAsB,MAAM,CAAC,CAAA;AAAA,MACtE;AAAA,IACF;AAAA,GACF;AACF,CAAA,CAAA;AAsCO,MAAM,mBAAA,GAAsBC,uBAAkB,oBAAoB;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../../src/integrations/tracing/vercelai/index.ts"],"sourcesContent":["import type { Client, IntegrationFn } from '@sentry/core';\nimport { addVercelAiProcessors, defineIntegration } from '@sentry/core';\nimport { generateInstrumentOnce, type modulesIntegration } from '@sentry/node-core';\nimport { vercelAiIntegration as serverUtilsVercelAiIntegration } from '@sentry/server-utils';\nimport { INTEGRATION_NAME } from './constants';\nimport { SentryVercelAiInstrumentation } from './instrumentation';\nimport type { VercelAiOptions } from './types';\n\nexport const instrumentVercelAi = generateInstrumentOnce(INTEGRATION_NAME, () => new SentryVercelAiInstrumentation({}));\n\n/**\n * Determines if the integration should be forced based on environment and package availability.\n * Returns true if the 'ai' package is available.\n */\nfunction shouldForceIntegration(client: Client): boolean {\n const modules = client.getIntegrationByName<ReturnType<typeof modulesIntegration>>('Modules');\n return !!modules?.getModules?.()?.ai;\n}\n\nconst _vercelAIIntegration = ((options: VercelAiOptions = {}) => {\n let instrumentation: undefined | SentryVercelAiInstrumentation;\n\n const parentIntegration = serverUtilsVercelAiIntegration(options);\n\n return {\n name: INTEGRATION_NAME,\n options,\n setupOnce() {\n instrumentation = instrumentVercelAi();\n parentIntegration.setupOnce?.();\n },\n afterAllSetup(client) {\n // Auto-detect if we should force the integration when running with 'ai' package available\n // Note that this can only be detected if the 'Modules' integration is available, and running in CJS mode\n const shouldForce = options.force ?? shouldForceIntegration(client);\n\n if (shouldForce) {\n addVercelAiProcessors(client);\n } else {\n instrumentation?.callWhenPatched(() => addVercelAiProcessors(client));\n }\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [ai](https://www.npmjs.com/package/ai) library.\n *\n * For more information, see the [`ai` documentation](https://sdk.vercel.ai/docs/ai-sdk-core/telemetry).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.vercelAIIntegration()],\n * });\n * ```\n *\n * This integration adds tracing support to all `ai` function calls.\n * You need to opt-in to collecting spans for a specific call,\n * you can do so by setting `experimental_telemetry.isEnabled` to `true` in the first argument of the function call.\n *\n * ```javascript\n * const result = await generateText({\n * model: openai('gpt-4-turbo'),\n * experimental_telemetry: { isEnabled: true },\n * });\n * ```\n *\n * If you want to collect inputs and outputs for a specific call, you must specifically opt-in to each\n * function call by setting `experimental_telemetry.recordInputs` and `experimental_telemetry.recordOutputs`\n * to `true`.\n *\n * ```javascript\n * const result = await generateText({\n * model: openai('gpt-4-turbo'),\n * experimental_telemetry: { isEnabled: true, recordInputs: true, recordOutputs: true },\n * });\n */\nexport const vercelAIIntegration = defineIntegration(_vercelAIIntegration);\n"],"names":["generateInstrumentOnce","INTEGRATION_NAME","SentryVercelAiInstrumentation","serverUtilsVercelAiIntegration","addVercelAiProcessors","defineIntegration"],"mappings":";;;;;;;;AAQO,MAAM,kBAAA,GAAqBA,gCAAuBC,0BAAA,EAAkB,MAAM,IAAIC,6CAAA,CAA8B,EAAE,CAAC;AAMtH,SAAS,uBAAuB,MAAA,EAAyB;AACvD,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,oBAAA,CAA4D,SAAS,CAAA;AAC5F,EAAA,OAAO,CAAC,CAAC,OAAA,EAAS,UAAA,IAAa,EAAG,EAAA;AACpC;AAEA,MAAM,oBAAA,IAAwB,CAAC,OAAA,GAA2B,EAAC,KAAM;AAC/D,EAAA,IAAI,eAAA;AAEJ,EAAA,MAAM,iBAAA,GAAoBC,gCAA+B,OAAO,CAAA;AAEhE,EAAA,OAAO;AAAA,IACL,IAAA,EAAMF,0BAAA;AAAA,IACN,OAAA;AAAA,IACA,SAAA,GAAY;AACV,MAAA,eAAA,GAAkB,kBAAA,EAAmB;AACrC,MAAA,iBAAA,CAAkB,SAAA,IAAY;AAAA,IAChC,CAAA;AAAA,IACA,cAAc,MAAA,EAAQ;AAGpB,MAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,KAAA,IAAS,sBAAA,CAAuB,MAAM,CAAA;AAElE,MAAA,IAAI,WAAA,EAAa;AACf,QAAAG,0BAAA,CAAsB,MAAM,CAAA;AAAA,MAC9B,CAAA,MAAO;AACL,QAAA,eAAA,EAAiB,eAAA,CAAgB,MAAMA,0BAAA,CAAsB,MAAM,CAAC,CAAA;AAAA,MACtE;AAAA,IACF;AAAA,GACF;AACF,CAAA,CAAA;AAqCO,MAAM,mBAAA,GAAsBC,uBAAkB,oBAAoB;;;;;"}
@@ -1,17 +1,9 @@
1
- import { AmqplibInstrumentation } from './vendored/amqplib.js';
2
1
  import { defineIntegration } from '@sentry/core';
3
- import { generateInstrumentOnce, addOriginToSpan } from '@sentry/node-core';
2
+ import { generateInstrumentOnce } from '@sentry/node-core';
3
+ import { AmqplibInstrumentation } from './vendored/instrumentation.js';
4
4
 
5
5
  const INTEGRATION_NAME = "Amqplib";
6
- const config = {
7
- consumeEndHook: (span) => {
8
- addOriginToSpan(span, "auto.amqplib.otel.consumer");
9
- },
10
- publishHook: (span) => {
11
- addOriginToSpan(span, "auto.amqplib.otel.publisher");
12
- }
13
- };
14
- const instrumentAmqplib = generateInstrumentOnce(INTEGRATION_NAME, () => new AmqplibInstrumentation(config));
6
+ const instrumentAmqplib = generateInstrumentOnce(INTEGRATION_NAME, () => new AmqplibInstrumentation());
15
7
  const _amqplibIntegration = (() => {
16
8
  return {
17
9
  name: INTEGRATION_NAME,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../../src/integrations/tracing/amqplib/index.ts"],"sourcesContent":["import type { Span } from '@opentelemetry/api';\nimport { AmqplibInstrumentation } from './vendored/amqplib';\nimport type { AmqplibInstrumentationConfig } from './vendored/types';\nimport type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\n\nconst INTEGRATION_NAME = 'Amqplib';\n\nconst config: AmqplibInstrumentationConfig = {\n consumeEndHook: (span: Span) => {\n addOriginToSpan(span, 'auto.amqplib.otel.consumer');\n },\n publishHook: (span: Span) => {\n addOriginToSpan(span, 'auto.amqplib.otel.publisher');\n },\n};\n\nexport const instrumentAmqplib = generateInstrumentOnce(INTEGRATION_NAME, () => new AmqplibInstrumentation(config));\n\nconst _amqplibIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentAmqplib();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [amqplib](https://www.npmjs.com/package/amqplib) library.\n *\n * For more information, see the [`amqplibIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/amqplib/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.amqplibIntegration()],\n * });\n * ```\n */\nexport const amqplibIntegration = defineIntegration(_amqplibIntegration);\n"],"names":[],"mappings":";;;;AAOA,MAAM,gBAAA,GAAmB,SAAA;AAEzB,MAAM,MAAA,GAAuC;AAAA,EAC3C,cAAA,EAAgB,CAAC,IAAA,KAAe;AAC9B,IAAA,eAAA,CAAgB,MAAM,4BAA4B,CAAA;AAAA,EACpD,CAAA;AAAA,EACA,WAAA,EAAa,CAAC,IAAA,KAAe;AAC3B,IAAA,eAAA,CAAgB,MAAM,6BAA6B,CAAA;AAAA,EACrD;AACF,CAAA;AAEO,MAAM,oBAAoB,sBAAA,CAAuB,gBAAA,EAAkB,MAAM,IAAI,sBAAA,CAAuB,MAAM,CAAC;AAElH,MAAM,uBAAuB,MAAM;AACjC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,SAAA,GAAY;AACV,MAAA,iBAAA,EAAkB;AAAA,IACpB;AAAA,GACF;AACF,CAAA,CAAA;AAgBO,MAAM,kBAAA,GAAqB,kBAAkB,mBAAmB;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../../src/integrations/tracing/amqplib/index.ts"],"sourcesContent":["import type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node-core';\nimport { AmqplibInstrumentation } from './vendored/instrumentation';\n\nconst INTEGRATION_NAME = 'Amqplib';\n\nexport const instrumentAmqplib = generateInstrumentOnce(INTEGRATION_NAME, () => new AmqplibInstrumentation());\n\nconst _amqplibIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentAmqplib();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [amqplib](https://www.npmjs.com/package/amqplib) library.\n *\n * For more information, see the [`amqplibIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/amqplib/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.amqplibIntegration()],\n * });\n * ```\n */\nexport const amqplibIntegration = defineIntegration(_amqplibIntegration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,gBAAA,GAAmB,SAAA;AAElB,MAAM,oBAAoB,sBAAA,CAAuB,gBAAA,EAAkB,MAAM,IAAI,wBAAwB;AAE5G,MAAM,uBAAuB,MAAM;AACjC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,SAAA,GAAY;AACV,MAAA,iBAAA,EAAkB;AAAA,IACpB;AAAA,GACF;AACF,CAAA,CAAA;AAgBO,MAAM,kBAAA,GAAqB,kBAAkB,mBAAmB;;;;"}
@@ -0,0 +1,115 @@
1
+ import { InstrumentationBase, InstrumentationNodeModuleDefinition, isWrapped } from '@opentelemetry/instrumentation';
2
+ import { SDK_VERSION } from '@sentry/core';
3
+ import { InstrumentationNodeModuleFile } from '../../InstrumentationNodeModuleFile.js';
4
+ import { getConnectPatch, getPublishPatch, getConsumePatch, getAckPatch, getAckAllPatch, getChannelEmitPatch, getConfirmedPublishPatch } from './patches.js';
5
+ import { EndOperation } from './types.js';
6
+
7
+ const PACKAGE_NAME = "@sentry/instrumentation-amqplib";
8
+ const supportedVersions = [">=0.5.5 <2"];
9
+ class AmqplibInstrumentation extends InstrumentationBase {
10
+ constructor(config = {}) {
11
+ super(PACKAGE_NAME, SDK_VERSION, config);
12
+ }
13
+ init() {
14
+ const channelModelModuleFile = new InstrumentationNodeModuleFile(
15
+ "amqplib/lib/channel_model.js",
16
+ supportedVersions,
17
+ this.patchChannelModel.bind(this),
18
+ this.unpatchChannelModel.bind(this)
19
+ );
20
+ const callbackModelModuleFile = new InstrumentationNodeModuleFile(
21
+ "amqplib/lib/callback_model.js",
22
+ supportedVersions,
23
+ this.patchChannelModel.bind(this),
24
+ this.unpatchChannelModel.bind(this)
25
+ );
26
+ const connectModuleFile = new InstrumentationNodeModuleFile(
27
+ "amqplib/lib/connect.js",
28
+ supportedVersions,
29
+ this.patchConnect.bind(this),
30
+ this.unpatchConnect.bind(this)
31
+ );
32
+ const module = new InstrumentationNodeModuleDefinition("amqplib", supportedVersions, void 0, void 0, [
33
+ channelModelModuleFile,
34
+ connectModuleFile,
35
+ callbackModelModuleFile
36
+ ]);
37
+ return module;
38
+ }
39
+ patchConnect(moduleExports) {
40
+ const unpatchedExports = this.unpatchConnect(moduleExports);
41
+ if (!isWrapped(unpatchedExports.connect)) {
42
+ this._wrap(unpatchedExports, "connect", getConnectPatch);
43
+ }
44
+ return unpatchedExports;
45
+ }
46
+ unpatchConnect(moduleExports) {
47
+ if (isWrapped(moduleExports.connect)) {
48
+ this._unwrap(moduleExports, "connect");
49
+ }
50
+ return moduleExports;
51
+ }
52
+ patchChannelModel(moduleExports) {
53
+ if (!isWrapped(moduleExports.Channel.prototype.publish)) {
54
+ this._wrap(moduleExports.Channel.prototype, "publish", getPublishPatch);
55
+ }
56
+ if (!isWrapped(moduleExports.Channel.prototype.consume)) {
57
+ this._wrap(moduleExports.Channel.prototype, "consume", getConsumePatch);
58
+ }
59
+ if (!isWrapped(moduleExports.Channel.prototype.ack)) {
60
+ this._wrap(moduleExports.Channel.prototype, "ack", getAckPatch(false, EndOperation.Ack));
61
+ }
62
+ if (!isWrapped(moduleExports.Channel.prototype.nack)) {
63
+ this._wrap(moduleExports.Channel.prototype, "nack", getAckPatch(true, EndOperation.Nack));
64
+ }
65
+ if (!isWrapped(moduleExports.Channel.prototype.reject)) {
66
+ this._wrap(moduleExports.Channel.prototype, "reject", getAckPatch(true, EndOperation.Reject));
67
+ }
68
+ if (!isWrapped(moduleExports.Channel.prototype.ackAll)) {
69
+ this._wrap(moduleExports.Channel.prototype, "ackAll", getAckAllPatch(false, EndOperation.AckAll));
70
+ }
71
+ if (!isWrapped(moduleExports.Channel.prototype.nackAll)) {
72
+ this._wrap(moduleExports.Channel.prototype, "nackAll", getAckAllPatch(true, EndOperation.NackAll));
73
+ }
74
+ if (!isWrapped(moduleExports.Channel.prototype.emit)) {
75
+ this._wrap(moduleExports.Channel.prototype, "emit", getChannelEmitPatch);
76
+ }
77
+ if (!isWrapped(moduleExports.ConfirmChannel.prototype.publish)) {
78
+ this._wrap(moduleExports.ConfirmChannel.prototype, "publish", getConfirmedPublishPatch);
79
+ }
80
+ return moduleExports;
81
+ }
82
+ unpatchChannelModel(moduleExports) {
83
+ if (isWrapped(moduleExports.Channel.prototype.publish)) {
84
+ this._unwrap(moduleExports.Channel.prototype, "publish");
85
+ }
86
+ if (isWrapped(moduleExports.Channel.prototype.consume)) {
87
+ this._unwrap(moduleExports.Channel.prototype, "consume");
88
+ }
89
+ if (isWrapped(moduleExports.Channel.prototype.ack)) {
90
+ this._unwrap(moduleExports.Channel.prototype, "ack");
91
+ }
92
+ if (isWrapped(moduleExports.Channel.prototype.nack)) {
93
+ this._unwrap(moduleExports.Channel.prototype, "nack");
94
+ }
95
+ if (isWrapped(moduleExports.Channel.prototype.reject)) {
96
+ this._unwrap(moduleExports.Channel.prototype, "reject");
97
+ }
98
+ if (isWrapped(moduleExports.Channel.prototype.ackAll)) {
99
+ this._unwrap(moduleExports.Channel.prototype, "ackAll");
100
+ }
101
+ if (isWrapped(moduleExports.Channel.prototype.nackAll)) {
102
+ this._unwrap(moduleExports.Channel.prototype, "nackAll");
103
+ }
104
+ if (isWrapped(moduleExports.Channel.prototype.emit)) {
105
+ this._unwrap(moduleExports.Channel.prototype, "emit");
106
+ }
107
+ if (isWrapped(moduleExports.ConfirmChannel.prototype.publish)) {
108
+ this._unwrap(moduleExports.ConfirmChannel.prototype, "publish");
109
+ }
110
+ return moduleExports;
111
+ }
112
+ }
113
+
114
+ export { AmqplibInstrumentation };
115
+ //# sourceMappingURL=instrumentation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instrumentation.js","sources":["../../../../../../src/integrations/tracing/amqplib/vendored/instrumentation.ts"],"sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n *\n * NOTICE from the Sentry authors:\n * - Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/15ef7506553f631ea4181391e0c5725a56f0d082/packages/instrumentation-amqplib\n * - Upstream version: @opentelemetry/instrumentation-amqplib@0.65.0\n * - Refactored to use Sentry's span APIs instead of OpenTelemetry tracing APIs; the channel/connection\n * patches live in `patches.ts` and span creation in `utils.ts`\n * - Dropped the instrumentation config and all hooks; origin is folded into span creation instead of\n * `index.ts` hooks (see `patches.ts`/`utils.ts` for details)\n */\n\nimport type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport { InstrumentationBase, InstrumentationNodeModuleDefinition, isWrapped } from '@opentelemetry/instrumentation';\nimport { SDK_VERSION } from '@sentry/core';\nimport { InstrumentationNodeModuleFile } from '../../InstrumentationNodeModuleFile';\nimport {\n getAckAllPatch,\n getAckPatch,\n getChannelEmitPatch,\n getConfirmedPublishPatch,\n getConnectPatch,\n getConsumePatch,\n getPublishPatch,\n} from './patches';\nimport { EndOperation } from './types';\n\nconst PACKAGE_NAME = '@sentry/instrumentation-amqplib';\nconst supportedVersions = ['>=0.5.5 <2'];\n\nexport class AmqplibInstrumentation extends InstrumentationBase<InstrumentationConfig> {\n public constructor(config: InstrumentationConfig = {}) {\n super(PACKAGE_NAME, SDK_VERSION, config);\n }\n\n protected init(): InstrumentationNodeModuleDefinition {\n const channelModelModuleFile = new InstrumentationNodeModuleFile(\n 'amqplib/lib/channel_model.js',\n supportedVersions,\n this.patchChannelModel.bind(this),\n this.unpatchChannelModel.bind(this),\n );\n\n const callbackModelModuleFile = new InstrumentationNodeModuleFile(\n 'amqplib/lib/callback_model.js',\n supportedVersions,\n this.patchChannelModel.bind(this),\n this.unpatchChannelModel.bind(this),\n );\n\n const connectModuleFile = new InstrumentationNodeModuleFile(\n 'amqplib/lib/connect.js',\n supportedVersions,\n this.patchConnect.bind(this),\n this.unpatchConnect.bind(this),\n );\n\n const module = new InstrumentationNodeModuleDefinition('amqplib', supportedVersions, undefined, undefined, [\n channelModelModuleFile,\n connectModuleFile,\n callbackModelModuleFile,\n ]);\n return module;\n }\n\n private patchConnect(moduleExports: any): any {\n const unpatchedExports = this.unpatchConnect(moduleExports);\n if (!isWrapped(unpatchedExports.connect)) {\n this._wrap(unpatchedExports, 'connect', getConnectPatch);\n }\n return unpatchedExports;\n }\n\n private unpatchConnect(moduleExports: any): any {\n if (isWrapped(moduleExports.connect)) {\n this._unwrap(moduleExports, 'connect');\n }\n return moduleExports;\n }\n\n private patchChannelModel(moduleExports: any): any {\n if (!isWrapped(moduleExports.Channel.prototype.publish)) {\n this._wrap(moduleExports.Channel.prototype, 'publish', getPublishPatch);\n }\n if (!isWrapped(moduleExports.Channel.prototype.consume)) {\n this._wrap(moduleExports.Channel.prototype, 'consume', getConsumePatch);\n }\n if (!isWrapped(moduleExports.Channel.prototype.ack)) {\n this._wrap(moduleExports.Channel.prototype, 'ack', getAckPatch(false, EndOperation.Ack));\n }\n if (!isWrapped(moduleExports.Channel.prototype.nack)) {\n this._wrap(moduleExports.Channel.prototype, 'nack', getAckPatch(true, EndOperation.Nack));\n }\n if (!isWrapped(moduleExports.Channel.prototype.reject)) {\n this._wrap(moduleExports.Channel.prototype, 'reject', getAckPatch(true, EndOperation.Reject));\n }\n if (!isWrapped(moduleExports.Channel.prototype.ackAll)) {\n this._wrap(moduleExports.Channel.prototype, 'ackAll', getAckAllPatch(false, EndOperation.AckAll));\n }\n if (!isWrapped(moduleExports.Channel.prototype.nackAll)) {\n this._wrap(moduleExports.Channel.prototype, 'nackAll', getAckAllPatch(true, EndOperation.NackAll));\n }\n if (!isWrapped(moduleExports.Channel.prototype.emit)) {\n this._wrap(moduleExports.Channel.prototype, 'emit', getChannelEmitPatch);\n }\n if (!isWrapped(moduleExports.ConfirmChannel.prototype.publish)) {\n this._wrap(moduleExports.ConfirmChannel.prototype, 'publish', getConfirmedPublishPatch);\n }\n return moduleExports;\n }\n\n private unpatchChannelModel(moduleExports: any): any {\n if (isWrapped(moduleExports.Channel.prototype.publish)) {\n this._unwrap(moduleExports.Channel.prototype, 'publish');\n }\n if (isWrapped(moduleExports.Channel.prototype.consume)) {\n this._unwrap(moduleExports.Channel.prototype, 'consume');\n }\n if (isWrapped(moduleExports.Channel.prototype.ack)) {\n this._unwrap(moduleExports.Channel.prototype, 'ack');\n }\n if (isWrapped(moduleExports.Channel.prototype.nack)) {\n this._unwrap(moduleExports.Channel.prototype, 'nack');\n }\n if (isWrapped(moduleExports.Channel.prototype.reject)) {\n this._unwrap(moduleExports.Channel.prototype, 'reject');\n }\n if (isWrapped(moduleExports.Channel.prototype.ackAll)) {\n this._unwrap(moduleExports.Channel.prototype, 'ackAll');\n }\n if (isWrapped(moduleExports.Channel.prototype.nackAll)) {\n this._unwrap(moduleExports.Channel.prototype, 'nackAll');\n }\n if (isWrapped(moduleExports.Channel.prototype.emit)) {\n this._unwrap(moduleExports.Channel.prototype, 'emit');\n }\n if (isWrapped(moduleExports.ConfirmChannel.prototype.publish)) {\n this._unwrap(moduleExports.ConfirmChannel.prototype, 'publish');\n }\n return moduleExports;\n }\n}\n"],"names":[],"mappings":";;;;;;AA4BA,MAAM,YAAA,GAAe,iCAAA;AACrB,MAAM,iBAAA,GAAoB,CAAC,YAAY,CAAA;AAEhC,MAAM,+BAA+B,mBAAA,CAA2C;AAAA,EAC9E,WAAA,CAAY,MAAA,GAAgC,EAAC,EAAG;AACrD,IAAA,KAAA,CAAM,YAAA,EAAc,aAAa,MAAM,CAAA;AAAA,EACzC;AAAA,EAEU,IAAA,GAA4C;AACpD,IAAA,MAAM,yBAAyB,IAAI,6BAAA;AAAA,MACjC,8BAAA;AAAA,MACA,iBAAA;AAAA,MACA,IAAA,CAAK,iBAAA,CAAkB,IAAA,CAAK,IAAI,CAAA;AAAA,MAChC,IAAA,CAAK,mBAAA,CAAoB,IAAA,CAAK,IAAI;AAAA,KACpC;AAEA,IAAA,MAAM,0BAA0B,IAAI,6BAAA;AAAA,MAClC,+BAAA;AAAA,MACA,iBAAA;AAAA,MACA,IAAA,CAAK,iBAAA,CAAkB,IAAA,CAAK,IAAI,CAAA;AAAA,MAChC,IAAA,CAAK,mBAAA,CAAoB,IAAA,CAAK,IAAI;AAAA,KACpC;AAEA,IAAA,MAAM,oBAAoB,IAAI,6BAAA;AAAA,MAC5B,wBAAA;AAAA,MACA,iBAAA;AAAA,MACA,IAAA,CAAK,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA;AAAA,MAC3B,IAAA,CAAK,cAAA,CAAe,IAAA,CAAK,IAAI;AAAA,KAC/B;AAEA,IAAA,MAAM,SAAS,IAAI,mCAAA,CAAoC,SAAA,EAAW,iBAAA,EAAmB,QAAW,MAAA,EAAW;AAAA,MACzG,sBAAA;AAAA,MACA,iBAAA;AAAA,MACA;AAAA,KACD,CAAA;AACD,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEQ,aAAa,aAAA,EAAyB;AAC5C,IAAA,MAAM,gBAAA,GAAmB,IAAA,CAAK,cAAA,CAAe,aAAa,CAAA;AAC1D,IAAA,IAAI,CAAC,SAAA,CAAU,gBAAA,CAAiB,OAAO,CAAA,EAAG;AACxC,MAAA,IAAA,CAAK,KAAA,CAAM,gBAAA,EAAkB,SAAA,EAAW,eAAe,CAAA;AAAA,IACzD;AACA,IAAA,OAAO,gBAAA;AAAA,EACT;AAAA,EAEQ,eAAe,aAAA,EAAyB;AAC9C,IAAA,IAAI,SAAA,CAAU,aAAA,CAAc,OAAO,CAAA,EAAG;AACpC,MAAA,IAAA,CAAK,OAAA,CAAQ,eAAe,SAAS,CAAA;AAAA,IACvC;AACA,IAAA,OAAO,aAAA;AAAA,EACT;AAAA,EAEQ,kBAAkB,aAAA,EAAyB;AACjD,IAAA,IAAI,CAAC,SAAA,CAAU,aAAA,CAAc,OAAA,CAAQ,SAAA,CAAU,OAAO,CAAA,EAAG;AACvD,MAAA,IAAA,CAAK,KAAA,CAAM,aAAA,CAAc,OAAA,CAAQ,SAAA,EAAW,WAAW,eAAe,CAAA;AAAA,IACxE;AACA,IAAA,IAAI,CAAC,SAAA,CAAU,aAAA,CAAc,OAAA,CAAQ,SAAA,CAAU,OAAO,CAAA,EAAG;AACvD,MAAA,IAAA,CAAK,KAAA,CAAM,aAAA,CAAc,OAAA,CAAQ,SAAA,EAAW,WAAW,eAAe,CAAA;AAAA,IACxE;AACA,IAAA,IAAI,CAAC,SAAA,CAAU,aAAA,CAAc,OAAA,CAAQ,SAAA,CAAU,GAAG,CAAA,EAAG;AACnD,MAAA,IAAA,CAAK,KAAA,CAAM,cAAc,OAAA,CAAQ,SAAA,EAAW,OAAO,WAAA,CAAY,KAAA,EAAO,YAAA,CAAa,GAAG,CAAC,CAAA;AAAA,IACzF;AACA,IAAA,IAAI,CAAC,SAAA,CAAU,aAAA,CAAc,OAAA,CAAQ,SAAA,CAAU,IAAI,CAAA,EAAG;AACpD,MAAA,IAAA,CAAK,KAAA,CAAM,cAAc,OAAA,CAAQ,SAAA,EAAW,QAAQ,WAAA,CAAY,IAAA,EAAM,YAAA,CAAa,IAAI,CAAC,CAAA;AAAA,IAC1F;AACA,IAAA,IAAI,CAAC,SAAA,CAAU,aAAA,CAAc,OAAA,CAAQ,SAAA,CAAU,MAAM,CAAA,EAAG;AACtD,MAAA,IAAA,CAAK,KAAA,CAAM,cAAc,OAAA,CAAQ,SAAA,EAAW,UAAU,WAAA,CAAY,IAAA,EAAM,YAAA,CAAa,MAAM,CAAC,CAAA;AAAA,IAC9F;AACA,IAAA,IAAI,CAAC,SAAA,CAAU,aAAA,CAAc,OAAA,CAAQ,SAAA,CAAU,MAAM,CAAA,EAAG;AACtD,MAAA,IAAA,CAAK,KAAA,CAAM,cAAc,OAAA,CAAQ,SAAA,EAAW,UAAU,cAAA,CAAe,KAAA,EAAO,YAAA,CAAa,MAAM,CAAC,CAAA;AAAA,IAClG;AACA,IAAA,IAAI,CAAC,SAAA,CAAU,aAAA,CAAc,OAAA,CAAQ,SAAA,CAAU,OAAO,CAAA,EAAG;AACvD,MAAA,IAAA,CAAK,KAAA,CAAM,cAAc,OAAA,CAAQ,SAAA,EAAW,WAAW,cAAA,CAAe,IAAA,EAAM,YAAA,CAAa,OAAO,CAAC,CAAA;AAAA,IACnG;AACA,IAAA,IAAI,CAAC,SAAA,CAAU,aAAA,CAAc,OAAA,CAAQ,SAAA,CAAU,IAAI,CAAA,EAAG;AACpD,MAAA,IAAA,CAAK,KAAA,CAAM,aAAA,CAAc,OAAA,CAAQ,SAAA,EAAW,QAAQ,mBAAmB,CAAA;AAAA,IACzE;AACA,IAAA,IAAI,CAAC,SAAA,CAAU,aAAA,CAAc,cAAA,CAAe,SAAA,CAAU,OAAO,CAAA,EAAG;AAC9D,MAAA,IAAA,CAAK,KAAA,CAAM,aAAA,CAAc,cAAA,CAAe,SAAA,EAAW,WAAW,wBAAwB,CAAA;AAAA,IACxF;AACA,IAAA,OAAO,aAAA;AAAA,EACT;AAAA,EAEQ,oBAAoB,aAAA,EAAyB;AACnD,IAAA,IAAI,SAAA,CAAU,aAAA,CAAc,OAAA,CAAQ,SAAA,CAAU,OAAO,CAAA,EAAG;AACtD,MAAA,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,OAAA,CAAQ,SAAA,EAAW,SAAS,CAAA;AAAA,IACzD;AACA,IAAA,IAAI,SAAA,CAAU,aAAA,CAAc,OAAA,CAAQ,SAAA,CAAU,OAAO,CAAA,EAAG;AACtD,MAAA,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,OAAA,CAAQ,SAAA,EAAW,SAAS,CAAA;AAAA,IACzD;AACA,IAAA,IAAI,SAAA,CAAU,aAAA,CAAc,OAAA,CAAQ,SAAA,CAAU,GAAG,CAAA,EAAG;AAClD,MAAA,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,OAAA,CAAQ,SAAA,EAAW,KAAK,CAAA;AAAA,IACrD;AACA,IAAA,IAAI,SAAA,CAAU,aAAA,CAAc,OAAA,CAAQ,SAAA,CAAU,IAAI,CAAA,EAAG;AACnD,MAAA,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,OAAA,CAAQ,SAAA,EAAW,MAAM,CAAA;AAAA,IACtD;AACA,IAAA,IAAI,SAAA,CAAU,aAAA,CAAc,OAAA,CAAQ,SAAA,CAAU,MAAM,CAAA,EAAG;AACrD,MAAA,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,OAAA,CAAQ,SAAA,EAAW,QAAQ,CAAA;AAAA,IACxD;AACA,IAAA,IAAI,SAAA,CAAU,aAAA,CAAc,OAAA,CAAQ,SAAA,CAAU,MAAM,CAAA,EAAG;AACrD,MAAA,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,OAAA,CAAQ,SAAA,EAAW,QAAQ,CAAA;AAAA,IACxD;AACA,IAAA,IAAI,SAAA,CAAU,aAAA,CAAc,OAAA,CAAQ,SAAA,CAAU,OAAO,CAAA,EAAG;AACtD,MAAA,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,OAAA,CAAQ,SAAA,EAAW,SAAS,CAAA;AAAA,IACzD;AACA,IAAA,IAAI,SAAA,CAAU,aAAA,CAAc,OAAA,CAAQ,SAAA,CAAU,IAAI,CAAA,EAAG;AACnD,MAAA,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,OAAA,CAAQ,SAAA,EAAW,MAAM,CAAA;AAAA,IACtD;AACA,IAAA,IAAI,SAAA,CAAU,aAAA,CAAc,cAAA,CAAe,SAAA,CAAU,OAAO,CAAA,EAAG;AAC7D,MAAA,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,cAAA,CAAe,SAAA,EAAW,SAAS,CAAA;AAAA,IAChE;AACA,IAAA,OAAO,aAAA;AAAA,EACT;AACF;;;;"}