@sentry/core 10.41.0-beta.0 → 10.41.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/client.js +10 -0
- package/build/cjs/client.js.map +1 -1
- package/build/cjs/index.js +2 -0
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/integrations/consola.js +9 -1
- package/build/cjs/integrations/consola.js.map +1 -1
- package/build/cjs/integrations/postgresjs.js +434 -0
- package/build/cjs/integrations/postgresjs.js.map +1 -0
- package/build/cjs/server-runtime-client.js +26 -0
- package/build/cjs/server-runtime-client.js.map +1 -1
- package/build/cjs/tracing/langchain/index.js +11 -2
- package/build/cjs/tracing/langchain/index.js.map +1 -1
- package/build/cjs/tracing/langchain/utils.js +39 -6
- package/build/cjs/tracing/langchain/utils.js.map +1 -1
- package/build/cjs/utils/version.js +1 -1
- package/build/cjs/utils/version.js.map +1 -1
- package/build/esm/client.js +10 -0
- package/build/esm/client.js.map +1 -1
- package/build/esm/index.js +1 -0
- package/build/esm/index.js.map +1 -1
- package/build/esm/integrations/consola.js +9 -1
- package/build/esm/integrations/consola.js.map +1 -1
- package/build/esm/integrations/postgresjs.js +430 -0
- package/build/esm/integrations/postgresjs.js.map +1 -0
- package/build/esm/package.json +1 -1
- package/build/esm/server-runtime-client.js +26 -0
- package/build/esm/server-runtime-client.js.map +1 -1
- package/build/esm/tracing/langchain/index.js +11 -2
- package/build/esm/tracing/langchain/index.js.map +1 -1
- package/build/esm/tracing/langchain/utils.js +39 -6
- package/build/esm/tracing/langchain/utils.js.map +1 -1
- package/build/esm/utils/version.js +1 -1
- package/build/esm/utils/version.js.map +1 -1
- package/build/types/client.d.ts +13 -3
- package/build/types/client.d.ts.map +1 -1
- package/build/types/index.d.ts +1 -0
- package/build/types/index.d.ts.map +1 -1
- package/build/types/integrations/consola.d.ts +8 -3
- package/build/types/integrations/consola.d.ts.map +1 -1
- package/build/types/integrations/postgresjs.d.ts +62 -0
- package/build/types/integrations/postgresjs.d.ts.map +1 -0
- package/build/types/server-runtime-client.d.ts +12 -0
- package/build/types/server-runtime-client.d.ts.map +1 -1
- package/build/types/tracing/langchain/index.d.ts.map +1 -1
- package/build/types/tracing/langchain/utils.d.ts.map +1 -1
- package/build/types/types-hoist/replay.d.ts +0 -1
- package/build/types/types-hoist/replay.d.ts.map +1 -1
- package/build/types-ts3.8/client.d.ts +13 -3
- package/build/types-ts3.8/index.d.ts +1 -0
- package/build/types-ts3.8/integrations/consola.d.ts +8 -3
- package/build/types-ts3.8/integrations/postgresjs.d.ts +62 -0
- package/build/types-ts3.8/server-runtime-client.d.ts +12 -0
- package/build/types-ts3.8/types-hoist/replay.d.ts +0 -4
- package/package.json +1 -1
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const debugBuild = require('../debug-build.js');
|
|
4
|
+
const semanticAttributes = require('../semanticAttributes.js');
|
|
5
|
+
const debugLogger = require('../utils/debug-logger.js');
|
|
6
|
+
const spanUtils = require('../utils/spanUtils.js');
|
|
7
|
+
const spanstatus = require('../tracing/spanstatus.js');
|
|
8
|
+
const trace = require('../tracing/trace.js');
|
|
9
|
+
|
|
10
|
+
// Portable instrumentation for https://github.com/porsager/postgres
|
|
11
|
+
// This can be used in any environment (Node.js, Cloudflare Workers, etc.)
|
|
12
|
+
// without depending on OpenTelemetry module hooking.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
const SQL_OPERATION_REGEX = /^(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)/i;
|
|
16
|
+
|
|
17
|
+
const CONNECTION_CONTEXT_SYMBOL = Symbol('sentryPostgresConnectionContext');
|
|
18
|
+
|
|
19
|
+
// Use the same Symbol.for() markers as the Node.js OTel instrumentation
|
|
20
|
+
// so that both approaches recognize each other and prevent double-wrapping.
|
|
21
|
+
const INSTRUMENTED_MARKER = Symbol.for('sentry.instrumented.postgresjs');
|
|
22
|
+
// Marker to track if a query was created from an instrumented sql instance.
|
|
23
|
+
// This prevents double-spanning when both the wrapper and the Node.js Query.prototype
|
|
24
|
+
// fallback patch are active simultaneously.
|
|
25
|
+
const QUERY_FROM_INSTRUMENTED_SQL = Symbol.for('sentry.query.from.instrumented.sql');
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Instruments a postgres.js `sql` instance with Sentry tracing.
|
|
29
|
+
*
|
|
30
|
+
* This is a portable instrumentation function that works in any environment
|
|
31
|
+
* (Node.js, Cloudflare Workers, etc.) without depending on OpenTelemetry.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```javascript
|
|
35
|
+
* import postgres from 'postgres';
|
|
36
|
+
* import * as Sentry from '@sentry/cloudflare'; // or '@sentry/deno'
|
|
37
|
+
*
|
|
38
|
+
* const sql = Sentry.instrumentPostgresJsSql(
|
|
39
|
+
* postgres({ host: 'localhost', database: 'mydb' })
|
|
40
|
+
* );
|
|
41
|
+
*
|
|
42
|
+
* // All queries now create Sentry spans
|
|
43
|
+
* await sql`SELECT * FROM users WHERE id = ${userId}`;
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
function instrumentPostgresJsSql(sql, options) {
|
|
47
|
+
if (!sql || typeof sql !== 'function') {
|
|
48
|
+
debugBuild.DEBUG_BUILD && debugLogger.debug.warn('instrumentPostgresJsSql: provided value is not a valid postgres.js sql instance');
|
|
49
|
+
return sql;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return _instrumentSqlInstance(sql, { requireParentSpan: true, ...options }) ;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Instruments a sql instance by wrapping its query execution methods.
|
|
57
|
+
*/
|
|
58
|
+
function _instrumentSqlInstance(
|
|
59
|
+
sql,
|
|
60
|
+
options,
|
|
61
|
+
parentConnectionContext,
|
|
62
|
+
) {
|
|
63
|
+
// Check if already instrumented to prevent double-wrapping
|
|
64
|
+
// Using Symbol.for() ensures the marker survives proxying
|
|
65
|
+
if ((sql )[INSTRUMENTED_MARKER]) {
|
|
66
|
+
return sql;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Wrap the sql function to intercept query creation
|
|
70
|
+
const proxiedSql = new Proxy(sql , {
|
|
71
|
+
apply(target, thisArg, argumentsList) {
|
|
72
|
+
const query = Reflect.apply(target, thisArg, argumentsList);
|
|
73
|
+
|
|
74
|
+
if (query && typeof query === 'object' && 'handle' in query) {
|
|
75
|
+
_wrapSingleQueryHandle(query , proxiedSql, options);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return query;
|
|
79
|
+
},
|
|
80
|
+
get(target, prop) {
|
|
81
|
+
const original = (target )[prop];
|
|
82
|
+
|
|
83
|
+
if (typeof prop !== 'string' || typeof original !== 'function') {
|
|
84
|
+
return original;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Wrap methods that return PendingQuery objects (unsafe, file)
|
|
88
|
+
if (prop === 'unsafe' || prop === 'file') {
|
|
89
|
+
return _wrapQueryMethod(original , target, proxiedSql, options);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Wrap begin and reserve (not savepoint to avoid duplicate spans)
|
|
93
|
+
if (prop === 'begin' || prop === 'reserve') {
|
|
94
|
+
return _wrapCallbackMethod(original , target, proxiedSql, options);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return original;
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Use provided parent context if available, otherwise extract from sql.options
|
|
102
|
+
if (parentConnectionContext) {
|
|
103
|
+
(proxiedSql )[CONNECTION_CONTEXT_SYMBOL] = parentConnectionContext;
|
|
104
|
+
} else {
|
|
105
|
+
_attachConnectionContext(sql, proxiedSql );
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Mark both the original and proxy as instrumented to prevent double-wrapping
|
|
109
|
+
(sql )[INSTRUMENTED_MARKER] = true;
|
|
110
|
+
(proxiedSql )[INSTRUMENTED_MARKER] = true;
|
|
111
|
+
|
|
112
|
+
return proxiedSql;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Wraps query-returning methods (unsafe, file) to ensure their queries are instrumented.
|
|
117
|
+
*/
|
|
118
|
+
function _wrapQueryMethod(
|
|
119
|
+
original,
|
|
120
|
+
target,
|
|
121
|
+
proxiedSql,
|
|
122
|
+
options,
|
|
123
|
+
) {
|
|
124
|
+
return function ( ...args) {
|
|
125
|
+
const query = Reflect.apply(original, target, args);
|
|
126
|
+
|
|
127
|
+
if (query && typeof query === 'object' && 'handle' in query) {
|
|
128
|
+
_wrapSingleQueryHandle(query , proxiedSql, options);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return query;
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Wraps callback-based methods (begin, reserve) to recursively instrument Sql instances.
|
|
137
|
+
* Note: These methods can also be used as tagged templates, which we pass through unchanged.
|
|
138
|
+
*
|
|
139
|
+
* Savepoint is not wrapped to avoid complex nested transaction instrumentation issues.
|
|
140
|
+
* Queries within savepoint callbacks are still instrumented through the parent transaction's Sql instance.
|
|
141
|
+
*/
|
|
142
|
+
function _wrapCallbackMethod(
|
|
143
|
+
original,
|
|
144
|
+
target,
|
|
145
|
+
parentSqlInstance,
|
|
146
|
+
options,
|
|
147
|
+
) {
|
|
148
|
+
return function ( ...args) {
|
|
149
|
+
// Extract parent context to propagate to child instances
|
|
150
|
+
const parentContext = (parentSqlInstance )[CONNECTION_CONTEXT_SYMBOL]
|
|
151
|
+
|
|
152
|
+
;
|
|
153
|
+
|
|
154
|
+
// Check if this is a callback-based call by verifying the last argument is a function
|
|
155
|
+
const isCallbackBased = typeof args[args.length - 1] === 'function';
|
|
156
|
+
|
|
157
|
+
if (!isCallbackBased) {
|
|
158
|
+
// Not a callback-based call - could be tagged template or promise-based
|
|
159
|
+
const result = Reflect.apply(original, target, args);
|
|
160
|
+
// If result is a Promise (e.g., reserve() without callback), instrument the resolved Sql instance
|
|
161
|
+
if (result && typeof (result ).then === 'function') {
|
|
162
|
+
return (result ).then((sqlInstance) => {
|
|
163
|
+
return _instrumentSqlInstance(sqlInstance, options, parentContext);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
return result;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Callback-based call: wrap the callback to instrument the Sql instance
|
|
170
|
+
const callback = (args.length === 1 ? args[0] : args[1]) ;
|
|
171
|
+
const wrappedCallback = function (sqlInstance) {
|
|
172
|
+
const instrumentedSql = _instrumentSqlInstance(sqlInstance, options, parentContext);
|
|
173
|
+
return callback(instrumentedSql);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const newArgs = args.length === 1 ? [wrappedCallback] : [args[0], wrappedCallback];
|
|
177
|
+
return Reflect.apply(original, target, newArgs);
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Wraps a single query's handle method to create spans.
|
|
183
|
+
*/
|
|
184
|
+
function _wrapSingleQueryHandle(
|
|
185
|
+
query,
|
|
186
|
+
sqlInstance,
|
|
187
|
+
options,
|
|
188
|
+
) {
|
|
189
|
+
// Prevent double wrapping - check if the handle itself is already wrapped
|
|
190
|
+
if ((query.handle )?.__sentryWrapped) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Mark this query as coming from an instrumented sql instance.
|
|
195
|
+
// This prevents the Node.js Query.prototype fallback patch from double-spanning.
|
|
196
|
+
(query )[QUERY_FROM_INSTRUMENTED_SQL] = true;
|
|
197
|
+
|
|
198
|
+
const originalHandle = query.handle ;
|
|
199
|
+
|
|
200
|
+
// IMPORTANT: We must replace the handle function directly, not use a Proxy,
|
|
201
|
+
// because Query.then() internally calls this.handle(), which would bypass a Proxy wrapper.
|
|
202
|
+
const wrappedHandle = async function ( ...args) {
|
|
203
|
+
if (!_shouldCreateSpans(options)) {
|
|
204
|
+
return originalHandle.apply(this, args);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const fullQuery = _reconstructQuery(query.strings);
|
|
208
|
+
const sanitizedSqlQuery = _sanitizeSqlQuery(fullQuery);
|
|
209
|
+
|
|
210
|
+
return trace.startSpanManual(
|
|
211
|
+
{
|
|
212
|
+
name: sanitizedSqlQuery || 'postgresjs.query',
|
|
213
|
+
op: 'db',
|
|
214
|
+
},
|
|
215
|
+
(span) => {
|
|
216
|
+
span.setAttribute(semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.postgresjs');
|
|
217
|
+
|
|
218
|
+
span.setAttributes({
|
|
219
|
+
'db.system.name': 'postgres',
|
|
220
|
+
'db.query.text': sanitizedSqlQuery,
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
const connectionContext = sqlInstance
|
|
224
|
+
? ((sqlInstance )[CONNECTION_CONTEXT_SYMBOL]
|
|
225
|
+
|
|
226
|
+
)
|
|
227
|
+
: undefined;
|
|
228
|
+
|
|
229
|
+
_setConnectionAttributes(span, connectionContext);
|
|
230
|
+
|
|
231
|
+
if (options.requestHook) {
|
|
232
|
+
try {
|
|
233
|
+
options.requestHook(span, sanitizedSqlQuery, connectionContext);
|
|
234
|
+
} catch (e) {
|
|
235
|
+
span.setAttribute('sentry.hook.error', 'requestHook failed');
|
|
236
|
+
debugBuild.DEBUG_BUILD && debugLogger.debug.error('Error in requestHook for PostgresJs instrumentation:', e);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const queryWithCallbacks = this
|
|
241
|
+
|
|
242
|
+
;
|
|
243
|
+
|
|
244
|
+
queryWithCallbacks.resolve = new Proxy(queryWithCallbacks.resolve , {
|
|
245
|
+
apply: (resolveTarget, resolveThisArg, resolveArgs) => {
|
|
246
|
+
try {
|
|
247
|
+
_setOperationName(span, sanitizedSqlQuery, resolveArgs?.[0]?.command);
|
|
248
|
+
span.end();
|
|
249
|
+
} catch (e) {
|
|
250
|
+
debugBuild.DEBUG_BUILD && debugLogger.debug.error('Error ending span in resolve callback:', e);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return Reflect.apply(resolveTarget, resolveThisArg, resolveArgs);
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
queryWithCallbacks.reject = new Proxy(queryWithCallbacks.reject , {
|
|
258
|
+
apply: (rejectTarget, rejectThisArg, rejectArgs) => {
|
|
259
|
+
try {
|
|
260
|
+
span.setStatus({
|
|
261
|
+
code: spanstatus.SPAN_STATUS_ERROR,
|
|
262
|
+
message: rejectArgs?.[0]?.message || 'unknown_error',
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
span.setAttribute('db.response.status_code', rejectArgs?.[0]?.code || 'unknown');
|
|
266
|
+
span.setAttribute('error.type', rejectArgs?.[0]?.name || 'unknown');
|
|
267
|
+
|
|
268
|
+
_setOperationName(span, sanitizedSqlQuery);
|
|
269
|
+
span.end();
|
|
270
|
+
} catch (e) {
|
|
271
|
+
debugBuild.DEBUG_BUILD && debugLogger.debug.error('Error ending span in reject callback:', e);
|
|
272
|
+
}
|
|
273
|
+
return Reflect.apply(rejectTarget, rejectThisArg, rejectArgs);
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// Handle synchronous errors that might occur before promise is created
|
|
278
|
+
try {
|
|
279
|
+
return originalHandle.apply(this, args);
|
|
280
|
+
} catch (e) {
|
|
281
|
+
span.setStatus({
|
|
282
|
+
code: spanstatus.SPAN_STATUS_ERROR,
|
|
283
|
+
message: e instanceof Error ? e.message : 'unknown_error',
|
|
284
|
+
});
|
|
285
|
+
span.end();
|
|
286
|
+
throw e;
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
);
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
(wrappedHandle ).__sentryWrapped = true;
|
|
293
|
+
query.handle = wrappedHandle;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Determines whether a span should be created based on the current context.
|
|
298
|
+
* If `requireParentSpan` is set to true in the options, a span will
|
|
299
|
+
* only be created if there is a parent span available.
|
|
300
|
+
*/
|
|
301
|
+
function _shouldCreateSpans(options) {
|
|
302
|
+
const hasParentSpan = spanUtils.getActiveSpan() !== undefined;
|
|
303
|
+
return hasParentSpan || !options.requireParentSpan;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Reconstructs the full SQL query from template strings with PostgreSQL placeholders.
|
|
308
|
+
*
|
|
309
|
+
* For sql`SELECT * FROM users WHERE id = ${123} AND name = ${'foo'}`:
|
|
310
|
+
* strings = ["SELECT * FROM users WHERE id = ", " AND name = ", ""]
|
|
311
|
+
* returns: "SELECT * FROM users WHERE id = $1 AND name = $2"
|
|
312
|
+
*
|
|
313
|
+
* @internal Exported for testing only
|
|
314
|
+
*/
|
|
315
|
+
function _reconstructQuery(strings) {
|
|
316
|
+
if (!strings?.length) {
|
|
317
|
+
return undefined;
|
|
318
|
+
}
|
|
319
|
+
if (strings.length === 1) {
|
|
320
|
+
return strings[0] || undefined;
|
|
321
|
+
}
|
|
322
|
+
// Join template parts with PostgreSQL placeholders ($1, $2, etc.)
|
|
323
|
+
return strings.reduce((acc, str, i) => (i === 0 ? str : `${acc}$${i}${str}`), '');
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Sanitize SQL query as per the OTEL semantic conventions
|
|
328
|
+
* https://opentelemetry.io/docs/specs/semconv/database/database-spans/#sanitization-of-dbquerytext
|
|
329
|
+
*
|
|
330
|
+
* PostgreSQL $n placeholders are preserved per OTEL spec - they're parameterized queries,
|
|
331
|
+
* not sensitive literals. Only actual values (strings, numbers, booleans) are sanitized.
|
|
332
|
+
*
|
|
333
|
+
* @internal Exported for testing only
|
|
334
|
+
*/
|
|
335
|
+
function _sanitizeSqlQuery(sqlQuery) {
|
|
336
|
+
if (!sqlQuery) {
|
|
337
|
+
return 'Unknown SQL Query';
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return (
|
|
341
|
+
sqlQuery
|
|
342
|
+
// Remove comments first (they may contain newlines and extra spaces)
|
|
343
|
+
.replace(/--.*$/gm, '') // Single line comments (multiline mode)
|
|
344
|
+
.replace(/\/\*[\s\S]*?\*\//g, '') // Multi-line comments
|
|
345
|
+
.replace(/;\s*$/, '') // Remove trailing semicolons
|
|
346
|
+
// Collapse whitespace to a single space (after removing comments)
|
|
347
|
+
.replace(/\s+/g, ' ')
|
|
348
|
+
.trim() // Remove extra spaces and trim
|
|
349
|
+
// Sanitize hex/binary literals before string literals
|
|
350
|
+
.replace(/\bX'[0-9A-Fa-f]*'/gi, '?') // Hex string literals
|
|
351
|
+
.replace(/\bB'[01]*'/gi, '?') // Binary string literals
|
|
352
|
+
// Sanitize string literals (handles escaped quotes)
|
|
353
|
+
.replace(/'(?:[^']|'')*'/g, '?')
|
|
354
|
+
// Sanitize hex numbers
|
|
355
|
+
.replace(/\b0x[0-9A-Fa-f]+/gi, '?')
|
|
356
|
+
// Sanitize boolean literals
|
|
357
|
+
.replace(/\b(?:TRUE|FALSE)\b/gi, '?')
|
|
358
|
+
// Sanitize numeric literals (preserve $n placeholders via negative lookbehind)
|
|
359
|
+
.replace(/-?\b\d+\.?\d*[eE][+-]?\d+\b/g, '?') // Scientific notation
|
|
360
|
+
.replace(/-?\b\d+\.\d+\b/g, '?') // Decimals
|
|
361
|
+
.replace(/-?\.\d+\b/g, '?') // Decimals starting with dot
|
|
362
|
+
.replace(/(?<!\$)-?\b\d+\b/g, '?') // Integers (NOT $n placeholders)
|
|
363
|
+
// Collapse IN clauses for cardinality (both ? and $n variants)
|
|
364
|
+
.replace(/\bIN\b\s*\(\s*\?(?:\s*,\s*\?)*\s*\)/gi, 'IN (?)')
|
|
365
|
+
.replace(/\bIN\b\s*\(\s*\$\d+(?:\s*,\s*\$\d+)*\s*\)/gi, 'IN ($?)')
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Sets connection context attributes on a span.
|
|
371
|
+
*/
|
|
372
|
+
function _setConnectionAttributes(span, connectionContext) {
|
|
373
|
+
if (!connectionContext) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
if (connectionContext.ATTR_DB_NAMESPACE) {
|
|
377
|
+
span.setAttribute('db.namespace', connectionContext.ATTR_DB_NAMESPACE);
|
|
378
|
+
}
|
|
379
|
+
if (connectionContext.ATTR_SERVER_ADDRESS) {
|
|
380
|
+
span.setAttribute('server.address', connectionContext.ATTR_SERVER_ADDRESS);
|
|
381
|
+
}
|
|
382
|
+
if (connectionContext.ATTR_SERVER_PORT !== undefined) {
|
|
383
|
+
// Port is stored as string in PostgresConnectionContext for requestHook backwards compatibility,
|
|
384
|
+
// but semantic conventions expect port as a number for span attributes
|
|
385
|
+
const portNumber = parseInt(connectionContext.ATTR_SERVER_PORT, 10);
|
|
386
|
+
if (!isNaN(portNumber)) {
|
|
387
|
+
span.setAttribute('server.port', portNumber);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Extracts DB operation name from SQL query and sets it on the span.
|
|
394
|
+
*/
|
|
395
|
+
function _setOperationName(span, sanitizedQuery, command) {
|
|
396
|
+
if (command) {
|
|
397
|
+
span.setAttribute('db.operation.name', command);
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
// Fallback: extract operation from the SQL query
|
|
401
|
+
const operationMatch = sanitizedQuery?.match(SQL_OPERATION_REGEX);
|
|
402
|
+
if (operationMatch?.[1]) {
|
|
403
|
+
span.setAttribute('db.operation.name', operationMatch[1].toUpperCase());
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Extracts and stores connection context from sql.options.
|
|
409
|
+
*/
|
|
410
|
+
function _attachConnectionContext(sql, proxiedSql) {
|
|
411
|
+
const sqlInstance = sql ;
|
|
412
|
+
if (!sqlInstance.options || typeof sqlInstance.options !== 'object') {
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
const opts = sqlInstance.options;
|
|
417
|
+
// postgres.js stores parsed options with host and port as arrays
|
|
418
|
+
// The library defaults to 'localhost' and 5432 if not specified, but we're defensive here
|
|
419
|
+
const host = opts.host?.[0] || 'localhost';
|
|
420
|
+
const port = opts.port?.[0] || 5432;
|
|
421
|
+
|
|
422
|
+
const connectionContext = {
|
|
423
|
+
ATTR_DB_NAMESPACE: typeof opts.database === 'string' && opts.database !== '' ? opts.database : undefined,
|
|
424
|
+
ATTR_SERVER_ADDRESS: host,
|
|
425
|
+
ATTR_SERVER_PORT: String(port),
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
proxiedSql[CONNECTION_CONTEXT_SYMBOL] = connectionContext;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
exports._reconstructQuery = _reconstructQuery;
|
|
432
|
+
exports._sanitizeSqlQuery = _sanitizeSqlQuery;
|
|
433
|
+
exports.instrumentPostgresJsSql = instrumentPostgresJsSql;
|
|
434
|
+
//# sourceMappingURL=postgresjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgresjs.js","sources":["../../../src/integrations/postgresjs.ts"],"sourcesContent":["// Portable instrumentation for https://github.com/porsager/postgres\n// This can be used in any environment (Node.js, Cloudflare Workers, etc.)\n// without depending on OpenTelemetry module hooking.\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../semanticAttributes';\nimport { SPAN_STATUS_ERROR, startSpanManual } from '../tracing';\nimport type { Span } from '../types-hoist/span';\nimport { debug } from '../utils/debug-logger';\nimport { getActiveSpan } from '../utils/spanUtils';\n\nconst SQL_OPERATION_REGEX = /^(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)/i;\n\ntype PostgresConnectionContext = {\n ATTR_DB_NAMESPACE?: string;\n ATTR_SERVER_ADDRESS?: string;\n ATTR_SERVER_PORT?: string;\n};\n\ninterface PostgresJsSqlInstrumentationOptions {\n /**\n * Whether to require a parent span for the instrumentation.\n * If set to true, the instrumentation will only create spans if there is a parent span\n * available in the current scope.\n * @default true\n */\n requireParentSpan?: boolean;\n /**\n * Hook to modify the span before it is started.\n * This can be used to set additional attributes or modify the span in any way.\n */\n requestHook?: (span: Span, sanitizedSqlQuery: string, postgresConnectionContext?: PostgresConnectionContext) => void;\n}\n\nconst CONNECTION_CONTEXT_SYMBOL = Symbol('sentryPostgresConnectionContext');\n\n// Use the same Symbol.for() markers as the Node.js OTel instrumentation\n// so that both approaches recognize each other and prevent double-wrapping.\nconst INSTRUMENTED_MARKER = Symbol.for('sentry.instrumented.postgresjs');\n// Marker to track if a query was created from an instrumented sql instance.\n// This prevents double-spanning when both the wrapper and the Node.js Query.prototype\n// fallback patch are active simultaneously.\nconst QUERY_FROM_INSTRUMENTED_SQL = Symbol.for('sentry.query.from.instrumented.sql');\n\n/**\n * Instruments a postgres.js `sql` instance with Sentry tracing.\n *\n * This is a portable instrumentation function that works in any environment\n * (Node.js, Cloudflare Workers, etc.) without depending on OpenTelemetry.\n *\n * @example\n * ```javascript\n * import postgres from 'postgres';\n * import * as Sentry from '@sentry/cloudflare'; // or '@sentry/deno'\n *\n * const sql = Sentry.instrumentPostgresJsSql(\n * postgres({ host: 'localhost', database: 'mydb' })\n * );\n *\n * // All queries now create Sentry spans\n * await sql`SELECT * FROM users WHERE id = ${userId}`;\n * ```\n */\nexport function instrumentPostgresJsSql<T>(sql: T, options?: PostgresJsSqlInstrumentationOptions): T {\n if (!sql || typeof sql !== 'function') {\n DEBUG_BUILD && debug.warn('instrumentPostgresJsSql: provided value is not a valid postgres.js sql instance');\n return sql;\n }\n\n return _instrumentSqlInstance(sql, { requireParentSpan: true, ...options }) as T;\n}\n\n/**\n * Instruments a sql instance by wrapping its query execution methods.\n */\nfunction _instrumentSqlInstance(\n sql: unknown,\n options: PostgresJsSqlInstrumentationOptions,\n parentConnectionContext?: PostgresConnectionContext,\n): unknown {\n // Check if already instrumented to prevent double-wrapping\n // Using Symbol.for() ensures the marker survives proxying\n if ((sql as Record<symbol, unknown>)[INSTRUMENTED_MARKER]) {\n return sql;\n }\n\n // Wrap the sql function to intercept query creation\n const proxiedSql: unknown = new Proxy(sql as (...args: unknown[]) => unknown, {\n apply(target, thisArg, argumentsList: unknown[]) {\n const query = Reflect.apply(target, thisArg, argumentsList);\n\n if (query && typeof query === 'object' && 'handle' in query) {\n _wrapSingleQueryHandle(query as { handle: unknown; strings?: string[] }, proxiedSql, options);\n }\n\n return query;\n },\n get(target, prop) {\n const original = (target as unknown as Record<string | symbol, unknown>)[prop];\n\n if (typeof prop !== 'string' || typeof original !== 'function') {\n return original;\n }\n\n // Wrap methods that return PendingQuery objects (unsafe, file)\n if (prop === 'unsafe' || prop === 'file') {\n return _wrapQueryMethod(original as (...args: unknown[]) => unknown, target, proxiedSql, options);\n }\n\n // Wrap begin and reserve (not savepoint to avoid duplicate spans)\n if (prop === 'begin' || prop === 'reserve') {\n return _wrapCallbackMethod(original as (...args: unknown[]) => unknown, target, proxiedSql, options);\n }\n\n return original;\n },\n });\n\n // Use provided parent context if available, otherwise extract from sql.options\n if (parentConnectionContext) {\n (proxiedSql as Record<symbol, unknown>)[CONNECTION_CONTEXT_SYMBOL] = parentConnectionContext;\n } else {\n _attachConnectionContext(sql, proxiedSql as Record<symbol, unknown>);\n }\n\n // Mark both the original and proxy as instrumented to prevent double-wrapping\n (sql as Record<symbol, unknown>)[INSTRUMENTED_MARKER] = true;\n (proxiedSql as Record<symbol, unknown>)[INSTRUMENTED_MARKER] = true;\n\n return proxiedSql;\n}\n\n/**\n * Wraps query-returning methods (unsafe, file) to ensure their queries are instrumented.\n */\nfunction _wrapQueryMethod(\n original: (...args: unknown[]) => unknown,\n target: unknown,\n proxiedSql: unknown,\n options: PostgresJsSqlInstrumentationOptions,\n): (...args: unknown[]) => unknown {\n return function (this: unknown, ...args: unknown[]): unknown {\n const query = Reflect.apply(original, target, args);\n\n if (query && typeof query === 'object' && 'handle' in query) {\n _wrapSingleQueryHandle(query as { handle: unknown; strings?: string[] }, proxiedSql, options);\n }\n\n return query;\n };\n}\n\n/**\n * Wraps callback-based methods (begin, reserve) to recursively instrument Sql instances.\n * Note: These methods can also be used as tagged templates, which we pass through unchanged.\n *\n * Savepoint is not wrapped to avoid complex nested transaction instrumentation issues.\n * Queries within savepoint callbacks are still instrumented through the parent transaction's Sql instance.\n */\nfunction _wrapCallbackMethod(\n original: (...args: unknown[]) => unknown,\n target: unknown,\n parentSqlInstance: unknown,\n options: PostgresJsSqlInstrumentationOptions,\n): (...args: unknown[]) => unknown {\n return function (this: unknown, ...args: unknown[]): unknown {\n // Extract parent context to propagate to child instances\n const parentContext = (parentSqlInstance as Record<symbol, unknown>)[CONNECTION_CONTEXT_SYMBOL] as\n | PostgresConnectionContext\n | undefined;\n\n // Check if this is a callback-based call by verifying the last argument is a function\n const isCallbackBased = typeof args[args.length - 1] === 'function';\n\n if (!isCallbackBased) {\n // Not a callback-based call - could be tagged template or promise-based\n const result = Reflect.apply(original, target, args);\n // If result is a Promise (e.g., reserve() without callback), instrument the resolved Sql instance\n if (result && typeof (result as Promise<unknown>).then === 'function') {\n return (result as Promise<unknown>).then((sqlInstance: unknown) => {\n return _instrumentSqlInstance(sqlInstance, options, parentContext);\n });\n }\n return result;\n }\n\n // Callback-based call: wrap the callback to instrument the Sql instance\n const callback = (args.length === 1 ? args[0] : args[1]) as (sql: unknown) => unknown;\n const wrappedCallback = function (sqlInstance: unknown): unknown {\n const instrumentedSql = _instrumentSqlInstance(sqlInstance, options, parentContext);\n return callback(instrumentedSql);\n };\n\n const newArgs = args.length === 1 ? [wrappedCallback] : [args[0], wrappedCallback];\n return Reflect.apply(original, target, newArgs);\n };\n}\n\n/**\n * Wraps a single query's handle method to create spans.\n */\nfunction _wrapSingleQueryHandle(\n query: { handle: unknown; strings?: string[]; __sentryWrapped?: boolean },\n sqlInstance: unknown,\n options: PostgresJsSqlInstrumentationOptions,\n): void {\n // Prevent double wrapping - check if the handle itself is already wrapped\n if ((query.handle as { __sentryWrapped?: boolean })?.__sentryWrapped) {\n return;\n }\n\n // Mark this query as coming from an instrumented sql instance.\n // This prevents the Node.js Query.prototype fallback patch from double-spanning.\n (query as Record<symbol, unknown>)[QUERY_FROM_INSTRUMENTED_SQL] = true;\n\n const originalHandle = query.handle as (...args: unknown[]) => Promise<unknown>;\n\n // IMPORTANT: We must replace the handle function directly, not use a Proxy,\n // because Query.then() internally calls this.handle(), which would bypass a Proxy wrapper.\n const wrappedHandle = async function (this: unknown, ...args: unknown[]): Promise<unknown> {\n if (!_shouldCreateSpans(options)) {\n return originalHandle.apply(this, args);\n }\n\n const fullQuery = _reconstructQuery(query.strings);\n const sanitizedSqlQuery = _sanitizeSqlQuery(fullQuery);\n\n return startSpanManual(\n {\n name: sanitizedSqlQuery || 'postgresjs.query',\n op: 'db',\n },\n (span: Span) => {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.postgresjs');\n\n span.setAttributes({\n 'db.system.name': 'postgres',\n 'db.query.text': sanitizedSqlQuery,\n });\n\n const connectionContext = sqlInstance\n ? ((sqlInstance as Record<symbol, unknown>)[CONNECTION_CONTEXT_SYMBOL] as\n | PostgresConnectionContext\n | undefined)\n : undefined;\n\n _setConnectionAttributes(span, connectionContext);\n\n if (options.requestHook) {\n try {\n options.requestHook(span, sanitizedSqlQuery, connectionContext);\n } catch (e) {\n span.setAttribute('sentry.hook.error', 'requestHook failed');\n DEBUG_BUILD && debug.error('Error in requestHook for PostgresJs instrumentation:', e);\n }\n }\n\n const queryWithCallbacks = this as {\n resolve: unknown;\n reject: unknown;\n };\n\n queryWithCallbacks.resolve = new Proxy(queryWithCallbacks.resolve as (...args: unknown[]) => unknown, {\n apply: (resolveTarget, resolveThisArg, resolveArgs: [{ command?: string }]) => {\n try {\n _setOperationName(span, sanitizedSqlQuery, resolveArgs?.[0]?.command);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in resolve callback:', e);\n }\n\n return Reflect.apply(resolveTarget, resolveThisArg, resolveArgs);\n },\n });\n\n queryWithCallbacks.reject = new Proxy(queryWithCallbacks.reject as (...args: unknown[]) => unknown, {\n apply: (rejectTarget, rejectThisArg, rejectArgs: { message?: string; code?: string; name?: string }[]) => {\n try {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: rejectArgs?.[0]?.message || 'unknown_error',\n });\n\n span.setAttribute('db.response.status_code', rejectArgs?.[0]?.code || 'unknown');\n span.setAttribute('error.type', rejectArgs?.[0]?.name || 'unknown');\n\n _setOperationName(span, sanitizedSqlQuery);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in reject callback:', e);\n }\n return Reflect.apply(rejectTarget, rejectThisArg, rejectArgs);\n },\n });\n\n // Handle synchronous errors that might occur before promise is created\n try {\n return originalHandle.apply(this, args);\n } catch (e) {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: e instanceof Error ? e.message : 'unknown_error',\n });\n span.end();\n throw e;\n }\n },\n );\n };\n\n (wrappedHandle as { __sentryWrapped?: boolean }).__sentryWrapped = true;\n query.handle = wrappedHandle;\n}\n\n/**\n * Determines whether a span should be created based on the current context.\n * If `requireParentSpan` is set to true in the options, a span will\n * only be created if there is a parent span available.\n */\nfunction _shouldCreateSpans(options: PostgresJsSqlInstrumentationOptions): boolean {\n const hasParentSpan = getActiveSpan() !== undefined;\n return hasParentSpan || !options.requireParentSpan;\n}\n\n/**\n * Reconstructs the full SQL query from template strings with PostgreSQL placeholders.\n *\n * For sql`SELECT * FROM users WHERE id = ${123} AND name = ${'foo'}`:\n * strings = [\"SELECT * FROM users WHERE id = \", \" AND name = \", \"\"]\n * returns: \"SELECT * FROM users WHERE id = $1 AND name = $2\"\n *\n * @internal Exported for testing only\n */\nexport function _reconstructQuery(strings: string[] | undefined): string | undefined {\n if (!strings?.length) {\n return undefined;\n }\n if (strings.length === 1) {\n return strings[0] || undefined;\n }\n // Join template parts with PostgreSQL placeholders ($1, $2, etc.)\n return strings.reduce((acc, str, i) => (i === 0 ? str : `${acc}$${i}${str}`), '');\n}\n\n/**\n * Sanitize SQL query as per the OTEL semantic conventions\n * https://opentelemetry.io/docs/specs/semconv/database/database-spans/#sanitization-of-dbquerytext\n *\n * PostgreSQL $n placeholders are preserved per OTEL spec - they're parameterized queries,\n * not sensitive literals. Only actual values (strings, numbers, booleans) are sanitized.\n *\n * @internal Exported for testing only\n */\nexport function _sanitizeSqlQuery(sqlQuery: string | undefined): string {\n if (!sqlQuery) {\n return 'Unknown SQL Query';\n }\n\n return (\n sqlQuery\n // Remove comments first (they may contain newlines and extra spaces)\n .replace(/--.*$/gm, '') // Single line comments (multiline mode)\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '') // Multi-line comments\n .replace(/;\\s*$/, '') // Remove trailing semicolons\n // Collapse whitespace to a single space (after removing comments)\n .replace(/\\s+/g, ' ')\n .trim() // Remove extra spaces and trim\n // Sanitize hex/binary literals before string literals\n .replace(/\\bX'[0-9A-Fa-f]*'/gi, '?') // Hex string literals\n .replace(/\\bB'[01]*'/gi, '?') // Binary string literals\n // Sanitize string literals (handles escaped quotes)\n .replace(/'(?:[^']|'')*'/g, '?')\n // Sanitize hex numbers\n .replace(/\\b0x[0-9A-Fa-f]+/gi, '?')\n // Sanitize boolean literals\n .replace(/\\b(?:TRUE|FALSE)\\b/gi, '?')\n // Sanitize numeric literals (preserve $n placeholders via negative lookbehind)\n .replace(/-?\\b\\d+\\.?\\d*[eE][+-]?\\d+\\b/g, '?') // Scientific notation\n .replace(/-?\\b\\d+\\.\\d+\\b/g, '?') // Decimals\n .replace(/-?\\.\\d+\\b/g, '?') // Decimals starting with dot\n .replace(/(?<!\\$)-?\\b\\d+\\b/g, '?') // Integers (NOT $n placeholders)\n // Collapse IN clauses for cardinality (both ? and $n variants)\n .replace(/\\bIN\\b\\s*\\(\\s*\\?(?:\\s*,\\s*\\?)*\\s*\\)/gi, 'IN (?)')\n .replace(/\\bIN\\b\\s*\\(\\s*\\$\\d+(?:\\s*,\\s*\\$\\d+)*\\s*\\)/gi, 'IN ($?)')\n );\n}\n\n/**\n * Sets connection context attributes on a span.\n */\nfunction _setConnectionAttributes(span: Span, connectionContext: PostgresConnectionContext | undefined): void {\n if (!connectionContext) {\n return;\n }\n if (connectionContext.ATTR_DB_NAMESPACE) {\n span.setAttribute('db.namespace', connectionContext.ATTR_DB_NAMESPACE);\n }\n if (connectionContext.ATTR_SERVER_ADDRESS) {\n span.setAttribute('server.address', connectionContext.ATTR_SERVER_ADDRESS);\n }\n if (connectionContext.ATTR_SERVER_PORT !== undefined) {\n // Port is stored as string in PostgresConnectionContext for requestHook backwards compatibility,\n // but semantic conventions expect port as a number for span attributes\n const portNumber = parseInt(connectionContext.ATTR_SERVER_PORT, 10);\n if (!isNaN(portNumber)) {\n span.setAttribute('server.port', portNumber);\n }\n }\n}\n\n/**\n * Extracts DB operation name from SQL query and sets it on the span.\n */\nfunction _setOperationName(span: Span, sanitizedQuery: string | undefined, command?: string): void {\n if (command) {\n span.setAttribute('db.operation.name', command);\n return;\n }\n // Fallback: extract operation from the SQL query\n const operationMatch = sanitizedQuery?.match(SQL_OPERATION_REGEX);\n if (operationMatch?.[1]) {\n span.setAttribute('db.operation.name', operationMatch[1].toUpperCase());\n }\n}\n\n/**\n * Extracts and stores connection context from sql.options.\n */\nfunction _attachConnectionContext(sql: unknown, proxiedSql: Record<symbol, unknown>): void {\n const sqlInstance = sql as { options?: { host?: string[]; port?: number[]; database?: string } };\n if (!sqlInstance.options || typeof sqlInstance.options !== 'object') {\n return;\n }\n\n const opts = sqlInstance.options;\n // postgres.js stores parsed options with host and port as arrays\n // The library defaults to 'localhost' and 5432 if not specified, but we're defensive here\n const host = opts.host?.[0] || 'localhost';\n const port = opts.port?.[0] || 5432;\n\n const connectionContext: PostgresConnectionContext = {\n ATTR_DB_NAMESPACE: typeof opts.database === 'string' && opts.database !== '' ? opts.database : undefined,\n ATTR_SERVER_ADDRESS: host,\n ATTR_SERVER_PORT: String(port),\n };\n\n proxiedSql[CONNECTION_CONTEXT_SYMBOL] = connectionContext;\n}\n"],"names":["DEBUG_BUILD","debug","startSpanManual","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SPAN_STATUS_ERROR","getActiveSpan"],"mappings":";;;;;;;;;AAAA;AACA;AACA;;;AASA,MAAM,mBAAA,GAAsB,mDAAmD;;AAuB/E,MAAM,yBAAA,GAA4B,MAAM,CAAC,iCAAiC,CAAC;;AAE3E;AACA;AACA,MAAM,sBAAsB,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC;AACxE;AACA;AACA;AACA,MAAM,8BAA8B,MAAM,CAAC,GAAG,CAAC,oCAAoC,CAAC;;AAEpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,uBAAuB,CAAI,GAAG,EAAK,OAAO,EAA2C;AACrG,EAAE,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,UAAU,EAAE;AACzC,IAAIA,0BAAeC,iBAAK,CAAC,IAAI,CAAC,iFAAiF,CAAC;AAChH,IAAI,OAAO,GAAG;AACd,EAAE;;AAEF,EAAE,OAAO,sBAAsB,CAAC,GAAG,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,GAAG,OAAA,EAAS,CAAA;AAC5E;;AAEA;AACA;AACA;AACA,SAAS,sBAAsB;AAC/B,EAAE,GAAG;AACL,EAAE,OAAO;AACT,EAAE,uBAAuB;AACzB,EAAW;AACX;AACA;AACA,EAAE,IAAI,CAAC,GAAA,GAAgC,mBAAmB,CAAC,EAAE;AAC7D,IAAI,OAAO,GAAG;AACd,EAAE;;AAEF;AACA,EAAE,MAAM,UAAU,GAAY,IAAI,KAAK,CAAC,MAAwC;AAChF,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,EAAa;AACrD,MAAM,MAAM,KAAA,GAAQ,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC;;AAEjE,MAAM,IAAI,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,IAAY,QAAA,IAAY,KAAK,EAAE;AACnE,QAAQ,sBAAsB,CAAC,KAAA,GAAkD,UAAU,EAAE,OAAO,CAAC;AACrG,MAAM;;AAEN,MAAM,OAAO,KAAK;AAClB,IAAI,CAAC;AACL,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE;AACtB,MAAM,MAAM,WAAW,CAAC,SAAuD,IAAI,CAAC;;AAEpF,MAAM,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,OAAO,QAAA,KAAa,UAAU,EAAE;AACtE,QAAQ,OAAO,QAAQ;AACvB,MAAM;;AAEN;AACA,MAAM,IAAI,IAAA,KAAS,YAAY,IAAA,KAAS,MAAM,EAAE;AAChD,QAAQ,OAAO,gBAAgB,CAAC,QAAA,GAA6C,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC;AACzG,MAAM;;AAEN;AACA,MAAM,IAAI,IAAA,KAAS,WAAW,IAAA,KAAS,SAAS,EAAE;AAClD,QAAQ,OAAO,mBAAmB,CAAC,QAAA,GAA6C,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC;AAC5G,MAAM;;AAEN,MAAM,OAAO,QAAQ;AACrB,IAAI,CAAC;AACL,GAAG,CAAC;;AAEJ;AACA,EAAE,IAAI,uBAAuB,EAAE;AAC/B,IAAI,CAAC,UAAA,GAAuC,yBAAyB,CAAA,GAAI,uBAAuB;AAChG,EAAE,OAAO;AACT,IAAI,wBAAwB,CAAC,GAAG,EAAE,YAAsC;AACxE,EAAE;;AAEF;AACA,EAAE,CAAC,GAAA,GAAgC,mBAAmB,CAAA,GAAI,IAAI;AAC9D,EAAE,CAAC,UAAA,GAAuC,mBAAmB,CAAA,GAAI,IAAI;;AAErE,EAAE,OAAO,UAAU;AACnB;;AAEA;AACA;AACA;AACA,SAAS,gBAAgB;AACzB,EAAE,QAAQ;AACV,EAAE,MAAM;AACR,EAAE,UAAU;AACZ,EAAE,OAAO;AACT,EAAmC;AACnC,EAAE,OAAO,WAAyB,GAAG,IAAI,EAAsB;AAC/D,IAAI,MAAM,KAAA,GAAQ,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC;;AAEvD,IAAI,IAAI,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,IAAY,QAAA,IAAY,KAAK,EAAE;AACjE,MAAM,sBAAsB,CAAC,KAAA,GAAkD,UAAU,EAAE,OAAO,CAAC;AACnG,IAAI;;AAEJ,IAAI,OAAO,KAAK;AAChB,EAAE,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,mBAAmB;AAC5B,EAAE,QAAQ;AACV,EAAE,MAAM;AACR,EAAE,iBAAiB;AACnB,EAAE,OAAO;AACT,EAAmC;AACnC,EAAE,OAAO,WAAyB,GAAG,IAAI,EAAsB;AAC/D;AACA,IAAI,MAAM,gBAAgB,CAAC,oBAA8C,yBAAyB;;AAE5F;;AAEN;AACA,IAAI,MAAM,eAAA,GAAkB,OAAO,IAAI,CAAC,IAAI,CAAC,MAAA,GAAS,CAAC,CAAA,KAAM,UAAU;;AAEvE,IAAI,IAAI,CAAC,eAAe,EAAE;AAC1B;AACA,MAAM,MAAM,MAAA,GAAS,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC;AAC1D;AACA,MAAM,IAAI,MAAA,IAAU,OAAO,CAAC,MAAA,GAA4B,IAAA,KAAS,UAAU,EAAE;AAC7E,QAAQ,OAAO,CAAC,MAAA,GAA4B,IAAI,CAAC,CAAC,WAAW,KAAc;AAC3E,UAAU,OAAO,sBAAsB,CAAC,WAAW,EAAE,OAAO,EAAE,aAAa,CAAC;AAC5E,QAAQ,CAAC,CAAC;AACV,MAAM;AACN,MAAM,OAAO,MAAM;AACnB,IAAI;;AAEJ;AACA,IAAI,MAAM,QAAA,IAAY,IAAI,CAAC,WAAW,CAAA,GAAI,IAAI,CAAC,CAAC,CAAA,GAAI,IAAI,CAAC,CAAC,CAAC,CAAA;AAC3D,IAAI,MAAM,eAAA,GAAkB,UAAU,WAAW,EAAoB;AACrE,MAAM,MAAM,eAAA,GAAkB,sBAAsB,CAAC,WAAW,EAAE,OAAO,EAAE,aAAa,CAAC;AACzF,MAAM,OAAO,QAAQ,CAAC,eAAe,CAAC;AACtC,IAAI,CAAC;;AAEL,IAAI,MAAM,UAAU,IAAI,CAAC,MAAA,KAAW,IAAI,CAAC,eAAe,CAAA,GAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC;AACtF,IAAI,OAAO,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC;AACnD,EAAE,CAAC;AACH;;AAEA;AACA;AACA;AACA,SAAS,sBAAsB;AAC/B,EAAE,KAAK;AACP,EAAE,WAAW;AACb,EAAE,OAAO;AACT,EAAQ;AACR;AACA,EAAE,IAAI,CAAC,KAAK,CAAC,MAAA,IAA0C,eAAe,EAAE;AACxE,IAAI;AACJ,EAAE;;AAEF;AACA;AACA,EAAE,CAAC,KAAA,GAAkC,2BAA2B,CAAA,GAAI,IAAI;;AAExE,EAAE,MAAM,cAAA,GAAiB,KAAK,CAAC,MAAA;;AAE/B;AACA;AACA,EAAE,MAAM,aAAA,GAAgB,iBAA+B,GAAG,IAAI,EAA+B;AAC7F,IAAI,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE;AACtC,MAAM,OAAO,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;AAC7C,IAAI;;AAEJ,IAAI,MAAM,YAAY,iBAAiB,CAAC,KAAK,CAAC,OAAO,CAAC;AACtD,IAAI,MAAM,iBAAA,GAAoB,iBAAiB,CAAC,SAAS,CAAC;;AAE1D,IAAI,OAAOC,qBAAe;AAC1B,MAAM;AACN,QAAQ,IAAI,EAAE,iBAAA,IAAqB,kBAAkB;AACrD,QAAQ,EAAE,EAAE,IAAI;AAChB,OAAO;AACP,MAAM,CAAC,IAAI,KAAW;AACtB,QAAQ,IAAI,CAAC,YAAY,CAACC,mDAAgC,EAAE,oBAAoB,CAAC;;AAEjF,QAAQ,IAAI,CAAC,aAAa,CAAC;AAC3B,UAAU,gBAAgB,EAAE,UAAU;AACtC,UAAU,eAAe,EAAE,iBAAiB;AAC5C,SAAS,CAAC;;AAEV,QAAQ,MAAM,oBAAoB;AAClC,aAAa,CAAC,cAAwC,yBAAyB;;AAEjE;AACd,YAAY,SAAS;;AAErB,QAAQ,wBAAwB,CAAC,IAAI,EAAE,iBAAiB,CAAC;;AAEzD,QAAQ,IAAI,OAAO,CAAC,WAAW,EAAE;AACjC,UAAU,IAAI;AACd,YAAY,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,iBAAiB,EAAE,iBAAiB,CAAC;AAC3E,UAAU,CAAA,CAAE,OAAO,CAAC,EAAE;AACtB,YAAY,IAAI,CAAC,YAAY,CAAC,mBAAmB,EAAE,oBAAoB,CAAC;AACxE,YAAYH,sBAAA,IAAeC,iBAAK,CAAC,KAAK,CAAC,sDAAsD,EAAE,CAAC,CAAC;AACjG,UAAU;AACV,QAAQ;;AAER,QAAQ,MAAM,kBAAA,GAAqB;;AAG3B;;AAER,QAAQ,kBAAkB,CAAC,OAAA,GAAU,IAAI,KAAK,CAAC,kBAAkB,CAAC,OAAA,GAA4C;AAC9G,UAAU,KAAK,EAAE,CAAC,aAAa,EAAE,cAAc,EAAE,WAAW,KAA6B;AACzF,YAAY,IAAI;AAChB,cAAc,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,EAAE,WAAW,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC;AACnF,cAAc,IAAI,CAAC,GAAG,EAAE;AACxB,YAAY,CAAA,CAAE,OAAO,CAAC,EAAE;AACxB,cAAcD,sBAAA,IAAeC,iBAAK,CAAC,KAAK,CAAC,wCAAwC,EAAE,CAAC,CAAC;AACrF,YAAY;;AAEZ,YAAY,OAAO,OAAO,CAAC,KAAK,CAAC,aAAa,EAAE,cAAc,EAAE,WAAW,CAAC;AAC5E,UAAU,CAAC;AACX,SAAS,CAAC;;AAEV,QAAQ,kBAAkB,CAAC,MAAA,GAAS,IAAI,KAAK,CAAC,kBAAkB,CAAC,MAAA,GAA2C;AAC5G,UAAU,KAAK,EAAE,CAAC,YAAY,EAAE,aAAa,EAAE,UAAU,KAA2D;AACpH,YAAY,IAAI;AAChB,cAAc,IAAI,CAAC,SAAS,CAAC;AAC7B,gBAAgB,IAAI,EAAEG,4BAAiB;AACvC,gBAAgB,OAAO,EAAE,UAAU,GAAG,CAAC,CAAC,EAAE,OAAA,IAAW,eAAe;AACpE,eAAe,CAAC;;AAEhB,cAAc,IAAI,CAAC,YAAY,CAAC,yBAAyB,EAAE,UAAU,GAAG,CAAC,CAAC,EAAE,IAAA,IAAQ,SAAS,CAAC;AAC9F,cAAc,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,UAAU,GAAG,CAAC,CAAC,EAAE,IAAA,IAAQ,SAAS,CAAC;;AAEjF,cAAc,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,CAAC;AACxD,cAAc,IAAI,CAAC,GAAG,EAAE;AACxB,YAAY,CAAA,CAAE,OAAO,CAAC,EAAE;AACxB,cAAcJ,sBAAA,IAAeC,iBAAK,CAAC,KAAK,CAAC,uCAAuC,EAAE,CAAC,CAAC;AACpF,YAAY;AACZ,YAAY,OAAO,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,aAAa,EAAE,UAAU,CAAC;AACzE,UAAU,CAAC;AACX,SAAS,CAAC;;AAEV;AACA,QAAQ,IAAI;AACZ,UAAU,OAAO,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;AACjD,QAAQ,CAAA,CAAE,OAAO,CAAC,EAAE;AACpB,UAAU,IAAI,CAAC,SAAS,CAAC;AACzB,YAAY,IAAI,EAAEG,4BAAiB;AACnC,YAAY,OAAO,EAAE,CAAA,YAAa,KAAA,GAAQ,CAAC,CAAC,OAAA,GAAU,eAAe;AACrE,WAAW,CAAC;AACZ,UAAU,IAAI,CAAC,GAAG,EAAE;AACpB,UAAU,MAAM,CAAC;AACjB,QAAQ;AACR,MAAM,CAAC;AACP,KAAK;AACL,EAAE,CAAC;;AAEH,EAAE,CAAC,aAAA,GAAgD,eAAA,GAAkB,IAAI;AACzE,EAAE,KAAK,CAAC,MAAA,GAAS,aAAa;AAC9B;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS,kBAAkB,CAAC,OAAO,EAAgD;AACnF,EAAE,MAAM,aAAA,GAAgBC,uBAAa,EAAC,KAAM,SAAS;AACrD,EAAE,OAAO,aAAA,IAAiB,CAAC,OAAO,CAAC,iBAAiB;AACpD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,iBAAiB,CAAC,OAAO,EAA4C;AACrF,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE;AACxB,IAAI,OAAO,SAAS;AACpB,EAAE;AACF,EAAE,IAAI,OAAO,CAAC,MAAA,KAAW,CAAC,EAAE;AAC5B,IAAI,OAAO,OAAO,CAAC,CAAC,CAAA,IAAK,SAAS;AAClC,EAAE;AACF;AACA,EAAE,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAA,KAAM,IAAI,GAAA,GAAM,CAAC,EAAA,GAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,GAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAA,iBAAA,CAAA,QAAA,EAAA;AACA,EAAA,IAAA,CAAA,QAAA,EAAA;AACA,IAAA,OAAA,mBAAA;AACA,EAAA;;AAEA,EAAA;AACA,IAAA;AACA;AACA,OAAA,OAAA,CAAA,SAAA,EAAA,EAAA,CAAA;AACA,OAAA,OAAA,CAAA,mBAAA,EAAA,EAAA,CAAA;AACA,OAAA,OAAA,CAAA,OAAA,EAAA,EAAA,CAAA;AACA;AACA,OAAA,OAAA,CAAA,MAAA,EAAA,GAAA;AACA,OAAA,IAAA,EAAA;AACA;AACA,OAAA,OAAA,CAAA,qBAAA,EAAA,GAAA,CAAA;AACA,OAAA,OAAA,CAAA,cAAA,EAAA,GAAA,CAAA;AACA;AACA,OAAA,OAAA,CAAA,iBAAA,EAAA,GAAA;AACA;AACA,OAAA,OAAA,CAAA,oBAAA,EAAA,GAAA;AACA;AACA,OAAA,OAAA,CAAA,sBAAA,EAAA,GAAA;AACA;AACA,OAAA,OAAA,CAAA,8BAAA,EAAA,GAAA,CAAA;AACA,OAAA,OAAA,CAAA,iBAAA,EAAA,GAAA,CAAA;AACA,OAAA,OAAA,CAAA,YAAA,EAAA,GAAA,CAAA;AACA,OAAA,OAAA,CAAA,mBAAA,EAAA,GAAA,CAAA;AACA;AACA,OAAA,OAAA,CAAA,uCAAA,EAAA,QAAA;AACA,OAAA,OAAA,CAAA,6CAAA,EAAA,SAAA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAA,wBAAA,CAAA,IAAA,EAAA,iBAAA,EAAA;AACA,EAAA,IAAA,CAAA,iBAAA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA,IAAA,iBAAA,CAAA,iBAAA,EAAA;AACA,IAAA,IAAA,CAAA,YAAA,CAAA,cAAA,EAAA,iBAAA,CAAA,iBAAA,CAAA;AACA,EAAA;AACA,EAAA,IAAA,iBAAA,CAAA,mBAAA,EAAA;AACA,IAAA,IAAA,CAAA,YAAA,CAAA,gBAAA,EAAA,iBAAA,CAAA,mBAAA,CAAA;AACA,EAAA;AACA,EAAA,IAAA,iBAAA,CAAA,gBAAA,KAAA,SAAA,EAAA;AACA;AACA;AACA,IAAA,MAAA,UAAA,GAAA,QAAA,CAAA,iBAAA,CAAA,gBAAA,EAAA,EAAA,CAAA;AACA,IAAA,IAAA,CAAA,KAAA,CAAA,UAAA,CAAA,EAAA;AACA,MAAA,IAAA,CAAA,YAAA,CAAA,aAAA,EAAA,UAAA,CAAA;AACA,IAAA;AACA,EAAA;AACA;;AAEA;AACA;AACA;AACA,SAAA,iBAAA,CAAA,IAAA,EAAA,cAAA,EAAA,OAAA,EAAA;AACA,EAAA,IAAA,OAAA,EAAA;AACA,IAAA,IAAA,CAAA,YAAA,CAAA,mBAAA,EAAA,OAAA,CAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA,MAAA,cAAA,GAAA,cAAA,EAAA,KAAA,CAAA,mBAAA,CAAA;AACA,EAAA,IAAA,cAAA,GAAA,CAAA,CAAA,EAAA;AACA,IAAA,IAAA,CAAA,YAAA,CAAA,mBAAA,EAAA,cAAA,CAAA,CAAA,CAAA,CAAA,WAAA,EAAA,CAAA;AACA,EAAA;AACA;;AAEA;AACA;AACA;AACA,SAAA,wBAAA,CAAA,GAAA,EAAA,UAAA,EAAA;AACA,EAAA,MAAA,WAAA,GAAA,GAAA;AACA,EAAA,IAAA,CAAA,WAAA,CAAA,OAAA,IAAA,OAAA,WAAA,CAAA,OAAA,KAAA,QAAA,EAAA;AACA,IAAA;AACA,EAAA;;AAEA,EAAA,MAAA,IAAA,GAAA,WAAA,CAAA,OAAA;AACA;AACA;AACA,EAAA,MAAA,IAAA,GAAA,IAAA,CAAA,IAAA,GAAA,CAAA,CAAA,IAAA,WAAA;AACA,EAAA,MAAA,IAAA,GAAA,IAAA,CAAA,IAAA,GAAA,CAAA,CAAA,IAAA,IAAA;;AAEA,EAAA,MAAA,iBAAA,GAAA;AACA,IAAA,iBAAA,EAAA,OAAA,IAAA,CAAA,QAAA,KAAA,QAAA,IAAA,IAAA,CAAA,QAAA,KAAA,EAAA,GAAA,IAAA,CAAA,QAAA,GAAA,SAAA;AACA,IAAA,mBAAA,EAAA,IAAA;AACA,IAAA,gBAAA,EAAA,MAAA,CAAA,IAAA,CAAA;AACA,GAAA;;AAEA,EAAA,UAAA,CAAA,yBAAA,CAAA,GAAA,iBAAA;AACA;;;;;;"}
|
|
@@ -141,6 +141,32 @@ class ServerRuntimeClient
|
|
|
141
141
|
return id;
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
/**
|
|
145
|
+
* Disposes of the client and releases all resources.
|
|
146
|
+
*
|
|
147
|
+
* This method clears all internal state to allow the client to be garbage collected.
|
|
148
|
+
* It clears hooks, event processors, integrations, transport, and other internal references.
|
|
149
|
+
*
|
|
150
|
+
* Call this method after flushing to allow the client to be garbage collected.
|
|
151
|
+
* After calling dispose(), the client should not be used anymore.
|
|
152
|
+
*
|
|
153
|
+
* Subclasses should override this method to clean up their own resources and call `super.dispose()`.
|
|
154
|
+
*/
|
|
155
|
+
dispose() {
|
|
156
|
+
debugBuild.DEBUG_BUILD && debugLogger.debug.log('Disposing client...');
|
|
157
|
+
|
|
158
|
+
for (const hookName of Object.keys(this._hooks)) {
|
|
159
|
+
this._hooks[hookName]?.clear();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
this._hooks = {};
|
|
163
|
+
this._eventProcessors.length = 0;
|
|
164
|
+
this._integrations = {};
|
|
165
|
+
this._outcomes = {};
|
|
166
|
+
(this )._transport = undefined;
|
|
167
|
+
(this )._promiseBuffer = undefined;
|
|
168
|
+
}
|
|
169
|
+
|
|
144
170
|
/**
|
|
145
171
|
* @inheritDoc
|
|
146
172
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-runtime-client.js","sources":["../../src/server-runtime-client.ts"],"sourcesContent":["import { createCheckInEnvelope } from './checkin';\nimport { Client } from './client';\nimport { getIsolationScope } from './currentScopes';\nimport { DEBUG_BUILD } from './debug-build';\nimport type { Scope } from './scope';\nimport { registerSpanErrorInstrumentation } from './tracing';\nimport { addUserAgentToTransportHeaders } from './transports/userAgent';\nimport type { CheckIn, MonitorConfig, SerializedCheckIn } from './types-hoist/checkin';\nimport type { Event, EventHint } from './types-hoist/event';\nimport type { ClientOptions } from './types-hoist/options';\nimport type { ParameterizedString } from './types-hoist/parameterize';\nimport type { SeverityLevel } from './types-hoist/severity';\nimport type { BaseTransportOptions } from './types-hoist/transport';\nimport { debug } from './utils/debug-logger';\nimport { eventFromMessage, eventFromUnknownInput } from './utils/eventbuilder';\nimport { uuid4 } from './utils/misc';\nimport { resolvedSyncPromise } from './utils/syncpromise';\nimport { _getTraceInfoFromScope } from './utils/trace-info';\n\nexport interface ServerRuntimeClientOptions extends ClientOptions<BaseTransportOptions> {\n platform?: string;\n runtime?: { name: string; version?: string };\n serverName?: string;\n}\n\n/**\n * The Sentry Server Runtime Client SDK.\n */\nexport class ServerRuntimeClient<\n O extends ClientOptions & ServerRuntimeClientOptions = ServerRuntimeClientOptions,\n> extends Client<O> {\n /**\n * Creates a new Edge SDK instance.\n * @param options Configuration options for this SDK.\n */\n public constructor(options: O) {\n // Server clients always support tracing\n registerSpanErrorInstrumentation();\n\n addUserAgentToTransportHeaders(options);\n\n super(options);\n\n this._setUpMetricsProcessing();\n }\n\n /**\n * @inheritDoc\n */\n public eventFromException(exception: unknown, hint?: EventHint): PromiseLike<Event> {\n const event = eventFromUnknownInput(this, this._options.stackParser, exception, hint);\n event.level = 'error';\n\n return resolvedSyncPromise(event);\n }\n\n /**\n * @inheritDoc\n */\n public eventFromMessage(\n message: ParameterizedString,\n level: SeverityLevel = 'info',\n hint?: EventHint,\n ): PromiseLike<Event> {\n return resolvedSyncPromise(\n eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace),\n );\n }\n\n /**\n * @inheritDoc\n */\n public captureException(exception: unknown, hint?: EventHint, scope?: Scope): string {\n setCurrentRequestSessionErroredOrCrashed(hint);\n return super.captureException(exception, hint, scope);\n }\n\n /**\n * @inheritDoc\n */\n public captureEvent(event: Event, hint?: EventHint, scope?: Scope): string {\n // If the event is of type Exception, then a request session should be captured\n const isException = !event.type && event.exception?.values && event.exception.values.length > 0;\n if (isException) {\n setCurrentRequestSessionErroredOrCrashed(hint);\n }\n\n return super.captureEvent(event, hint, scope);\n }\n\n /**\n * Create a cron monitor check in and send it to Sentry.\n *\n * @param checkIn An object that describes a check in.\n * @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want\n * to create a monitor automatically when sending a check in.\n */\n public captureCheckIn(checkIn: CheckIn, monitorConfig?: MonitorConfig, scope?: Scope): string {\n const id = 'checkInId' in checkIn && checkIn.checkInId ? checkIn.checkInId : uuid4();\n if (!this._isEnabled()) {\n DEBUG_BUILD && debug.warn('SDK not enabled, will not capture check-in.');\n return id;\n }\n\n const options = this.getOptions();\n const { release, environment, tunnel } = options;\n\n const serializedCheckIn: SerializedCheckIn = {\n check_in_id: id,\n monitor_slug: checkIn.monitorSlug,\n status: checkIn.status,\n release,\n environment,\n };\n\n if ('duration' in checkIn) {\n serializedCheckIn.duration = checkIn.duration;\n }\n\n if (monitorConfig) {\n serializedCheckIn.monitor_config = {\n schedule: monitorConfig.schedule,\n checkin_margin: monitorConfig.checkinMargin,\n max_runtime: monitorConfig.maxRuntime,\n timezone: monitorConfig.timezone,\n failure_issue_threshold: monitorConfig.failureIssueThreshold,\n recovery_threshold: monitorConfig.recoveryThreshold,\n };\n }\n\n const [dynamicSamplingContext, traceContext] = _getTraceInfoFromScope(this, scope);\n if (traceContext) {\n serializedCheckIn.contexts = {\n trace: traceContext,\n };\n }\n\n const envelope = createCheckInEnvelope(\n serializedCheckIn,\n dynamicSamplingContext,\n this.getSdkMetadata(),\n tunnel,\n this.getDsn(),\n );\n\n DEBUG_BUILD && debug.log('Sending checkin:', checkIn.monitorSlug, checkIn.status);\n\n // sendEnvelope should not throw\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.sendEnvelope(envelope);\n\n return id;\n }\n\n /**\n * @inheritDoc\n */\n protected _prepareEvent(\n event: Event,\n hint: EventHint,\n currentScope: Scope,\n isolationScope: Scope,\n ): PromiseLike<Event | null> {\n if (this._options.platform) {\n event.platform = event.platform || this._options.platform;\n }\n\n if (this._options.runtime) {\n event.contexts = {\n ...event.contexts,\n runtime: event.contexts?.runtime || this._options.runtime,\n };\n }\n\n if (this._options.serverName) {\n event.server_name = event.server_name || this._options.serverName;\n }\n\n return super._prepareEvent(event, hint, currentScope, isolationScope);\n }\n\n /**\n * Process a server-side metric before it is captured.\n */\n private _setUpMetricsProcessing(): void {\n this.on('processMetric', metric => {\n if (this._options.serverName) {\n metric.attributes = {\n 'server.address': this._options.serverName,\n ...metric.attributes,\n };\n }\n });\n }\n}\n\nfunction setCurrentRequestSessionErroredOrCrashed(eventHint?: EventHint): void {\n const requestSession = getIsolationScope().getScopeData().sdkProcessingMetadata.requestSession;\n if (requestSession) {\n // We mutate instead of doing `setSdkProcessingMetadata` because the http integration stores away a particular\n // isolationScope. If that isolation scope is forked, setting the processing metadata here will not mutate the\n // original isolation scope that the http integration stored away.\n const isHandledException = eventHint?.mechanism?.handled ?? true;\n // A request session can go from \"errored\" -> \"crashed\" but not \"crashed\" -> \"errored\".\n // Crashed (unhandled exception) is worse than errored (handled exception).\n if (isHandledException && requestSession.status !== 'crashed') {\n requestSession.status = 'errored';\n } else if (!isHandledException) {\n requestSession.status = 'crashed';\n }\n }\n}\n"],"names":["Client","registerSpanErrorInstrumentation","addUserAgentToTransportHeaders","eventFromUnknownInput","resolvedSyncPromise","eventFromMessage","uuid4","DEBUG_BUILD","debug","_getTraceInfoFromScope","createCheckInEnvelope","getIsolationScope"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server-runtime-client.js","sources":["../../src/server-runtime-client.ts"],"sourcesContent":["import { createCheckInEnvelope } from './checkin';\nimport { Client } from './client';\nimport { getIsolationScope } from './currentScopes';\nimport { DEBUG_BUILD } from './debug-build';\nimport type { Scope } from './scope';\nimport { registerSpanErrorInstrumentation } from './tracing';\nimport { addUserAgentToTransportHeaders } from './transports/userAgent';\nimport type { CheckIn, MonitorConfig, SerializedCheckIn } from './types-hoist/checkin';\nimport type { Event, EventHint } from './types-hoist/event';\nimport type { ClientOptions } from './types-hoist/options';\nimport type { ParameterizedString } from './types-hoist/parameterize';\nimport type { SeverityLevel } from './types-hoist/severity';\nimport type { BaseTransportOptions, Transport } from './types-hoist/transport';\nimport { debug } from './utils/debug-logger';\nimport { eventFromMessage, eventFromUnknownInput } from './utils/eventbuilder';\nimport { uuid4 } from './utils/misc';\nimport type { PromiseBuffer } from './utils/promisebuffer';\nimport { resolvedSyncPromise } from './utils/syncpromise';\nimport { _getTraceInfoFromScope } from './utils/trace-info';\n\nexport interface ServerRuntimeClientOptions extends ClientOptions<BaseTransportOptions> {\n platform?: string;\n runtime?: { name: string; version?: string };\n serverName?: string;\n}\n\n/**\n * The Sentry Server Runtime Client SDK.\n */\nexport class ServerRuntimeClient<\n O extends ClientOptions & ServerRuntimeClientOptions = ServerRuntimeClientOptions,\n> extends Client<O> {\n /**\n * Creates a new Edge SDK instance.\n * @param options Configuration options for this SDK.\n */\n public constructor(options: O) {\n // Server clients always support tracing\n registerSpanErrorInstrumentation();\n\n addUserAgentToTransportHeaders(options);\n\n super(options);\n\n this._setUpMetricsProcessing();\n }\n\n /**\n * @inheritDoc\n */\n public eventFromException(exception: unknown, hint?: EventHint): PromiseLike<Event> {\n const event = eventFromUnknownInput(this, this._options.stackParser, exception, hint);\n event.level = 'error';\n\n return resolvedSyncPromise(event);\n }\n\n /**\n * @inheritDoc\n */\n public eventFromMessage(\n message: ParameterizedString,\n level: SeverityLevel = 'info',\n hint?: EventHint,\n ): PromiseLike<Event> {\n return resolvedSyncPromise(\n eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace),\n );\n }\n\n /**\n * @inheritDoc\n */\n public captureException(exception: unknown, hint?: EventHint, scope?: Scope): string {\n setCurrentRequestSessionErroredOrCrashed(hint);\n return super.captureException(exception, hint, scope);\n }\n\n /**\n * @inheritDoc\n */\n public captureEvent(event: Event, hint?: EventHint, scope?: Scope): string {\n // If the event is of type Exception, then a request session should be captured\n const isException = !event.type && event.exception?.values && event.exception.values.length > 0;\n if (isException) {\n setCurrentRequestSessionErroredOrCrashed(hint);\n }\n\n return super.captureEvent(event, hint, scope);\n }\n\n /**\n * Create a cron monitor check in and send it to Sentry.\n *\n * @param checkIn An object that describes a check in.\n * @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want\n * to create a monitor automatically when sending a check in.\n */\n public captureCheckIn(checkIn: CheckIn, monitorConfig?: MonitorConfig, scope?: Scope): string {\n const id = 'checkInId' in checkIn && checkIn.checkInId ? checkIn.checkInId : uuid4();\n if (!this._isEnabled()) {\n DEBUG_BUILD && debug.warn('SDK not enabled, will not capture check-in.');\n return id;\n }\n\n const options = this.getOptions();\n const { release, environment, tunnel } = options;\n\n const serializedCheckIn: SerializedCheckIn = {\n check_in_id: id,\n monitor_slug: checkIn.monitorSlug,\n status: checkIn.status,\n release,\n environment,\n };\n\n if ('duration' in checkIn) {\n serializedCheckIn.duration = checkIn.duration;\n }\n\n if (monitorConfig) {\n serializedCheckIn.monitor_config = {\n schedule: monitorConfig.schedule,\n checkin_margin: monitorConfig.checkinMargin,\n max_runtime: monitorConfig.maxRuntime,\n timezone: monitorConfig.timezone,\n failure_issue_threshold: monitorConfig.failureIssueThreshold,\n recovery_threshold: monitorConfig.recoveryThreshold,\n };\n }\n\n const [dynamicSamplingContext, traceContext] = _getTraceInfoFromScope(this, scope);\n if (traceContext) {\n serializedCheckIn.contexts = {\n trace: traceContext,\n };\n }\n\n const envelope = createCheckInEnvelope(\n serializedCheckIn,\n dynamicSamplingContext,\n this.getSdkMetadata(),\n tunnel,\n this.getDsn(),\n );\n\n DEBUG_BUILD && debug.log('Sending checkin:', checkIn.monitorSlug, checkIn.status);\n\n // sendEnvelope should not throw\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.sendEnvelope(envelope);\n\n return id;\n }\n\n /**\n * Disposes of the client and releases all resources.\n *\n * This method clears all internal state to allow the client to be garbage collected.\n * It clears hooks, event processors, integrations, transport, and other internal references.\n *\n * Call this method after flushing to allow the client to be garbage collected.\n * After calling dispose(), the client should not be used anymore.\n *\n * Subclasses should override this method to clean up their own resources and call `super.dispose()`.\n */\n public override dispose(): void {\n DEBUG_BUILD && debug.log('Disposing client...');\n\n for (const hookName of Object.keys(this._hooks)) {\n this._hooks[hookName]?.clear();\n }\n\n this._hooks = {};\n this._eventProcessors.length = 0;\n this._integrations = {};\n this._outcomes = {};\n (this as unknown as { _transport?: Transport })._transport = undefined;\n (this as unknown as { _promiseBuffer?: PromiseBuffer<unknown> })._promiseBuffer = undefined;\n }\n\n /**\n * @inheritDoc\n */\n protected _prepareEvent(\n event: Event,\n hint: EventHint,\n currentScope: Scope,\n isolationScope: Scope,\n ): PromiseLike<Event | null> {\n if (this._options.platform) {\n event.platform = event.platform || this._options.platform;\n }\n\n if (this._options.runtime) {\n event.contexts = {\n ...event.contexts,\n runtime: event.contexts?.runtime || this._options.runtime,\n };\n }\n\n if (this._options.serverName) {\n event.server_name = event.server_name || this._options.serverName;\n }\n\n return super._prepareEvent(event, hint, currentScope, isolationScope);\n }\n\n /**\n * Process a server-side metric before it is captured.\n */\n private _setUpMetricsProcessing(): void {\n this.on('processMetric', metric => {\n if (this._options.serverName) {\n metric.attributes = {\n 'server.address': this._options.serverName,\n ...metric.attributes,\n };\n }\n });\n }\n}\n\nfunction setCurrentRequestSessionErroredOrCrashed(eventHint?: EventHint): void {\n const requestSession = getIsolationScope().getScopeData().sdkProcessingMetadata.requestSession;\n if (requestSession) {\n // We mutate instead of doing `setSdkProcessingMetadata` because the http integration stores away a particular\n // isolationScope. If that isolation scope is forked, setting the processing metadata here will not mutate the\n // original isolation scope that the http integration stored away.\n const isHandledException = eventHint?.mechanism?.handled ?? true;\n // A request session can go from \"errored\" -> \"crashed\" but not \"crashed\" -> \"errored\".\n // Crashed (unhandled exception) is worse than errored (handled exception).\n if (isHandledException && requestSession.status !== 'crashed') {\n requestSession.status = 'errored';\n } else if (!isHandledException) {\n requestSession.status = 'crashed';\n }\n }\n}\n"],"names":["Client","registerSpanErrorInstrumentation","addUserAgentToTransportHeaders","eventFromUnknownInput","resolvedSyncPromise","eventFromMessage","uuid4","DEBUG_BUILD","debug","_getTraceInfoFromScope","createCheckInEnvelope","getIsolationScope"],"mappings":"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"}
|
|
@@ -167,8 +167,17 @@ function createLangChainCallbackHandler(options = {}) {
|
|
|
167
167
|
},
|
|
168
168
|
|
|
169
169
|
// Chain Start Handler
|
|
170
|
-
handleChainStart(
|
|
171
|
-
|
|
170
|
+
handleChainStart(
|
|
171
|
+
chain,
|
|
172
|
+
inputs,
|
|
173
|
+
runId,
|
|
174
|
+
_parentRunId,
|
|
175
|
+
_tags,
|
|
176
|
+
_metadata,
|
|
177
|
+
_runType,
|
|
178
|
+
runName,
|
|
179
|
+
) {
|
|
180
|
+
const chainName = runName || chain.name || 'unknown_chain';
|
|
172
181
|
const attributes = {
|
|
173
182
|
[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ai.langchain',
|
|
174
183
|
'langchain.chain.name': chainName,
|