@justanalyticsapp/node 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/client.d.ts +286 -0
  2. package/dist/client.js +681 -0
  3. package/dist/client.js.map +1 -0
  4. package/dist/context.d.ts +126 -0
  5. package/dist/context.js +170 -0
  6. package/dist/context.js.map +1 -0
  7. package/dist/errors.d.ts +135 -0
  8. package/dist/errors.js +180 -0
  9. package/dist/errors.js.map +1 -0
  10. package/dist/index.d.ts +301 -0
  11. package/dist/index.js +314 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/integrations/express.d.ts +77 -0
  14. package/dist/integrations/express.js +87 -0
  15. package/dist/integrations/express.js.map +1 -0
  16. package/dist/integrations/http.d.ts +129 -0
  17. package/dist/integrations/http.js +465 -0
  18. package/dist/integrations/http.js.map +1 -0
  19. package/dist/integrations/metrics.d.ts +110 -0
  20. package/dist/integrations/metrics.js +313 -0
  21. package/dist/integrations/metrics.js.map +1 -0
  22. package/dist/integrations/next.d.ts +252 -0
  23. package/dist/integrations/next.js +480 -0
  24. package/dist/integrations/next.js.map +1 -0
  25. package/dist/integrations/pg.d.ts +169 -0
  26. package/dist/integrations/pg.js +616 -0
  27. package/dist/integrations/pg.js.map +1 -0
  28. package/dist/integrations/pino.d.ts +52 -0
  29. package/dist/integrations/pino.js +153 -0
  30. package/dist/integrations/pino.js.map +1 -0
  31. package/dist/integrations/redis.d.ts +190 -0
  32. package/dist/integrations/redis.js +597 -0
  33. package/dist/integrations/redis.js.map +1 -0
  34. package/dist/integrations/winston.d.ts +48 -0
  35. package/dist/integrations/winston.js +99 -0
  36. package/dist/integrations/winston.js.map +1 -0
  37. package/dist/logger.d.ts +148 -0
  38. package/dist/logger.js +162 -0
  39. package/dist/logger.js.map +1 -0
  40. package/dist/span.d.ts +192 -0
  41. package/dist/span.js +197 -0
  42. package/dist/span.js.map +1 -0
  43. package/dist/transport.d.ts +246 -0
  44. package/dist/transport.js +654 -0
  45. package/dist/transport.js.map +1 -0
  46. package/dist/utils/headers.d.ts +60 -0
  47. package/dist/utils/headers.js +93 -0
  48. package/dist/utils/headers.js.map +1 -0
  49. package/dist/utils/id.d.ts +23 -0
  50. package/dist/utils/id.js +36 -0
  51. package/dist/utils/id.js.map +1 -0
  52. package/package.json +65 -0
