@sentry/node 10.21.0 → 10.23.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.
- package/build/cjs/index.js +10 -7
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/integrations/node-fetch.js +2 -0
- package/build/cjs/integrations/node-fetch.js.map +1 -1
- package/build/cjs/integrations/tracing/firebase/firebase.js +18 -0
- package/build/cjs/integrations/tracing/firebase/firebase.js.map +1 -1
- package/build/cjs/integrations/tracing/firebase/otel/firebaseInstrumentation.js +3 -0
- package/build/cjs/integrations/tracing/firebase/otel/firebaseInstrumentation.js.map +1 -1
- package/build/cjs/integrations/tracing/firebase/otel/patches/functions.js +265 -0
- package/build/cjs/integrations/tracing/firebase/otel/patches/functions.js.map +1 -0
- package/build/cjs/integrations/tracing/index.js +3 -0
- package/build/cjs/integrations/tracing/index.js.map +1 -1
- package/build/cjs/integrations/tracing/langchain/index.js +112 -0
- package/build/cjs/integrations/tracing/langchain/index.js.map +1 -0
- package/build/cjs/integrations/tracing/langchain/instrumentation.js +201 -0
- package/build/cjs/integrations/tracing/langchain/instrumentation.js.map +1 -0
- package/build/cjs/integrations/tracing/postgresjs.js +1 -1
- package/build/cjs/integrations/tracing/postgresjs.js.map +1 -1
- package/build/esm/index.js +2 -1
- package/build/esm/index.js.map +1 -1
- package/build/esm/integrations/node-fetch.js +2 -0
- package/build/esm/integrations/node-fetch.js.map +1 -1
- package/build/esm/integrations/tracing/firebase/firebase.js +19 -1
- package/build/esm/integrations/tracing/firebase/firebase.js.map +1 -1
- package/build/esm/integrations/tracing/firebase/otel/firebaseInstrumentation.js +3 -0
- package/build/esm/integrations/tracing/firebase/otel/firebaseInstrumentation.js.map +1 -1
- package/build/esm/integrations/tracing/firebase/otel/patches/functions.js +262 -0
- package/build/esm/integrations/tracing/firebase/otel/patches/functions.js.map +1 -0
- package/build/esm/integrations/tracing/index.js +3 -0
- package/build/esm/integrations/tracing/index.js.map +1 -1
- package/build/esm/integrations/tracing/langchain/index.js +109 -0
- package/build/esm/integrations/tracing/langchain/index.js.map +1 -0
- package/build/esm/integrations/tracing/langchain/instrumentation.js +199 -0
- package/build/esm/integrations/tracing/langchain/instrumentation.js.map +1 -0
- package/build/esm/integrations/tracing/postgresjs.js +1 -1
- package/build/esm/integrations/tracing/postgresjs.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/types/index.d.ts +2 -1
- package/build/types/index.d.ts.map +1 -1
- package/build/types/integrations/node-fetch.d.ts +2 -1
- package/build/types/integrations/node-fetch.d.ts.map +1 -1
- package/build/types/integrations/tracing/firebase/firebase.d.ts.map +1 -1
- package/build/types/integrations/tracing/firebase/otel/firebaseInstrumentation.d.ts.map +1 -1
- package/build/types/integrations/tracing/firebase/otel/patches/functions.d.ts +23 -0
- package/build/types/integrations/tracing/firebase/otel/patches/functions.d.ts.map +1 -0
- package/build/types/integrations/tracing/firebase/otel/types.d.ts +34 -0
- package/build/types/integrations/tracing/firebase/otel/types.d.ts.map +1 -1
- package/build/types/integrations/tracing/index.d.ts.map +1 -1
- package/build/types/integrations/tracing/langchain/index.d.ts +93 -0
- package/build/types/integrations/tracing/langchain/index.d.ts.map +1 -0
- package/build/types/integrations/tracing/langchain/instrumentation.d.ts +29 -0
- package/build/types/integrations/tracing/langchain/instrumentation.d.ts.map +1 -0
- package/build/types-ts3.8/index.d.ts +2 -1
- package/build/types-ts3.8/integrations/node-fetch.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/firebase/otel/patches/functions.d.ts +23 -0
- package/build/types-ts3.8/integrations/tracing/firebase/otel/types.d.ts +34 -0
- package/build/types-ts3.8/integrations/tracing/langchain/index.d.ts +93 -0
- package/build/types-ts3.8/integrations/tracing/langchain/instrumentation.d.ts +29 -0
- package/package.json +4 -4
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { SpanKind, context, trace, diag } from '@opentelemetry/api';
|
|
2
|
+
import { InstrumentationNodeModuleDefinition, InstrumentationNodeModuleFile, isWrapped, safeExecuteInTheMiddle } from '@opentelemetry/instrumentation';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Patches Firebase Functions v2 to add OpenTelemetry instrumentation
|
|
6
|
+
* @param tracer - Opentelemetry Tracer
|
|
7
|
+
* @param functionsSupportedVersions - supported versions of firebase-functions
|
|
8
|
+
* @param wrap - reference to native instrumentation wrap function
|
|
9
|
+
* @param unwrap - reference to native instrumentation unwrap function
|
|
10
|
+
* @param config - Firebase instrumentation config
|
|
11
|
+
*/
|
|
12
|
+
function patchFunctions(
|
|
13
|
+
tracer,
|
|
14
|
+
functionsSupportedVersions,
|
|
15
|
+
wrap,
|
|
16
|
+
unwrap,
|
|
17
|
+
config,
|
|
18
|
+
) {
|
|
19
|
+
let requestHook = () => {};
|
|
20
|
+
let responseHook = () => {};
|
|
21
|
+
const errorHook = config.functions?.errorHook;
|
|
22
|
+
const configRequestHook = config.functions?.requestHook;
|
|
23
|
+
const configResponseHook = config.functions?.responseHook;
|
|
24
|
+
|
|
25
|
+
if (typeof configResponseHook === 'function') {
|
|
26
|
+
responseHook = (span, err) => {
|
|
27
|
+
safeExecuteInTheMiddle(
|
|
28
|
+
() => configResponseHook(span, err),
|
|
29
|
+
error => {
|
|
30
|
+
if (!error) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
diag.error(error?.message);
|
|
34
|
+
},
|
|
35
|
+
true,
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (typeof configRequestHook === 'function') {
|
|
40
|
+
requestHook = (span) => {
|
|
41
|
+
safeExecuteInTheMiddle(
|
|
42
|
+
() => configRequestHook(span),
|
|
43
|
+
error => {
|
|
44
|
+
if (!error) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
diag.error(error?.message);
|
|
48
|
+
},
|
|
49
|
+
true,
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const moduleFunctionsCJS = new InstrumentationNodeModuleDefinition('firebase-functions', functionsSupportedVersions);
|
|
55
|
+
const modulesToInstrument = [
|
|
56
|
+
{ name: 'firebase-functions/lib/v2/providers/https.js', triggerType: 'function' },
|
|
57
|
+
{ name: 'firebase-functions/lib/v2/providers/firestore.js', triggerType: 'firestore' },
|
|
58
|
+
{ name: 'firebase-functions/lib/v2/providers/scheduler.js', triggerType: 'scheduler' },
|
|
59
|
+
{ name: 'firebase-functions/lib/v2/storage.js', triggerType: 'storage' },
|
|
60
|
+
] ;
|
|
61
|
+
|
|
62
|
+
modulesToInstrument.forEach(({ name, triggerType }) => {
|
|
63
|
+
moduleFunctionsCJS.files.push(
|
|
64
|
+
new InstrumentationNodeModuleFile(
|
|
65
|
+
name,
|
|
66
|
+
functionsSupportedVersions,
|
|
67
|
+
moduleExports =>
|
|
68
|
+
wrapCommonFunctions(
|
|
69
|
+
moduleExports,
|
|
70
|
+
wrap,
|
|
71
|
+
unwrap,
|
|
72
|
+
tracer,
|
|
73
|
+
{ requestHook, responseHook, errorHook },
|
|
74
|
+
triggerType,
|
|
75
|
+
),
|
|
76
|
+
moduleExports => unwrapCommonFunctions(moduleExports, unwrap),
|
|
77
|
+
),
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
return moduleFunctionsCJS;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Patches Cloud Functions for Firebase (v2) to add OpenTelemetry instrumentation
|
|
86
|
+
*
|
|
87
|
+
* @param tracer - Opentelemetry Tracer
|
|
88
|
+
* @param functionsConfig - Firebase instrumentation config
|
|
89
|
+
* @param triggerType - Type of trigger
|
|
90
|
+
* @returns A function that patches the function
|
|
91
|
+
*/
|
|
92
|
+
function patchV2Functions(
|
|
93
|
+
tracer,
|
|
94
|
+
functionsConfig,
|
|
95
|
+
triggerType,
|
|
96
|
+
) {
|
|
97
|
+
return function v2FunctionsWrapper(original) {
|
|
98
|
+
return function ( ...args) {
|
|
99
|
+
const handler = typeof args[0] === 'function' ? args[0] : args[1];
|
|
100
|
+
const documentOrOptions = typeof args[0] === 'function' ? undefined : args[0];
|
|
101
|
+
|
|
102
|
+
if (!handler) {
|
|
103
|
+
return original.call(this, ...args);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const wrappedHandler = async function ( ...handlerArgs) {
|
|
107
|
+
const functionName = process.env.FUNCTION_TARGET || process.env.K_SERVICE || 'unknown';
|
|
108
|
+
const span = tracer.startSpan(`firebase.function.${triggerType}`, {
|
|
109
|
+
kind: SpanKind.SERVER,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const attributes = {
|
|
113
|
+
'faas.name': functionName,
|
|
114
|
+
'faas.trigger': triggerType,
|
|
115
|
+
'faas.provider': 'firebase',
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
if (process.env.GCLOUD_PROJECT) {
|
|
119
|
+
attributes['cloud.project_id'] = process.env.GCLOUD_PROJECT;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (process.env.EVENTARC_CLOUD_EVENT_SOURCE) {
|
|
123
|
+
attributes['cloud.event_source'] = process.env.EVENTARC_CLOUD_EVENT_SOURCE;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
span.setAttributes(attributes);
|
|
127
|
+
functionsConfig?.requestHook?.(span);
|
|
128
|
+
|
|
129
|
+
// Can be changed to safeExecuteInTheMiddleAsync once following is merged and released
|
|
130
|
+
// https://github.com/open-telemetry/opentelemetry-js/pull/6032
|
|
131
|
+
return context.with(trace.setSpan(context.active(), span), async () => {
|
|
132
|
+
let error;
|
|
133
|
+
let result;
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
result = await handler.apply(this, handlerArgs);
|
|
137
|
+
} catch (e) {
|
|
138
|
+
error = e ;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
functionsConfig?.responseHook?.(span, error);
|
|
142
|
+
|
|
143
|
+
if (error) {
|
|
144
|
+
span.recordException(error);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
span.end();
|
|
148
|
+
|
|
149
|
+
if (error) {
|
|
150
|
+
await functionsConfig?.errorHook?.(span, error);
|
|
151
|
+
throw error;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return result;
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
if (documentOrOptions) {
|
|
159
|
+
return original.call(this, documentOrOptions, wrappedHandler);
|
|
160
|
+
} else {
|
|
161
|
+
return original.call(this, wrappedHandler);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function wrapCommonFunctions(
|
|
168
|
+
moduleExports,
|
|
169
|
+
wrap,
|
|
170
|
+
unwrap,
|
|
171
|
+
tracer,
|
|
172
|
+
functionsConfig,
|
|
173
|
+
triggerType,
|
|
174
|
+
) {
|
|
175
|
+
unwrapCommonFunctions(moduleExports, unwrap);
|
|
176
|
+
|
|
177
|
+
switch (triggerType) {
|
|
178
|
+
case 'function':
|
|
179
|
+
wrap(moduleExports, 'onRequest', patchV2Functions(tracer, functionsConfig, 'http.request'));
|
|
180
|
+
wrap(moduleExports, 'onCall', patchV2Functions(tracer, functionsConfig, 'http.call'));
|
|
181
|
+
break;
|
|
182
|
+
|
|
183
|
+
case 'firestore':
|
|
184
|
+
wrap(moduleExports, 'onDocumentCreated', patchV2Functions(tracer, functionsConfig, 'firestore.document.created'));
|
|
185
|
+
wrap(moduleExports, 'onDocumentUpdated', patchV2Functions(tracer, functionsConfig, 'firestore.document.updated'));
|
|
186
|
+
wrap(moduleExports, 'onDocumentDeleted', patchV2Functions(tracer, functionsConfig, 'firestore.document.deleted'));
|
|
187
|
+
wrap(moduleExports, 'onDocumentWritten', patchV2Functions(tracer, functionsConfig, 'firestore.document.written'));
|
|
188
|
+
wrap(
|
|
189
|
+
moduleExports,
|
|
190
|
+
'onDocumentCreatedWithAuthContext',
|
|
191
|
+
patchV2Functions(tracer, functionsConfig, 'firestore.document.created'),
|
|
192
|
+
);
|
|
193
|
+
wrap(
|
|
194
|
+
moduleExports,
|
|
195
|
+
'onDocumentUpdatedWithAuthContext',
|
|
196
|
+
patchV2Functions(tracer, functionsConfig, 'firestore.document.updated'),
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
wrap(
|
|
200
|
+
moduleExports,
|
|
201
|
+
'onDocumentDeletedWithAuthContext',
|
|
202
|
+
patchV2Functions(tracer, functionsConfig, 'firestore.document.deleted'),
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
wrap(
|
|
206
|
+
moduleExports,
|
|
207
|
+
'onDocumentWrittenWithAuthContext',
|
|
208
|
+
patchV2Functions(tracer, functionsConfig, 'firestore.document.written'),
|
|
209
|
+
);
|
|
210
|
+
break;
|
|
211
|
+
|
|
212
|
+
case 'scheduler':
|
|
213
|
+
wrap(moduleExports, 'onSchedule', patchV2Functions(tracer, functionsConfig, 'scheduler.scheduled'));
|
|
214
|
+
break;
|
|
215
|
+
|
|
216
|
+
case 'storage':
|
|
217
|
+
wrap(moduleExports, 'onObjectFinalized', patchV2Functions(tracer, functionsConfig, 'storage.object.finalized'));
|
|
218
|
+
wrap(moduleExports, 'onObjectArchived', patchV2Functions(tracer, functionsConfig, 'storage.object.archived'));
|
|
219
|
+
wrap(moduleExports, 'onObjectDeleted', patchV2Functions(tracer, functionsConfig, 'storage.object.deleted'));
|
|
220
|
+
wrap(
|
|
221
|
+
moduleExports,
|
|
222
|
+
'onObjectMetadataUpdated',
|
|
223
|
+
patchV2Functions(tracer, functionsConfig, 'storage.object.metadataUpdated'),
|
|
224
|
+
);
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return moduleExports;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function unwrapCommonFunctions(
|
|
232
|
+
moduleExports,
|
|
233
|
+
unwrap,
|
|
234
|
+
) {
|
|
235
|
+
const methods = [
|
|
236
|
+
'onSchedule',
|
|
237
|
+
'onRequest',
|
|
238
|
+
'onCall',
|
|
239
|
+
'onObjectFinalized',
|
|
240
|
+
'onObjectArchived',
|
|
241
|
+
'onObjectDeleted',
|
|
242
|
+
'onObjectMetadataUpdated',
|
|
243
|
+
'onDocumentCreated',
|
|
244
|
+
'onDocumentUpdated',
|
|
245
|
+
'onDocumentDeleted',
|
|
246
|
+
'onDocumentWritten',
|
|
247
|
+
'onDocumentCreatedWithAuthContext',
|
|
248
|
+
'onDocumentUpdatedWithAuthContext',
|
|
249
|
+
'onDocumentDeletedWithAuthContext',
|
|
250
|
+
'onDocumentWrittenWithAuthContext',
|
|
251
|
+
];
|
|
252
|
+
|
|
253
|
+
for (const method of methods) {
|
|
254
|
+
if (isWrapped(moduleExports[method])) {
|
|
255
|
+
unwrap(moduleExports, method);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return moduleExports;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export { patchFunctions, patchV2Functions };
|
|
262
|
+
//# sourceMappingURL=functions.js.map
|
|
@@ -0,0 +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 {\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n isWrapped,\n safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\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":[],"mappings":";;;AAoBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,cAAc;AAC9B,EAAE,MAAM;AACR,EAAE,0BAA0B;AAC5B,EAAE,IAAI;AACN,EAAE,MAAM;AACR,EAAE,MAAM;AACR,EAAuC;AACvC,EAAE,IAAI,WAAW,GAAgB,MAAM,EAAE;AACzC,EAAE,IAAI,YAAY,GAAiB,MAAM,EAAE;AAC3C,EAAE,MAAM,SAAA,GAAY,MAAM,CAAC,SAAS,EAAE,SAAS;AAC/C,EAAE,MAAM,iBAAA,GAAoB,MAAM,CAAC,SAAS,EAAE,WAAW;AACzD,EAAE,MAAM,kBAAA,GAAqB,MAAM,CAAC,SAAS,EAAE,YAAY;;AAE3D,EAAE,IAAI,OAAO,kBAAA,KAAuB,UAAU,EAAE;AAChD,IAAI,eAAe,CAAC,IAAI,EAAQ,GAAG,KAAc;AACjD,MAAM,sBAAsB;AAC5B,QAAQ,MAAM,kBAAkB,CAAC,IAAI,EAAE,GAAG,CAAC;AAC3C,QAAQ,SAAS;AACjB,UAAU,IAAI,CAAC,KAAK,EAAE;AACtB,YAAY;AACZ;AACA,UAAU,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC;AACpC,SAAS;AACT,QAAQ,IAAI;AACZ,OAAO;AACP,KAAK;AACL;AACA,EAAE,IAAI,OAAO,iBAAA,KAAsB,UAAU,EAAE;AAC/C,IAAI,WAAA,GAAc,CAAC,IAAI,KAAW;AAClC,MAAM,sBAAsB;AAC5B,QAAQ,MAAM,iBAAiB,CAAC,IAAI,CAAC;AACrC,QAAQ,SAAS;AACjB,UAAU,IAAI,CAAC,KAAK,EAAE;AACtB,YAAY;AACZ;AACA,UAAU,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC;AACpC,SAAS;AACT,QAAQ,IAAI;AACZ,OAAO;AACP,KAAK;AACL;;AAEA,EAAE,MAAM,qBAAqB,IAAI,mCAAmC,CAAC,oBAAoB,EAAE,0BAA0B,CAAC;AACtH,EAAE,MAAM,sBAAsB;AAC9B,IAAI,EAAE,IAAI,EAAE,8CAA8C,EAAE,WAAW,EAAE,YAAY;AACrF,IAAI,EAAE,IAAI,EAAE,kDAAkD,EAAE,WAAW,EAAE,aAAa;AAC1F,IAAI,EAAE,IAAI,EAAE,kDAAkD,EAAE,WAAW,EAAE,aAAa;AAC1F,IAAI,EAAE,IAAI,EAAE,sCAAsC,EAAE,WAAW,EAAE,WAAW;AAC5E,GAAE;;AAEF,EAAE,mBAAmB,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,WAAA,EAAa,KAAK;AACzD,IAAI,kBAAkB,CAAC,KAAK,CAAC,IAAI;AACjC,MAAM,IAAI,6BAA6B;AACvC,QAAQ,IAAI;AACZ,QAAQ,0BAA0B;AAClC,QAAQ,aAAA;AACR,UAAU,mBAAmB;AAC7B,YAAY,aAAa;AACzB,YAAY,IAAI;AAChB,YAAY,MAAM;AAClB,YAAY,MAAM;AAClB,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW;AACpD,YAAY,WAAW;AACvB,WAAW;AACX,QAAQ,iBAAiB,qBAAqB,CAAC,aAAa,EAAE,MAAM,CAAC;AACrE,OAAO;AACP,KAAK;AACL,GAAG,CAAC;;AAEJ,EAAE,OAAO,kBAAkB;AAC3B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB;AAChC,EAAE,MAAM;AACR,EAAE,eAAe;AACjB,EAAE,WAAW;AACb,EAAwE;AACxE,EAAE,OAAO,SAAS,kBAAkB,CAAC,QAAQ,EAA0D;AACvG,IAAI,OAAO,WAAyC,GAAG,IAAI,EAA0C;AACrG,MAAM,MAAM,OAAA,GAAU,OAAO,IAAI,CAAC,CAAC,CAAA,KAAM,aAAa,IAAI,CAAC,CAAC,CAAA,GAAI,IAAI,CAAC,CAAC,CAAC;AACvE,MAAM,MAAM,iBAAA,GAAoB,OAAO,IAAI,CAAC,CAAC,CAAA,KAAM,UAAA,GAAa,SAAA,GAAY,IAAI,CAAC,CAAC,CAAC;;AAEnF,MAAM,IAAI,CAAC,OAAO,EAAE;AACpB,QAAQ,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC;AAC3C;;AAEA,MAAM,MAAM,cAAA,GAAiB,iBAA+B,GAAG,WAAW,EAA+B;AACzG,QAAQ,MAAM,YAAA,GAAe,OAAO,CAAC,GAAG,CAAC,eAAA,IAAmB,OAAO,CAAC,GAAG,CAAC,SAAA,IAAa,SAAS;AAC9F,QAAQ,MAAM,IAAA,GAAO,MAAM,CAAC,SAAS,CAAC,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAA,EAAA;AACA,UAAA,IAAA,EAAA,QAAA,CAAA,MAAA;AACA,SAAA,CAAA;;AAEA,QAAA,MAAA,UAAA,GAAA;AACA,UAAA,WAAA,EAAA,YAAA;AACA,UAAA,cAAA,EAAA,WAAA;AACA,UAAA,eAAA,EAAA,UAAA;AACA,SAAA;;AAEA,QAAA,IAAA,OAAA,CAAA,GAAA,CAAA,cAAA,EAAA;AACA,UAAA,UAAA,CAAA,kBAAA,CAAA,GAAA,OAAA,CAAA,GAAA,CAAA,cAAA;AACA;;AAEA,QAAA,IAAA,OAAA,CAAA,GAAA,CAAA,2BAAA,EAAA;AACA,UAAA,UAAA,CAAA,oBAAA,CAAA,GAAA,OAAA,CAAA,GAAA,CAAA,2BAAA;AACA;;AAEA,QAAA,IAAA,CAAA,aAAA,CAAA,UAAA,CAAA;AACA,QAAA,eAAA,EAAA,WAAA,GAAA,IAAA,CAAA;;AAEA;AACA;AACA,QAAA,OAAA,OAAA,CAAA,IAAA,CAAA,KAAA,CAAA,OAAA,CAAA,OAAA,CAAA,MAAA,EAAA,EAAA,IAAA,CAAA,EAAA,YAAA;AACA,UAAA,IAAA,KAAA;AACA,UAAA,IAAA,MAAA;;AAEA,UAAA,IAAA;AACA,YAAA,MAAA,GAAA,MAAA,OAAA,CAAA,KAAA,CAAA,IAAA,EAAA,WAAA,CAAA;AACA,WAAA,CAAA,OAAA,CAAA,EAAA;AACA,YAAA,KAAA,GAAA,CAAA;AACA;;AAEA,UAAA,eAAA,EAAA,YAAA,GAAA,IAAA,EAAA,KAAA,CAAA;;AAEA,UAAA,IAAA,KAAA,EAAA;AACA,YAAA,IAAA,CAAA,eAAA,CAAA,KAAA,CAAA;AACA;;AAEA,UAAA,IAAA,CAAA,GAAA,EAAA;;AAEA,UAAA,IAAA,KAAA,EAAA;AACA,YAAA,MAAA,eAAA,EAAA,SAAA,GAAA,IAAA,EAAA,KAAA,CAAA;AACA,YAAA,MAAA,KAAA;AACA;;AAEA,UAAA,OAAA,MAAA;AACA,SAAA,CAAA;AACA,OAAA;;AAEA,MAAA,IAAA,iBAAA,EAAA;AACA,QAAA,OAAA,QAAA,CAAA,IAAA,CAAA,IAAA,EAAA,iBAAA,EAAA,cAAA,CAAA;AACA,OAAA,MAAA;AACA,QAAA,OAAA,QAAA,CAAA,IAAA,CAAA,IAAA,EAAA,cAAA,CAAA;AACA;AACA,KAAA;AACA,GAAA;AACA;;AAEA,SAAA,mBAAA;AACA,EAAA,aAAA;AACA,EAAA,IAAA;AACA,EAAA,MAAA;AACA,EAAA,MAAA;AACA,EAAA,eAAA;AACA,EAAA,WAAA;AACA,EAAA;AACA,EAAA,qBAAA,CAAA,aAAA,EAAA,MAAA,CAAA;;AAEA,EAAA,QAAA,WAAA;AACA,IAAA,KAAA,UAAA;AACA,MAAA,IAAA,CAAA,aAAA,EAAA,WAAA,EAAA,gBAAA,CAAA,MAAA,EAAA,eAAA,EAAA,cAAA,CAAA,CAAA;AACA,MAAA,IAAA,CAAA,aAAA,EAAA,QAAA,EAAA,gBAAA,CAAA,MAAA,EAAA,eAAA,EAAA,WAAA,CAAA,CAAA;AACA,MAAA;;AAEA,IAAA,KAAA,WAAA;AACA,MAAA,IAAA,CAAA,aAAA,EAAA,mBAAA,EAAA,gBAAA,CAAA,MAAA,EAAA,eAAA,EAAA,4BAAA,CAAA,CAAA;AACA,MAAA,IAAA,CAAA,aAAA,EAAA,mBAAA,EAAA,gBAAA,CAAA,MAAA,EAAA,eAAA,EAAA,4BAAA,CAAA,CAAA;AACA,MAAA,IAAA,CAAA,aAAA,EAAA,mBAAA,EAAA,gBAAA,CAAA,MAAA,EAAA,eAAA,EAAA,4BAAA,CAAA,CAAA;AACA,MAAA,IAAA,CAAA,aAAA,EAAA,mBAAA,EAAA,gBAAA,CAAA,MAAA,EAAA,eAAA,EAAA,4BAAA,CAAA,CAAA;AACA,MAAA,IAAA;AACA,QAAA,aAAA;AACA,QAAA,kCAAA;AACA,QAAA,gBAAA,CAAA,MAAA,EAAA,eAAA,EAAA,4BAAA,CAAA;AACA,OAAA;AACA,MAAA,IAAA;AACA,QAAA,aAAA;AACA,QAAA,kCAAA;AACA,QAAA,gBAAA,CAAA,MAAA,EAAA,eAAA,EAAA,4BAAA,CAAA;AACA,OAAA;;AAEA,MAAA,IAAA;AACA,QAAA,aAAA;AACA,QAAA,kCAAA;AACA,QAAA,gBAAA,CAAA,MAAA,EAAA,eAAA,EAAA,4BAAA,CAAA;AACA,OAAA;;AAEA,MAAA,IAAA;AACA,QAAA,aAAA;AACA,QAAA,kCAAA;AACA,QAAA,gBAAA,CAAA,MAAA,EAAA,eAAA,EAAA,4BAAA,CAAA;AACA,OAAA;AACA,MAAA;;AAEA,IAAA,KAAA,WAAA;AACA,MAAA,IAAA,CAAA,aAAA,EAAA,YAAA,EAAA,gBAAA,CAAA,MAAA,EAAA,eAAA,EAAA,qBAAA,CAAA,CAAA;AACA,MAAA;;AAEA,IAAA,KAAA,SAAA;AACA,MAAA,IAAA,CAAA,aAAA,EAAA,mBAAA,EAAA,gBAAA,CAAA,MAAA,EAAA,eAAA,EAAA,0BAAA,CAAA,CAAA;AACA,MAAA,IAAA,CAAA,aAAA,EAAA,kBAAA,EAAA,gBAAA,CAAA,MAAA,EAAA,eAAA,EAAA,yBAAA,CAAA,CAAA;AACA,MAAA,IAAA,CAAA,aAAA,EAAA,iBAAA,EAAA,gBAAA,CAAA,MAAA,EAAA,eAAA,EAAA,wBAAA,CAAA,CAAA;AACA,MAAA,IAAA;AACA,QAAA,aAAA;AACA,QAAA,yBAAA;AACA,QAAA,gBAAA,CAAA,MAAA,EAAA,eAAA,EAAA,gCAAA,CAAA;AACA,OAAA;AACA,MAAA;AACA;;AAEA,EAAA,OAAA,aAAA;AACA;;AAEA,SAAA,qBAAA;AACA,EAAA,aAAA;AACA,EAAA,MAAA;AACA,EAAA;AACA,EAAA,MAAA,OAAA,GAAA;AACA,IAAA,YAAA;AACA,IAAA,WAAA;AACA,IAAA,QAAA;AACA,IAAA,mBAAA;AACA,IAAA,kBAAA;AACA,IAAA,iBAAA;AACA,IAAA,yBAAA;AACA,IAAA,mBAAA;AACA,IAAA,mBAAA;AACA,IAAA,mBAAA;AACA,IAAA,mBAAA;AACA,IAAA,kCAAA;AACA,IAAA,kCAAA;AACA,IAAA,kCAAA;AACA,IAAA,kCAAA;AACA,GAAA;;AAEA,EAAA,KAAA,MAAA,MAAA,IAAA,OAAA,EAAA;AACA,IAAA,IAAA,SAAA,CAAA,aAAA,CAAA,MAAA,CAAA,CAAA,EAAA;AACA,MAAA,MAAA,CAAA,aAAA,EAAA,MAAA,CAAA;AACA;AACA;AACA,EAAA,OAAA,aAAA;AACA;;;;"}
|
|
@@ -12,6 +12,7 @@ import { instrumentHapi, hapiIntegration } from './hapi/index.js';
|
|
|
12
12
|
import { instrumentHono, honoIntegration } from './hono/index.js';
|
|
13
13
|
import { instrumentKafka, kafkaIntegration } from './kafka.js';
|
|
14
14
|
import { instrumentKoa, koaIntegration } from './koa.js';
|
|
15
|
+
import { instrumentLangChain, langChainIntegration } from './langchain/index.js';
|
|
15
16
|
import { instrumentLruMemoizer, lruMemoizerIntegration } from './lrumemoizer.js';
|
|
16
17
|
import { instrumentMongo, mongoIntegration } from './mongo.js';
|
|
17
18
|
import { instrumentMongoose, mongooseIntegration } from './mongoose.js';
|
|
@@ -55,6 +56,7 @@ function getAutoPerformanceIntegrations() {
|
|
|
55
56
|
firebaseIntegration(),
|
|
56
57
|
anthropicAIIntegration(),
|
|
57
58
|
googleGenAIIntegration(),
|
|
59
|
+
langChainIntegration(),
|
|
58
60
|
];
|
|
59
61
|
}
|
|
60
62
|
|
|
@@ -92,6 +94,7 @@ function getOpenTelemetryInstrumentationToPreload() {
|
|
|
92
94
|
instrumentFirebase,
|
|
93
95
|
instrumentAnthropicAi,
|
|
94
96
|
instrumentGoogleGenAI,
|
|
97
|
+
instrumentLangChain,
|
|
95
98
|
];
|
|
96
99
|
}
|
|
97
100
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/integrations/tracing/index.ts"],"sourcesContent":["import type { Integration } from '@sentry/core';\nimport { instrumentOtelHttp, instrumentSentryHttp } from '../http';\nimport { amqplibIntegration, instrumentAmqplib } from './amqplib';\nimport { anthropicAIIntegration, instrumentAnthropicAi } from './anthropic-ai';\nimport { connectIntegration, instrumentConnect } from './connect';\nimport { expressIntegration, instrumentExpress } from './express';\nimport { fastifyIntegration, instrumentFastify, instrumentFastifyV3 } from './fastify';\nimport { firebaseIntegration, instrumentFirebase } from './firebase';\nimport { genericPoolIntegration, instrumentGenericPool } from './genericPool';\nimport { googleGenAIIntegration, instrumentGoogleGenAI } from './google-genai';\nimport { graphqlIntegration, instrumentGraphql } from './graphql';\nimport { hapiIntegration, instrumentHapi } from './hapi';\nimport { honoIntegration, instrumentHono } from './hono';\nimport { instrumentKafka, kafkaIntegration } from './kafka';\nimport { instrumentKoa, koaIntegration } from './koa';\nimport { instrumentLruMemoizer, lruMemoizerIntegration } from './lrumemoizer';\nimport { instrumentMongo, mongoIntegration } from './mongo';\nimport { instrumentMongoose, mongooseIntegration } from './mongoose';\nimport { instrumentMysql, mysqlIntegration } from './mysql';\nimport { instrumentMysql2, mysql2Integration } from './mysql2';\nimport { instrumentOpenAi, openAIIntegration } from './openai';\nimport { instrumentPostgres, postgresIntegration } from './postgres';\nimport { instrumentPostgresJs, postgresJsIntegration } from './postgresjs';\nimport { prismaIntegration } from './prisma';\nimport { instrumentRedis, redisIntegration } from './redis';\nimport { instrumentTedious, tediousIntegration } from './tedious';\nimport { instrumentVercelAi, vercelAIIntegration } from './vercelai';\n\n/**\n * With OTEL, all performance integrations will be added, as OTEL only initializes them when the patched package is actually required.\n */\nexport function getAutoPerformanceIntegrations(): Integration[] {\n return [\n expressIntegration(),\n fastifyIntegration(),\n graphqlIntegration(),\n honoIntegration(),\n mongoIntegration(),\n mongooseIntegration(),\n mysqlIntegration(),\n mysql2Integration(),\n redisIntegration(),\n postgresIntegration(),\n prismaIntegration(),\n hapiIntegration(),\n koaIntegration(),\n connectIntegration(),\n tediousIntegration(),\n genericPoolIntegration(),\n kafkaIntegration(),\n amqplibIntegration(),\n lruMemoizerIntegration(),\n vercelAIIntegration(),\n openAIIntegration(),\n postgresJsIntegration(),\n firebaseIntegration(),\n anthropicAIIntegration(),\n googleGenAIIntegration(),\n ];\n}\n\n/**\n * Get a list of methods to instrument OTEL, when preload instrumentation.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getOpenTelemetryInstrumentationToPreload(): (((options?: any) => void) & { id: string })[] {\n return [\n instrumentSentryHttp,\n instrumentOtelHttp,\n instrumentExpress,\n instrumentConnect,\n instrumentFastify,\n instrumentFastifyV3,\n instrumentHapi,\n instrumentHono,\n instrumentKafka,\n instrumentKoa,\n instrumentLruMemoizer,\n instrumentMongo,\n instrumentMongoose,\n instrumentMysql,\n instrumentMysql2,\n instrumentPostgres,\n instrumentHapi,\n instrumentGraphql,\n instrumentRedis,\n instrumentTedious,\n instrumentGenericPool,\n instrumentAmqplib,\n instrumentVercelAi,\n instrumentOpenAi,\n instrumentPostgresJs,\n instrumentFirebase,\n instrumentAnthropicAi,\n instrumentGoogleGenAI,\n ];\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/integrations/tracing/index.ts"],"sourcesContent":["import type { Integration } from '@sentry/core';\nimport { instrumentOtelHttp, instrumentSentryHttp } from '../http';\nimport { amqplibIntegration, instrumentAmqplib } from './amqplib';\nimport { anthropicAIIntegration, instrumentAnthropicAi } from './anthropic-ai';\nimport { connectIntegration, instrumentConnect } from './connect';\nimport { expressIntegration, instrumentExpress } from './express';\nimport { fastifyIntegration, instrumentFastify, instrumentFastifyV3 } from './fastify';\nimport { firebaseIntegration, instrumentFirebase } from './firebase';\nimport { genericPoolIntegration, instrumentGenericPool } from './genericPool';\nimport { googleGenAIIntegration, instrumentGoogleGenAI } from './google-genai';\nimport { graphqlIntegration, instrumentGraphql } from './graphql';\nimport { hapiIntegration, instrumentHapi } from './hapi';\nimport { honoIntegration, instrumentHono } from './hono';\nimport { instrumentKafka, kafkaIntegration } from './kafka';\nimport { instrumentKoa, koaIntegration } from './koa';\nimport { instrumentLangChain, langChainIntegration } from './langchain';\nimport { instrumentLruMemoizer, lruMemoizerIntegration } from './lrumemoizer';\nimport { instrumentMongo, mongoIntegration } from './mongo';\nimport { instrumentMongoose, mongooseIntegration } from './mongoose';\nimport { instrumentMysql, mysqlIntegration } from './mysql';\nimport { instrumentMysql2, mysql2Integration } from './mysql2';\nimport { instrumentOpenAi, openAIIntegration } from './openai';\nimport { instrumentPostgres, postgresIntegration } from './postgres';\nimport { instrumentPostgresJs, postgresJsIntegration } from './postgresjs';\nimport { prismaIntegration } from './prisma';\nimport { instrumentRedis, redisIntegration } from './redis';\nimport { instrumentTedious, tediousIntegration } from './tedious';\nimport { instrumentVercelAi, vercelAIIntegration } from './vercelai';\n\n/**\n * With OTEL, all performance integrations will be added, as OTEL only initializes them when the patched package is actually required.\n */\nexport function getAutoPerformanceIntegrations(): Integration[] {\n return [\n expressIntegration(),\n fastifyIntegration(),\n graphqlIntegration(),\n honoIntegration(),\n mongoIntegration(),\n mongooseIntegration(),\n mysqlIntegration(),\n mysql2Integration(),\n redisIntegration(),\n postgresIntegration(),\n prismaIntegration(),\n hapiIntegration(),\n koaIntegration(),\n connectIntegration(),\n tediousIntegration(),\n genericPoolIntegration(),\n kafkaIntegration(),\n amqplibIntegration(),\n lruMemoizerIntegration(),\n vercelAIIntegration(),\n openAIIntegration(),\n postgresJsIntegration(),\n firebaseIntegration(),\n anthropicAIIntegration(),\n googleGenAIIntegration(),\n langChainIntegration(),\n ];\n}\n\n/**\n * Get a list of methods to instrument OTEL, when preload instrumentation.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getOpenTelemetryInstrumentationToPreload(): (((options?: any) => void) & { id: string })[] {\n return [\n instrumentSentryHttp,\n instrumentOtelHttp,\n instrumentExpress,\n instrumentConnect,\n instrumentFastify,\n instrumentFastifyV3,\n instrumentHapi,\n instrumentHono,\n instrumentKafka,\n instrumentKoa,\n instrumentLruMemoizer,\n instrumentMongo,\n instrumentMongoose,\n instrumentMysql,\n instrumentMysql2,\n instrumentPostgres,\n instrumentHapi,\n instrumentGraphql,\n instrumentRedis,\n instrumentTedious,\n instrumentGenericPool,\n instrumentAmqplib,\n instrumentVercelAi,\n instrumentOpenAi,\n instrumentPostgresJs,\n instrumentFirebase,\n instrumentAnthropicAi,\n instrumentGoogleGenAI,\n instrumentLangChain,\n ];\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA;AACA;AACA;AACO,SAAS,8BAA8B,GAAkB;AAChE,EAAE,OAAO;AACT,IAAI,kBAAkB,EAAE;AACxB,IAAI,kBAAkB,EAAE;AACxB,IAAI,kBAAkB,EAAE;AACxB,IAAI,eAAe,EAAE;AACrB,IAAI,gBAAgB,EAAE;AACtB,IAAI,mBAAmB,EAAE;AACzB,IAAI,gBAAgB,EAAE;AACtB,IAAI,iBAAiB,EAAE;AACvB,IAAI,gBAAgB,EAAE;AACtB,IAAI,mBAAmB,EAAE;AACzB,IAAI,iBAAiB,EAAE;AACvB,IAAI,eAAe,EAAE;AACrB,IAAI,cAAc,EAAE;AACpB,IAAI,kBAAkB,EAAE;AACxB,IAAI,kBAAkB,EAAE;AACxB,IAAI,sBAAsB,EAAE;AAC5B,IAAI,gBAAgB,EAAE;AACtB,IAAI,kBAAkB,EAAE;AACxB,IAAI,sBAAsB,EAAE;AAC5B,IAAI,mBAAmB,EAAE;AACzB,IAAI,iBAAiB,EAAE;AACvB,IAAI,qBAAqB,EAAE;AAC3B,IAAI,mBAAmB,EAAE;AACzB,IAAI,sBAAsB,EAAE;AAC5B,IAAI,sBAAsB,EAAE;AAC5B,IAAI,oBAAoB,EAAE;AAC1B,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACO,SAAS,wCAAwC,GAAmD;AAC3G,EAAE,OAAO;AACT,IAAI,oBAAoB;AACxB,IAAI,kBAAkB;AACtB,IAAI,iBAAiB;AACrB,IAAI,iBAAiB;AACrB,IAAI,iBAAiB;AACrB,IAAI,mBAAmB;AACvB,IAAI,cAAc;AAClB,IAAI,cAAc;AAClB,IAAI,eAAe;AACnB,IAAI,aAAa;AACjB,IAAI,qBAAqB;AACzB,IAAI,eAAe;AACnB,IAAI,kBAAkB;AACtB,IAAI,eAAe;AACnB,IAAI,gBAAgB;AACpB,IAAI,kBAAkB;AACtB,IAAI,cAAc;AAClB,IAAI,iBAAiB;AACrB,IAAI,eAAe;AACnB,IAAI,iBAAiB;AACrB,IAAI,qBAAqB;AACzB,IAAI,iBAAiB;AACrB,IAAI,kBAAkB;AACtB,IAAI,gBAAgB;AACpB,IAAI,oBAAoB;AACxB,IAAI,kBAAkB;AACtB,IAAI,qBAAqB;AACzB,IAAI,qBAAqB;AACzB,IAAI,mBAAmB;AACvB,GAAG;AACH;;;;"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { LANGCHAIN_INTEGRATION_NAME, defineIntegration } from '@sentry/core';
|
|
2
|
+
import { generateInstrumentOnce } from '@sentry/node-core';
|
|
3
|
+
import { SentryLangChainInstrumentation } from './instrumentation.js';
|
|
4
|
+
|
|
5
|
+
const instrumentLangChain = generateInstrumentOnce(
|
|
6
|
+
LANGCHAIN_INTEGRATION_NAME,
|
|
7
|
+
options => new SentryLangChainInstrumentation(options),
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
const _langChainIntegration = ((options = {}) => {
|
|
11
|
+
return {
|
|
12
|
+
name: LANGCHAIN_INTEGRATION_NAME,
|
|
13
|
+
setupOnce() {
|
|
14
|
+
instrumentLangChain(options);
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}) ;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Adds Sentry tracing instrumentation for LangChain.
|
|
21
|
+
*
|
|
22
|
+
* This integration is enabled by default.
|
|
23
|
+
*
|
|
24
|
+
* When configured, this integration automatically instruments LangChain runnable instances
|
|
25
|
+
* to capture telemetry data by injecting Sentry callback handlers into all LangChain calls.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```javascript
|
|
29
|
+
* import * as Sentry from '@sentry/node';
|
|
30
|
+
* import { ChatOpenAI } from '@langchain/openai';
|
|
31
|
+
*
|
|
32
|
+
* Sentry.init({
|
|
33
|
+
* integrations: [Sentry.langChainIntegration()],
|
|
34
|
+
* sendDefaultPii: true, // Enable to record inputs/outputs
|
|
35
|
+
* });
|
|
36
|
+
*
|
|
37
|
+
* // LangChain calls are automatically instrumented
|
|
38
|
+
* const model = new ChatOpenAI();
|
|
39
|
+
* await model.invoke("What is the capital of France?");
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* ## Manual Callback Handler
|
|
43
|
+
*
|
|
44
|
+
* You can also manually add the Sentry callback handler alongside other callbacks:
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```javascript
|
|
48
|
+
* import * as Sentry from '@sentry/node';
|
|
49
|
+
* import { ChatOpenAI } from '@langchain/openai';
|
|
50
|
+
*
|
|
51
|
+
* const sentryHandler = Sentry.createLangChainCallbackHandler({
|
|
52
|
+
* recordInputs: true,
|
|
53
|
+
* recordOutputs: true
|
|
54
|
+
* });
|
|
55
|
+
*
|
|
56
|
+
* const model = new ChatOpenAI();
|
|
57
|
+
* await model.invoke(
|
|
58
|
+
* "What is the capital of France?",
|
|
59
|
+
* { callbacks: [sentryHandler, myOtherCallback] }
|
|
60
|
+
* );
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* ## Options
|
|
64
|
+
*
|
|
65
|
+
* - `recordInputs`: Whether to record input messages/prompts (default: respects `sendDefaultPii` client option)
|
|
66
|
+
* - `recordOutputs`: Whether to record response text (default: respects `sendDefaultPii` client option)
|
|
67
|
+
*
|
|
68
|
+
* ### Default Behavior
|
|
69
|
+
*
|
|
70
|
+
* By default, the integration will:
|
|
71
|
+
* - Record inputs and outputs ONLY if `sendDefaultPii` is set to `true` in your Sentry client options
|
|
72
|
+
* - Otherwise, inputs and outputs are NOT recorded unless explicitly enabled
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```javascript
|
|
76
|
+
* // Record inputs and outputs when sendDefaultPii is false
|
|
77
|
+
* Sentry.init({
|
|
78
|
+
* integrations: [
|
|
79
|
+
* Sentry.langChainIntegration({
|
|
80
|
+
* recordInputs: true,
|
|
81
|
+
* recordOutputs: true
|
|
82
|
+
* })
|
|
83
|
+
* ],
|
|
84
|
+
* });
|
|
85
|
+
*
|
|
86
|
+
* // Never record inputs/outputs regardless of sendDefaultPii
|
|
87
|
+
* Sentry.init({
|
|
88
|
+
* sendDefaultPii: true,
|
|
89
|
+
* integrations: [
|
|
90
|
+
* Sentry.langChainIntegration({
|
|
91
|
+
* recordInputs: false,
|
|
92
|
+
* recordOutputs: false
|
|
93
|
+
* })
|
|
94
|
+
* ],
|
|
95
|
+
* });
|
|
96
|
+
* ```
|
|
97
|
+
*
|
|
98
|
+
* ## Supported Events
|
|
99
|
+
*
|
|
100
|
+
* The integration captures the following LangChain lifecycle events:
|
|
101
|
+
* - LLM/Chat Model: start, end, error
|
|
102
|
+
* - Chain: start, end, error
|
|
103
|
+
* - Tool: start, end, error
|
|
104
|
+
*
|
|
105
|
+
*/
|
|
106
|
+
const langChainIntegration = defineIntegration(_langChainIntegration);
|
|
107
|
+
|
|
108
|
+
export { instrumentLangChain, langChainIntegration };
|
|
109
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../../src/integrations/tracing/langchain/index.ts"],"sourcesContent":["import type { IntegrationFn, LangChainOptions } from '@sentry/core';\nimport { defineIntegration, LANGCHAIN_INTEGRATION_NAME } from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node-core';\nimport { SentryLangChainInstrumentation } from './instrumentation';\n\nexport const instrumentLangChain = generateInstrumentOnce<LangChainOptions>(\n LANGCHAIN_INTEGRATION_NAME,\n options => new SentryLangChainInstrumentation(options),\n);\n\nconst _langChainIntegration = ((options: LangChainOptions = {}) => {\n return {\n name: LANGCHAIN_INTEGRATION_NAME,\n setupOnce() {\n instrumentLangChain(options);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for LangChain.\n *\n * This integration is enabled by default.\n *\n * When configured, this integration automatically instruments LangChain runnable instances\n * to capture telemetry data by injecting Sentry callback handlers into all LangChain calls.\n *\n * @example\n * ```javascript\n * import * as Sentry from '@sentry/node';\n * import { ChatOpenAI } from '@langchain/openai';\n *\n * Sentry.init({\n * integrations: [Sentry.langChainIntegration()],\n * sendDefaultPii: true, // Enable to record inputs/outputs\n * });\n *\n * // LangChain calls are automatically instrumented\n * const model = new ChatOpenAI();\n * await model.invoke(\"What is the capital of France?\");\n * ```\n *\n * ## Manual Callback Handler\n *\n * You can also manually add the Sentry callback handler alongside other callbacks:\n *\n * @example\n * ```javascript\n * import * as Sentry from '@sentry/node';\n * import { ChatOpenAI } from '@langchain/openai';\n *\n * const sentryHandler = Sentry.createLangChainCallbackHandler({\n * recordInputs: true,\n * recordOutputs: true\n * });\n *\n * const model = new ChatOpenAI();\n * await model.invoke(\n * \"What is the capital of France?\",\n * { callbacks: [sentryHandler, myOtherCallback] }\n * );\n * ```\n *\n * ## Options\n *\n * - `recordInputs`: Whether to record input messages/prompts (default: respects `sendDefaultPii` client option)\n * - `recordOutputs`: Whether to record response text (default: respects `sendDefaultPii` client option)\n *\n * ### Default Behavior\n *\n * By default, the integration will:\n * - Record inputs and outputs ONLY if `sendDefaultPii` is set to `true` in your Sentry client options\n * - Otherwise, inputs and outputs are NOT recorded unless explicitly enabled\n *\n * @example\n * ```javascript\n * // Record inputs and outputs when sendDefaultPii is false\n * Sentry.init({\n * integrations: [\n * Sentry.langChainIntegration({\n * recordInputs: true,\n * recordOutputs: true\n * })\n * ],\n * });\n *\n * // Never record inputs/outputs regardless of sendDefaultPii\n * Sentry.init({\n * sendDefaultPii: true,\n * integrations: [\n * Sentry.langChainIntegration({\n * recordInputs: false,\n * recordOutputs: false\n * })\n * ],\n * });\n * ```\n *\n * ## Supported Events\n *\n * The integration captures the following LangChain lifecycle events:\n * - LLM/Chat Model: start, end, error\n * - Chain: start, end, error\n * - Tool: start, end, error\n *\n */\nexport const langChainIntegration = defineIntegration(_langChainIntegration);\n"],"names":[],"mappings":";;;;AAKO,MAAM,mBAAA,GAAsB,sBAAsB;AACzD,EAAE,0BAA0B;AAC5B,EAAE,WAAW,IAAI,8BAA8B,CAAC,OAAO,CAAC;AACxD;;AAEA,MAAM,qBAAA,IAAyB,CAAC,OAAO,GAAqB,EAAE,KAAK;AACnE,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,0BAA0B;AACpC,IAAI,SAAS,GAAG;AAChB,MAAM,mBAAmB,CAAC,OAAO,CAAC;AAClC,KAAK;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,oBAAA,GAAuB,iBAAiB,CAAC,qBAAqB;;;;"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { InstrumentationBase, InstrumentationNodeModuleDefinition, InstrumentationNodeModuleFile } from '@opentelemetry/instrumentation';
|
|
2
|
+
import { SDK_VERSION, getClient, createLangChainCallbackHandler } from '@sentry/core';
|
|
3
|
+
|
|
4
|
+
const supportedVersions = ['>=0.1.0 <1.0.0'];
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Augments a callback handler list with Sentry's handler if not already present
|
|
8
|
+
*/
|
|
9
|
+
function augmentCallbackHandlers(handlers, sentryHandler) {
|
|
10
|
+
// Handle null/undefined - return array with just our handler
|
|
11
|
+
if (!handlers) {
|
|
12
|
+
return [sentryHandler];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// If handlers is already an array
|
|
16
|
+
if (Array.isArray(handlers)) {
|
|
17
|
+
// Check if our handler is already in the list
|
|
18
|
+
if (handlers.includes(sentryHandler)) {
|
|
19
|
+
return handlers;
|
|
20
|
+
}
|
|
21
|
+
// Add our handler to the list
|
|
22
|
+
return [...handlers, sentryHandler];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// If it's a single handler object, convert to array
|
|
26
|
+
if (typeof handlers === 'object') {
|
|
27
|
+
return [handlers, sentryHandler];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Unknown type - return original
|
|
31
|
+
return handlers;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Wraps Runnable methods (invoke, stream, batch) to inject Sentry callbacks at request time
|
|
36
|
+
* Uses a Proxy to intercept method calls and augment the options.callbacks
|
|
37
|
+
*/
|
|
38
|
+
function wrapRunnableMethod(
|
|
39
|
+
originalMethod,
|
|
40
|
+
sentryHandler,
|
|
41
|
+
_methodName,
|
|
42
|
+
) {
|
|
43
|
+
return new Proxy(originalMethod, {
|
|
44
|
+
apply(target, thisArg, args) {
|
|
45
|
+
// LangChain Runnable method signatures:
|
|
46
|
+
// invoke(input, options?) - options contains callbacks
|
|
47
|
+
// stream(input, options?) - options contains callbacks
|
|
48
|
+
// batch(inputs, options?) - options contains callbacks
|
|
49
|
+
|
|
50
|
+
// Options is typically the second argument
|
|
51
|
+
const optionsIndex = 1;
|
|
52
|
+
let options = args[optionsIndex] ;
|
|
53
|
+
|
|
54
|
+
// If options don't exist or aren't an object, create them
|
|
55
|
+
if (!options || typeof options !== 'object' || Array.isArray(options)) {
|
|
56
|
+
options = {};
|
|
57
|
+
args[optionsIndex] = options;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Inject our callback handler into options.callbacks (request time callbacks)
|
|
61
|
+
const existingCallbacks = options.callbacks;
|
|
62
|
+
const augmentedCallbacks = augmentCallbackHandlers(existingCallbacks, sentryHandler);
|
|
63
|
+
options.callbacks = augmentedCallbacks;
|
|
64
|
+
|
|
65
|
+
// Call original method with augmented options
|
|
66
|
+
return Reflect.apply(target, thisArg, args);
|
|
67
|
+
},
|
|
68
|
+
}) ;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Sentry LangChain instrumentation using OpenTelemetry.
|
|
73
|
+
*/
|
|
74
|
+
class SentryLangChainInstrumentation extends InstrumentationBase {
|
|
75
|
+
constructor(config = {}) {
|
|
76
|
+
super('@sentry/instrumentation-langchain', SDK_VERSION, config);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Initializes the instrumentation by defining the modules to be patched.
|
|
81
|
+
* We patch the BaseChatModel class methods to inject callbacks
|
|
82
|
+
*
|
|
83
|
+
* We hook into provider packages (@langchain/anthropic, @langchain/openai, etc.)
|
|
84
|
+
* because @langchain/core is often bundled and not loaded as a separate module
|
|
85
|
+
*/
|
|
86
|
+
init() {
|
|
87
|
+
const modules = [];
|
|
88
|
+
|
|
89
|
+
// Hook into common LangChain provider packages
|
|
90
|
+
const providerPackages = [
|
|
91
|
+
'@langchain/anthropic',
|
|
92
|
+
'@langchain/openai',
|
|
93
|
+
'@langchain/google-genai',
|
|
94
|
+
'@langchain/mistralai',
|
|
95
|
+
'@langchain/google-vertexai',
|
|
96
|
+
'@langchain/groq',
|
|
97
|
+
];
|
|
98
|
+
|
|
99
|
+
for (const packageName of providerPackages) {
|
|
100
|
+
// In CJS, LangChain packages re-export from dist/index.cjs files.
|
|
101
|
+
// Patching only the root module sometimes misses the real implementation or
|
|
102
|
+
// gets overwritten when that file is loaded. We add a file-level patch so that
|
|
103
|
+
// _patch runs again on the concrete implementation
|
|
104
|
+
modules.push(
|
|
105
|
+
new InstrumentationNodeModuleDefinition(
|
|
106
|
+
packageName,
|
|
107
|
+
supportedVersions,
|
|
108
|
+
this._patch.bind(this),
|
|
109
|
+
exports => exports,
|
|
110
|
+
[
|
|
111
|
+
new InstrumentationNodeModuleFile(
|
|
112
|
+
`${packageName}/dist/index.cjs`,
|
|
113
|
+
supportedVersions,
|
|
114
|
+
this._patch.bind(this),
|
|
115
|
+
exports => exports,
|
|
116
|
+
),
|
|
117
|
+
],
|
|
118
|
+
),
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return modules;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Core patch logic - patches chat model methods to inject Sentry callbacks
|
|
127
|
+
* This is called when a LangChain provider package is loaded
|
|
128
|
+
*/
|
|
129
|
+
_patch(exports) {
|
|
130
|
+
const client = getClient();
|
|
131
|
+
const defaultPii = Boolean(client?.getOptions().sendDefaultPii);
|
|
132
|
+
|
|
133
|
+
const config = this.getConfig();
|
|
134
|
+
|
|
135
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
136
|
+
const recordInputs = config?.recordInputs ?? defaultPii;
|
|
137
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
138
|
+
const recordOutputs = config?.recordOutputs ?? defaultPii;
|
|
139
|
+
|
|
140
|
+
// Create a shared handler instance
|
|
141
|
+
const sentryHandler = createLangChainCallbackHandler({
|
|
142
|
+
recordInputs,
|
|
143
|
+
recordOutputs,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Patch Runnable methods to inject callbacks at request time
|
|
147
|
+
// This directly manipulates options.callbacks that LangChain uses
|
|
148
|
+
this._patchRunnableMethods(exports, sentryHandler);
|
|
149
|
+
|
|
150
|
+
return exports;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Patches chat model methods (invoke, stream, batch) to inject Sentry callbacks
|
|
155
|
+
* Finds a chat model class from the provider package exports and patches its prototype methods
|
|
156
|
+
*/
|
|
157
|
+
_patchRunnableMethods(exports, sentryHandler) {
|
|
158
|
+
// Known chat model class names for each provider
|
|
159
|
+
const knownChatModelNames = [
|
|
160
|
+
'ChatAnthropic',
|
|
161
|
+
'ChatOpenAI',
|
|
162
|
+
'ChatGoogleGenerativeAI',
|
|
163
|
+
'ChatMistralAI',
|
|
164
|
+
'ChatVertexAI',
|
|
165
|
+
'ChatGroq',
|
|
166
|
+
];
|
|
167
|
+
|
|
168
|
+
// Find a chat model class in the exports by checking known class names
|
|
169
|
+
const chatModelClass = Object.values(exports).find(exp => {
|
|
170
|
+
if (typeof exp !== 'function') {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
return knownChatModelNames.includes(exp.name);
|
|
174
|
+
}) ;
|
|
175
|
+
|
|
176
|
+
if (!chatModelClass) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Patch directly on chatModelClass.prototype
|
|
181
|
+
const targetProto = chatModelClass.prototype ;
|
|
182
|
+
|
|
183
|
+
// Patch the methods (invoke, stream, batch)
|
|
184
|
+
// All chat model instances will inherit these patched methods
|
|
185
|
+
const methodsToPatch = ['invoke', 'stream', 'batch'] ;
|
|
186
|
+
|
|
187
|
+
for (const methodName of methodsToPatch) {
|
|
188
|
+
const method = targetProto[methodName];
|
|
189
|
+
if (typeof method === 'function') {
|
|
190
|
+
targetProto[methodName] = wrapRunnableMethod(
|
|
191
|
+
method ,
|
|
192
|
+
sentryHandler);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export { SentryLangChainInstrumentation };
|
|
199
|
+
//# sourceMappingURL=instrumentation.js.map
|