@@ -0,0 +1,616 @@
1
+ "use strict";
2
+ /**
3
+ * @file packages/node-sdk/src/integrations/pg.ts
4
+ * @description PostgreSQL auto-instrumentation integration for the JustAnalytics Node.js SDK.
5
+ *
6
+ * Implements Story 039 - PostgreSQL Auto-Instrumentation
7
+ *
8
+ * Monkey-patches `pg.Client.prototype.query`, `pg.Pool.prototype.query`, and
9
+ * `pg.Pool.prototype.connect` to automatically create `db.query` and `db.connect`
10
+ * spans for all PostgreSQL operations. This captures all PostgreSQL traffic regardless
11
+ * of which ORM or query builder sits on top (Prisma, Knex, TypeORM, Sequelize, Drizzle).
12
+ *
13
+ * Follows the same monkey-patching pattern established in Story 036 (HTTP Auto-Instrumentation):
14
+ * - Integration class with `enable()`/`disable()` lifecycle methods
15
+ * - Original function preservation for clean teardown
16
+ * - Integration with AsyncLocalStorage context for automatic parent-child span relationships
17
+ * - Fail-open design: if instrumentation code fails, the original query executes normally
18
+ *
19
+ * SQL sanitization is a critical security requirement: all literal values (strings,
20
+ * numbers, booleans) are replaced with `$?` placeholders. Actual query parameter
21
+ * values are NEVER included in span attributes.
22
+ *
23
+ * References:
24
+ * - OpenTelemetry Database Semantic Conventions (db.system, db.statement, etc.)
25
+ * - Story 035 - Node.js SDK Core (Span, context, transport)
26
+ * - Story 036 - HTTP Auto-Instrumentation (integration pattern)
27
+ */
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.PgIntegration = void 0;
30
+ exports.sanitizeSql = sanitizeSql;
31
+ exports.extractSqlOperation = extractSqlOperation;
32
+ exports.extractTableName = extractTableName;
33
+ exports.sanitizeConnectionString = sanitizeConnectionString;
34
+ const span_1 = require("../span");
35
+ const context_1 = require("../context");
36
+ const id_1 = require("../utils/id");
37
+ // ============================================================================
38
+ // SQL Sanitization Utilities (exported for testing)
39
+ // ============================================================================
40
+ /**
41
+ * Sanitize a SQL query by replacing literal values with placeholders.
42
+ *
43
+ * Rules (applied in order):
44
+ * 1. Strip block comments (/* ... *​/)
45
+ * 2. Strip line comments (-- ...)
46
+ * 3. Replace string literals ('...') with $?
47
+ * 4. Replace numeric literals with $? (preserving $N parameter placeholders)
48
+ * 5. Replace boolean literals (TRUE/FALSE) with $?
49
+ * 6. Normalize whitespace (collapse multiple spaces, trim)
50
+ * 7. Truncate to maxLength
51
+ *
52
+ * @param sql - Raw SQL query string
53
+ * @param maxLength - Maximum length for the sanitized output (default: 2048)
54
+ * @returns Sanitized SQL with literals replaced
55
+ */
56
+ function sanitizeSql(sql, maxLength = 2048) {
57
+ try {
58
+ let result = sql;
59
+ // Step 1: Strip block comments /* ... */
60
+ result = result.replace(/\/\*[\s\S]*?\*\//g, '');
61
+ // Step 2: Strip line comments -- ...
62
+ result = result.replace(/--[^\n]*/g, '');
63
+ // Step 3: Replace string literals (handle escaped quotes like O''Brien)
64
+ result = result.replace(/'(?:[^']|'')*'/g, '$?');
65
+ // Step 4: Replace numeric literals (not preceded by $ for parameter placeholders)
66
+ result = result.replace(/(?<!\$)\b\d+(?:\.\d+)?\b/g, '$?');
67
+ // Step 5: Replace boolean literals
68
+ result = result.replace(/\b(?:TRUE|FALSE|true|false)\b/g, '$?');
69
+ // Step 6: Normalize whitespace
70
+ result = result.replace(/\s+/g, ' ').trim();
71
+ // Step 7: Truncate
72
+ if (result.length > maxLength) {
73
+ result = result.substring(0, maxLength - 3) + '...';
74
+ }
75
+ return result;
76
+ }
77
+ catch {
78
+ // If sanitization fails on malformed SQL, truncate the raw query
79
+ const trimmed = sql.replace(/\s+/g, ' ').trim();
80
+ if (trimmed.length > maxLength) {
81
+ return trimmed.substring(0, maxLength - 3) + '...';
82
+ }
83
+ return trimmed;
84
+ }
85
+ }
86
+ /**
87
+ * Extract the SQL operation keyword from a query string.
88
+ *
89
+ * Handles: SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP,
90
+ * BEGIN, COMMIT, ROLLBACK, TRUNCATE, COPY, EXPLAIN, ANALYZE, WITH (CTE)
91
+ *
92
+ * @param sql - Raw or sanitized SQL query
93
+ * @returns Uppercase operation keyword (e.g., "SELECT"), or "UNKNOWN" if not recognized
94
+ */
95
+ function extractSqlOperation(sql) {
96
+ const trimmed = sql.trimStart();
97
+ const match = trimmed.match(/^(SELECT|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP|BEGIN|COMMIT|ROLLBACK|TRUNCATE|COPY|EXPLAIN|ANALYZE|WITH)\b/i);
98
+ return match ? match[1].toUpperCase() : 'UNKNOWN';
99
+ }
100
+ /**
101
+ * Extract the primary table name from a SQL query (best effort).
102
+ *
103
+ * Patterns handled:
104
+ * - SELECT ... FROM table_name
105
+ * - INSERT INTO table_name
106
+ * - UPDATE table_name
107
+ * - DELETE FROM table_name
108
+ * - Handles schema-qualified names: schema.table
109
+ * - Handles quoted identifiers: "table_name"
110
+ *
111
+ * @param sql - Raw or sanitized SQL query
112
+ * @returns Table name, or null if extraction fails
113
+ */
114
+ function extractTableName(sql) {
115
+ const patterns = [
116
+ /\bFROM\s+(?:"([^"]+)"|(\w+)(?:\.(?:"([^"]+)"|(\w+)))?)/i,
117
+ /\bINTO\s+(?:"([^"]+)"|(\w+)(?:\.(?:"([^"]+)"|(\w+)))?)/i,
118
+ /\bUPDATE\s+(?:"([^"]+)"|(\w+)(?:\.(?:"([^"]+)"|(\w+)))?)/i,
119
+ /\bJOIN\s+(?:"([^"]+)"|(\w+)(?:\.(?:"([^"]+)"|(\w+)))?)/i,
120
+ ];
121
+ for (const pattern of patterns) {
122
+ const match = sql.match(pattern);
123
+ if (match) {
124
+ // Return the last non-undefined capture group (table name after schema)
125
+ const captures = match.slice(1).filter(Boolean);
126
+ return captures.length > 0 ? captures[captures.length - 1] : null;
127
+ }
128
+ }
129
+ return null;
130
+ }
131
+ /**
132
+ * Build a sanitized connection string from pg client config.
133
+ * Replaces password with '***'.
134
+ *
135
+ * @param connStr - Raw connection string potentially containing a password
136
+ * @returns Sanitized connection string with password masked
137
+ */
138
+ function sanitizeConnectionString(connStr) {
139
+ // Replace password in postgresql://user:password@host:port/db format
140
+ return connStr.replace(/^(postgresql:\/\/[^:]+:)([^@]+)(@)/, '$1***$3');
141
+ }
142
+ // ============================================================================
143
+ // Query Argument Normalization
144
+ // ============================================================================
145
+ /**
146
+ * Normalize the various overloaded argument forms of pg.Client.query
147
+ * into a consistent shape.
148
+ *
149
+ * pg supports:
150
+ * - query(text: string, values?: any[], callback?: Function)
151
+ * - query(config: { text: string, values?: any[], name?: string, ... })
152
+ * - query(config: { text: string, ... }, values?: any[], callback?: Function)
153
+ *
154
+ * @param args - The arguments passed to query()
155
+ * @returns { text, callback, isPromise }
156
+ */
157
+ function normalizeQueryArgs(args) {
158
+ let text;
159
+ let callback = null;
160
+ if (typeof args[0] === 'string') {
161
+ text = args[0];
162
+ // Find callback (last function argument)
163
+ for (let i = args.length - 1; i >= 1; i--) {
164
+ if (typeof args[i] === 'function') {
165
+ callback = args[i];
166
+ break;
167
+ }
168
+ }
169
+ }
170
+ else if (typeof args[0] === 'object' && args[0] !== null && 'text' in args[0]) {
171
+ text = args[0].text;
172
+ for (let i = args.length - 1; i >= 1; i--) {
173
+ if (typeof args[i] === 'function') {
174
+ callback = args[i];
175
+ break;
176
+ }
177
+ }
178
+ }
179
+ else {
180
+ text = '';
181
+ }
182
+ return { text, callback, isPromise: callback === null };
183
+ }
184
+ // ============================================================================
185
+ // PgIntegration Class
186
+ // ============================================================================
187
+ /**
188
+ * PgIntegration monkey-patches pg.Client.prototype.query,
189
+ * pg.Pool.prototype.query, and pg.Pool.prototype.connect to auto-create
190
+ * db.query and db.connect spans for all PostgreSQL operations.
191
+ *
192
+ * Follows the same pattern as HttpIntegration (Story 036):
193
+ * - Constructor accepts serviceName, options, onSpanEnd callback
194
+ * - enable() patches, disable() restores
195
+ * - Original functions preserved for clean teardown
196
+ * - Fail-open design: instrumentation failures never crash the host process
197
+ */
198
+ class PgIntegration {
199
+ /**
200
+ * Create a new PgIntegration.
201
+ *
202
+ * @param serviceName - The service name for span attribution
203
+ * @param options - Integration configuration options
204
+ * @param onSpanEnd - Callback invoked when a span ends (enqueues to transport)
205
+ */
206
+ constructor(serviceName, options, onSpanEnd) {
207
+ this._enabled = false;
208
+ // Store original functions for restoration
209
+ this._originalClientQuery = null;
210
+ this._originalPoolQuery = null;
211
+ this._originalPoolConnect = null;
212
+ // Store references to prototypes for restoration
213
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
214
+ this._pgClient = null;
215
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
216
+ this._pgPool = null;
217
+ this._serviceName = serviceName;
218
+ this._onSpanEnd = onSpanEnd;
219
+ // Resolve options with defaults
220
+ const opts = options || {};
221
+ this._options = {
222
+ enabled: opts.enabled !== false,
223
+ maxQueryLength: opts.maxQueryLength ?? 2048,
224
+ };
225
+ }
226
+ /**
227
+ * Activate the integration: load pg module and patch prototypes.
228
+ *
229
+ * Calling enable() when already enabled is a no-op (idempotent).
230
+ */
231
+ enable() {
232
+ if (this._enabled)
233
+ return;
234
+ if (!this._options.enabled)
235
+ return;
236
+ try {
237
+ // Dynamic require: pg is an optional peer dependency
238
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
239
+ let pg;
240
+ try {
241
+ pg = require('pg');
242
+ }
243
+ catch {
244
+ // pg module is not installed -- silently skip
245
+ if (typeof console !== 'undefined') {
246
+ console.debug('[JustAnalytics] pg module not found. Skipping PostgreSQL auto-instrumentation.');
247
+ }
248
+ return;
249
+ }
250
+ const Client = pg.Client;
251
+ const Pool = pg.Pool;
252
+ if (!Client || !Client.prototype) {
253
+ if (typeof console !== 'undefined') {
254
+ console.debug('[JustAnalytics] pg.Client not found. Skipping PostgreSQL auto-instrumentation.');
255
+ }
256
+ return;
257
+ }
258
+ // Store references for restoration
259
+ this._pgClient = Client.prototype;
260
+ this._originalClientQuery = Client.prototype.query;
261
+ // Patch Client.prototype.query
262
+ Client.prototype.query = this._wrapClientQuery(this._originalClientQuery);
263
+ // Patch Pool if available
264
+ if (Pool && Pool.prototype) {
265
+ this._pgPool = Pool.prototype;
266
+ // Patch Pool.prototype.query
267
+ this._originalPoolQuery = Pool.prototype.query;
268
+ Pool.prototype.query = this._wrapPoolQuery(this._originalPoolQuery);
269
+ // Patch Pool.prototype.connect
270
+ this._originalPoolConnect = Pool.prototype.connect;
271
+ Pool.prototype.connect = this._wrapPoolConnect(this._originalPoolConnect);
272
+ }
273
+ this._enabled = true;
274
+ }
275
+ catch (error) {
276
+ // Monkey-patching failed; fall back to no-op and restore any partial patches
277
+ this._restoreOriginals();
278
+ if (typeof console !== 'undefined') {
279
+ console.warn('[JustAnalytics] Failed to enable PostgreSQL integration:', error instanceof Error ? error.message : String(error));
280
+ }
281
+ }
282
+ }
283
+ /**
284
+ * Deactivate: restore original pg functions.
285
+ *
286
+ * Calling disable() when not enabled is a no-op (idempotent).
287
+ */
288
+ disable() {
289
+ if (!this._enabled)
290
+ return;
291
+ this._restoreOriginals();
292
+ this._enabled = false;
293
+ }
294
+ /**
295
+ * Restore all patched functions to their originals.
296
+ */
297
+ _restoreOriginals() {
298
+ if (this._pgClient && this._originalClientQuery) {
299
+ this._pgClient.query = this._originalClientQuery;
300
+ this._originalClientQuery = null;
301
+ this._pgClient = null;
302
+ }
303
+ if (this._pgPool) {
304
+ if (this._originalPoolQuery) {
305
+ this._pgPool.query = this._originalPoolQuery;
306
+ this._originalPoolQuery = null;
307
+ }
308
+ if (this._originalPoolConnect) {
309
+ this._pgPool.connect = this._originalPoolConnect;
310
+ this._originalPoolConnect = null;
311
+ }
312
+ this._pgPool = null;
313
+ }
314
+ }
315
+ /**
316
+ * Wrap pg.Client.prototype.query to create db.query spans.
317
+ *
318
+ * Handles all pg query signatures:
319
+ * 1. client.query(text, callback)
320
+ * 2. client.query(text, values, callback)
321
+ * 3. client.query(text) -- promise
322
+ * 4. client.query(text, values) -- promise
323
+ * 5. client.query(config) -- QueryConfig object, promise
324
+ * 6. client.query(config, callback) -- QueryConfig object, callback
325
+ *
326
+ * @param original - The original query function
327
+ * @returns A wrapped version of the query function
328
+ */
329
+ _wrapClientQuery(original) {
330
+ const integration = this;
331
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
332
+ return function patchedQuery(...args) {
333
+ try {
334
+ const { text, callback, isPromise } = normalizeQueryArgs(args);
335
+ if (!text) {
336
+ return original.apply(this, args);
337
+ }
338
+ // Get active span context
339
+ const parentSpan = (0, context_1.getActiveSpan)();
340
+ const traceId = parentSpan?.traceId ?? (0, id_1.generateTraceId)();
341
+ const parentSpanId = parentSpan?.id ?? null;
342
+ const operation = extractSqlOperation(text);
343
+ const table = extractTableName(text);
344
+ const sanitizedSql = sanitizeSql(text, integration._options.maxQueryLength);
345
+ const operationName = operation !== 'UNKNOWN' ? `db.query ${operation}` : 'db.query';
346
+ // Build attributes (OpenTelemetry Database Semantic Conventions)
347
+ const attributes = {
348
+ 'db.system': 'postgresql',
349
+ 'db.statement': sanitizedSql,
350
+ };
351
+ if (operation !== 'UNKNOWN')
352
+ attributes['db.operation'] = operation;
353
+ if (table)
354
+ attributes['db.sql.table'] = table;
355
+ // Extract connection info from pg Client config
356
+ const config = this.connectionParameters || this._connectionParameters || {};
357
+ if (config.database)
358
+ attributes['db.name'] = config.database;
359
+ if (config.user)
360
+ attributes['db.user'] = config.user;
361
+ // Build sanitized connection string
362
+ if (config.host || config.user || config.database) {
363
+ const host = config.host || 'localhost';
364
+ const port = config.port || 5432;
365
+ const database = config.database || '';
366
+ const user = config.user || '';
367
+ attributes['db.connection_string'] = `postgresql://${user}:***@${host}:${port}/${database}`;
368
+ }
369
+ // Create span
370
+ const span = new span_1.Span({
371
+ operationName,
372
+ serviceName: integration._serviceName,
373
+ kind: 'client',
374
+ traceId,
375
+ parentSpanId,
376
+ attributes,
377
+ });
378
+ if (isPromise) {
379
+ // Promise-style: call original, then end span on resolve/reject
380
+ try {
381
+ const result = original.apply(this, args);
382
+ if (result && typeof result.then === 'function') {
383
+ return result.then((value) => {
384
+ span.end();
385
+ integration._onSpanEnd(span);
386
+ return value;
387
+ }, (error) => {
388
+ span.setStatus('error', error instanceof Error ? error.message : String(error));
389
+ span.end();
390
+ integration._onSpanEnd(span);
391
+ throw error;
392
+ });
393
+ }
394
+ // Sync return (unlikely but defensive)
395
+ span.end();
396
+ integration._onSpanEnd(span);
397
+ return result;
398
+ }
399
+ catch (error) {
400
+ span.setStatus('error', error instanceof Error ? error.message : String(error));
401
+ span.end();
402
+ integration._onSpanEnd(span);
403
+ throw error;
404
+ }
405
+ }
406
+ else {
407
+ // Callback-style: wrap callback to end span
408
+ const wrappedArgs = [...args];
409
+ const cbIndex = wrappedArgs.findIndex((a) => typeof a === 'function');
410
+ if (cbIndex !== -1) {
411
+ const originalCb = wrappedArgs[cbIndex];
412
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
413
+ wrappedArgs[cbIndex] = function wrappedCallback(err, result) {
414
+ if (err) {
415
+ span.setStatus('error', err instanceof Error ? err.message : String(err));
416
+ }
417
+ span.end();
418
+ integration._onSpanEnd(span);
419
+ return originalCb.call(this, err, result);
420
+ };
421
+ }
422
+ return original.apply(this, wrappedArgs);
423
+ }
424
+ }
425
+ catch (error) {
426
+ // If instrumentation code fails, fall through to original
427
+ return original.apply(this, args);
428
+ }
429
+ };
430
+ }
431
+ /**
432
+ * Wrap pg.Pool.prototype.query to create db.query spans.
433
+ *
434
+ * Pool.query is a convenience method that acquires a client, runs the query,
435
+ * and releases the client. We patch it separately to track pool-level queries.
436
+ *
437
+ * @param original - The original Pool.prototype.query function
438
+ * @returns A wrapped version of the query function
439
+ */
440
+ _wrapPoolQuery(original) {
441
+ const integration = this;
442
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
443
+ return function patchedPoolQuery(...args) {
444
+ try {
445
+ const { text, callback, isPromise } = normalizeQueryArgs(args);
446
+ if (!text) {
447
+ return original.apply(this, args);
448
+ }
449
+ // Get active span context
450
+ const parentSpan = (0, context_1.getActiveSpan)();
451
+ const traceId = parentSpan?.traceId ?? (0, id_1.generateTraceId)();
452
+ const parentSpanId = parentSpan?.id ?? null;
453
+ const operation = extractSqlOperation(text);
454
+ const table = extractTableName(text);
455
+ const sanitizedSql = sanitizeSql(text, integration._options.maxQueryLength);
456
+ const operationName = operation !== 'UNKNOWN' ? `db.query ${operation}` : 'db.query';
457
+ // Build attributes
458
+ const attributes = {
459
+ 'db.system': 'postgresql',
460
+ 'db.statement': sanitizedSql,
461
+ };
462
+ if (operation !== 'UNKNOWN')
463
+ attributes['db.operation'] = operation;
464
+ if (table)
465
+ attributes['db.sql.table'] = table;
466
+ // Extract connection info from Pool options
467
+ const poolOptions = this.options || {};
468
+ if (poolOptions.database)
469
+ attributes['db.name'] = poolOptions.database;
470
+ if (poolOptions.user)
471
+ attributes['db.user'] = poolOptions.user;
472
+ if (poolOptions.host || poolOptions.user || poolOptions.database) {
473
+ const host = poolOptions.host || 'localhost';
474
+ const port = poolOptions.port || 5432;
475
+ const database = poolOptions.database || '';
476
+ const user = poolOptions.user || '';
477
+ attributes['db.connection_string'] = `postgresql://${user}:***@${host}:${port}/${database}`;
478
+ }
479
+ // Create span
480
+ const span = new span_1.Span({
481
+ operationName,
482
+ serviceName: integration._serviceName,
483
+ kind: 'client',
484
+ traceId,
485
+ parentSpanId,
486
+ attributes,
487
+ });
488
+ if (isPromise) {
489
+ try {
490
+ const result = original.apply(this, args);
491
+ if (result && typeof result.then === 'function') {
492
+ return result.then((value) => {
493
+ span.end();
494
+ integration._onSpanEnd(span);
495
+ return value;
496
+ }, (error) => {
497
+ span.setStatus('error', error instanceof Error ? error.message : String(error));
498
+ span.end();
499
+ integration._onSpanEnd(span);
500
+ throw error;
501
+ });
502
+ }
503
+ span.end();
504
+ integration._onSpanEnd(span);
505
+ return result;
506
+ }
507
+ catch (error) {
508
+ span.setStatus('error', error instanceof Error ? error.message : String(error));
509
+ span.end();
510
+ integration._onSpanEnd(span);
511
+ throw error;
512
+ }
513
+ }
514
+ else {
515
+ const wrappedArgs = [...args];
516
+ const cbIndex = wrappedArgs.findIndex((a) => typeof a === 'function');
517
+ if (cbIndex !== -1) {
518
+ const originalCb = wrappedArgs[cbIndex];
519
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
520
+ wrappedArgs[cbIndex] = function wrappedCallback(err, result) {
521
+ if (err) {
522
+ span.setStatus('error', err instanceof Error ? err.message : String(err));
523
+ }
524
+ span.end();
525
+ integration._onSpanEnd(span);
526
+ return originalCb.call(this, err, result);
527
+ };
528
+ }
529
+ return original.apply(this, wrappedArgs);
530
+ }
531
+ }
532
+ catch (error) {
533
+ return original.apply(this, args);
534
+ }
535
+ };
536
+ }
537
+ /**
538
+ * Wrap pg.Pool.prototype.connect to create db.connect spans that measure
539
+ * the time to acquire a connection from the pool.
540
+ *
541
+ * @param original - The original Pool.prototype.connect function
542
+ * @returns A wrapped version of the connect function
543
+ */
544
+ _wrapPoolConnect(original) {
545
+ const integration = this;
546
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
547
+ return function patchedPoolConnect(...args) {
548
+ try {
549
+ // Get active span context
550
+ const parentSpan = (0, context_1.getActiveSpan)();
551
+ const traceId = parentSpan?.traceId ?? (0, id_1.generateTraceId)();
552
+ const parentSpanId = parentSpan?.id ?? null;
553
+ // Build attributes
554
+ const attributes = {
555
+ 'db.system': 'postgresql',
556
+ };
557
+ // Extract connection info from Pool options
558
+ const poolOptions = this.options || {};
559
+ if (poolOptions.database)
560
+ attributes['db.name'] = poolOptions.database;
561
+ // Create span
562
+ const span = new span_1.Span({
563
+ operationName: 'db.connect',
564
+ serviceName: integration._serviceName,
565
+ kind: 'client',
566
+ traceId,
567
+ parentSpanId,
568
+ attributes,
569
+ });
570
+ // Check if callback-style or promise-style
571
+ const callback = typeof args[args.length - 1] === 'function'
572
+ ? args[args.length - 1]
573
+ : null;
574
+ if (callback) {
575
+ // Callback-style
576
+ const wrappedArgs = [...args];
577
+ wrappedArgs[wrappedArgs.length - 1] = function wrappedConnectCallback(err, client, release) {
578
+ if (err) {
579
+ span.setStatus('error', err instanceof Error ? err.message : String(err));
580
+ }
581
+ span.end();
582
+ integration._onSpanEnd(span);
583
+ return callback.call(this, err, client, release);
584
+ };
585
+ return original.apply(this, wrappedArgs);
586
+ }
587
+ else {
588
+ // Promise-style
589
+ const result = original.apply(this, args);
590
+ if (result && typeof result.then === 'function') {
591
+ return result.then((client) => {
592
+ span.end();
593
+ integration._onSpanEnd(span);
594
+ return client;
595
+ }, (error) => {
596
+ span.setStatus('error', error instanceof Error ? error.message : String(error));
597
+ span.end();
598
+ integration._onSpanEnd(span);
599
+ throw error;
600
+ });
601
+ }
602
+ // Sync return (unlikely)
603
+ span.end();
604
+ integration._onSpanEnd(span);
605
+ return result;
606
+ }
607
+ }
608
+ catch (error) {
609
+ // If instrumentation code fails, fall through to original
610
+ return original.apply(this, args);
611
+ }
612
+ };
613
+ }
614
+ }
615
+ exports.PgIntegration = PgIntegration;
616
+ //# sourceMappingURL=pg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg.js","sourceRoot":"","sources":["../../src/integrations/pg.ts"],"names":[],"mappings":"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"}