@vestig/next 0.18.0 → 0.20.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/dist/db/index.d.ts +2 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +2 -0
- package/dist/db/index.js.map +1 -1
- package/dist/db/postgres.d.ts +123 -0
- package/dist/db/postgres.d.ts.map +1 -0
- package/dist/db/postgres.js +298 -0
- package/dist/db/postgres.js.map +1 -0
- package/dist/db/types.d.ts +36 -0
- package/dist/db/types.d.ts.map +1 -1
- package/dist/instrumentation/register.d.ts +13 -0
- package/dist/instrumentation/register.d.ts.map +1 -1
- package/dist/instrumentation/register.js +54 -0
- package/dist/instrumentation/register.js.map +1 -1
- package/dist/instrumentation/types.d.ts +35 -0
- package/dist/instrumentation/types.d.ts.map +1 -1
- package/dist/wide-events/context.d.ts.map +1 -1
- package/dist/wide-events/context.js +3 -1
- package/dist/wide-events/context.js.map +1 -1
- package/package.json +2 -2
package/dist/db/index.d.ts
CHANGED
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
*/
|
|
45
45
|
export { withVestigPrisma, createPrismaQueryHandler, createPrismaLogConfig, type VestigPrismaOptions, } from './prisma';
|
|
46
46
|
export { createVestigDrizzleLogger, createDrizzleQueryLogger, measureQuery, type VestigDrizzleLoggerOptions, } from './drizzle';
|
|
47
|
+
export { instrumentPostgres, isPostgresInstrumented, type PostgresInstrumentConfig, } from './postgres';
|
|
47
48
|
export { formatDuration, createQueryLogEntry, logQuery, mergeConfig, extractAllTableNames, } from './query-logger';
|
|
48
|
-
export type { QueryLogEntry, DbLoggerConfig, PrismaQueryEvent, PrismaLogEvent, DrizzleLogger, } from './types';
|
|
49
|
+
export type { QueryLogEntry, DbLoggerConfig, DatabaseInstrumentConfig, PrismaQueryEvent, PrismaLogEvent, DrizzleLogger, } from './types';
|
|
49
50
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/db/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAGH,OAAO,EACN,gBAAgB,EAChB,wBAAwB,EACxB,qBAAqB,EACrB,KAAK,mBAAmB,GACxB,MAAM,UAAU,CAAA;AAGjB,OAAO,EACN,yBAAyB,EACzB,wBAAwB,EACxB,YAAY,EACZ,KAAK,0BAA0B,GAC/B,MAAM,WAAW,CAAA;AAGlB,OAAO,EACN,cAAc,EACd,mBAAmB,EACnB,QAAQ,EACR,WAAW,EACX,oBAAoB,GACpB,MAAM,gBAAgB,CAAA;AAGvB,YAAY,EACX,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,aAAa,GACb,MAAM,SAAS,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAGH,OAAO,EACN,gBAAgB,EAChB,wBAAwB,EACxB,qBAAqB,EACrB,KAAK,mBAAmB,GACxB,MAAM,UAAU,CAAA;AAGjB,OAAO,EACN,yBAAyB,EACzB,wBAAwB,EACxB,YAAY,EACZ,KAAK,0BAA0B,GAC/B,MAAM,WAAW,CAAA;AAGlB,OAAO,EACN,kBAAkB,EAClB,sBAAsB,EACtB,KAAK,wBAAwB,GAC7B,MAAM,YAAY,CAAA;AAGnB,OAAO,EACN,cAAc,EACd,mBAAmB,EACnB,QAAQ,EACR,WAAW,EACX,oBAAoB,GACpB,MAAM,gBAAgB,CAAA;AAGvB,YAAY,EACX,aAAa,EACb,cAAc,EACd,wBAAwB,EACxB,gBAAgB,EAChB,cAAc,EACd,aAAa,GACb,MAAM,SAAS,CAAA"}
|
package/dist/db/index.js
CHANGED
|
@@ -46,6 +46,8 @@
|
|
|
46
46
|
export { withVestigPrisma, createPrismaQueryHandler, createPrismaLogConfig, } from './prisma';
|
|
47
47
|
// Drizzle integration
|
|
48
48
|
export { createVestigDrizzleLogger, createDrizzleQueryLogger, measureQuery, } from './drizzle';
|
|
49
|
+
// PostgreSQL driver instrumentation
|
|
50
|
+
export { instrumentPostgres, isPostgresInstrumented, } from './postgres';
|
|
49
51
|
// Core utilities
|
|
50
52
|
export { formatDuration, createQueryLogEntry, logQuery, mergeConfig, extractAllTableNames, } from './query-logger';
|
|
51
53
|
//# sourceMappingURL=index.js.map
|
package/dist/db/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,qBAAqB;AACrB,OAAO,EACN,gBAAgB,EAChB,wBAAwB,EACxB,qBAAqB,GAErB,MAAM,UAAU,CAAA;AAEjB,sBAAsB;AACtB,OAAO,EACN,yBAAyB,EACzB,wBAAwB,EACxB,YAAY,GAEZ,MAAM,WAAW,CAAA;AAElB,iBAAiB;AACjB,OAAO,EACN,cAAc,EACd,mBAAmB,EACnB,QAAQ,EACR,WAAW,EACX,oBAAoB,GACpB,MAAM,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,qBAAqB;AACrB,OAAO,EACN,gBAAgB,EAChB,wBAAwB,EACxB,qBAAqB,GAErB,MAAM,UAAU,CAAA;AAEjB,sBAAsB;AACtB,OAAO,EACN,yBAAyB,EACzB,wBAAwB,EACxB,YAAY,GAEZ,MAAM,WAAW,CAAA;AAElB,oCAAoC;AACpC,OAAO,EACN,kBAAkB,EAClB,sBAAsB,GAEtB,MAAM,YAAY,CAAA;AAEnB,iBAAiB;AACjB,OAAO,EACN,cAAc,EACd,mBAAmB,EACnB,QAAQ,EACR,WAAW,EACX,oBAAoB,GACpB,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostgreSQL Auto-Instrumentation
|
|
3
|
+
*
|
|
4
|
+
* Wraps postgres-js client for automatic span creation and metrics.
|
|
5
|
+
* Provides precise timing measurement by wrapping at the driver level.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import postgres from 'postgres'
|
|
10
|
+
* import { instrumentPostgres } from '@vestig/next/db'
|
|
11
|
+
* import { drizzle } from 'drizzle-orm/postgres-js'
|
|
12
|
+
*
|
|
13
|
+
* const client = instrumentPostgres(postgres(DATABASE_URL), {
|
|
14
|
+
* slowQueryThreshold: 100,
|
|
15
|
+
* onQuery: (entry) => {
|
|
16
|
+
* if (entry.isSlow) metrics.recordSlowQuery(entry)
|
|
17
|
+
* }
|
|
18
|
+
* })
|
|
19
|
+
*
|
|
20
|
+
* export const db = drizzle(client)
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @packageDocumentation
|
|
24
|
+
*/
|
|
25
|
+
import type { DbLoggerConfig } from './types';
|
|
26
|
+
/**
|
|
27
|
+
* Configuration for postgres-js instrumentation
|
|
28
|
+
*/
|
|
29
|
+
export interface PostgresInstrumentConfig extends DbLoggerConfig {
|
|
30
|
+
/**
|
|
31
|
+
* Database system name for OTLP semantic conventions
|
|
32
|
+
* @default 'postgresql'
|
|
33
|
+
*/
|
|
34
|
+
dbSystem?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Database name for OTLP attributes
|
|
37
|
+
*/
|
|
38
|
+
dbName?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Connection string or identifier (will be sanitized)
|
|
41
|
+
* Used for debugging, credentials are removed
|
|
42
|
+
*/
|
|
43
|
+
connectionName?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Type for postgres-js Sql client
|
|
47
|
+
* We use a minimal interface to avoid requiring postgres as a dependency
|
|
48
|
+
*/
|
|
49
|
+
interface PostgresSql {
|
|
50
|
+
(strings: TemplateStringsArray, ...values: unknown[]): Promise<unknown[]>;
|
|
51
|
+
unsafe: (query: string, params?: unknown[]) => Promise<unknown[]>;
|
|
52
|
+
begin: <T>(fn: (sql: PostgresSql) => Promise<T>) => Promise<T>;
|
|
53
|
+
end: (options?: {
|
|
54
|
+
timeout?: number;
|
|
55
|
+
}) => Promise<void>;
|
|
56
|
+
file: (path: string, options?: unknown) => Promise<unknown[]>;
|
|
57
|
+
[key: string]: unknown;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Instrument a postgres-js client for automatic span creation and metrics
|
|
61
|
+
*
|
|
62
|
+
* This function wraps the postgres-js client to automatically:
|
|
63
|
+
* - Create OTLP spans for each query
|
|
64
|
+
* - Measure precise query duration
|
|
65
|
+
* - Detect slow queries
|
|
66
|
+
* - Call the onQuery callback for external metrics
|
|
67
|
+
*
|
|
68
|
+
* @example Basic usage
|
|
69
|
+
* ```typescript
|
|
70
|
+
* import postgres from 'postgres'
|
|
71
|
+
* import { instrumentPostgres } from '@vestig/next/db'
|
|
72
|
+
*
|
|
73
|
+
* const sql = instrumentPostgres(postgres(DATABASE_URL))
|
|
74
|
+
*
|
|
75
|
+
* // All queries now create spans automatically
|
|
76
|
+
* const users = await sql`SELECT * FROM users`
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* @example With Drizzle ORM
|
|
80
|
+
* ```typescript
|
|
81
|
+
* import postgres from 'postgres'
|
|
82
|
+
* import { instrumentPostgres } from '@vestig/next/db'
|
|
83
|
+
* import { drizzle } from 'drizzle-orm/postgres-js'
|
|
84
|
+
*
|
|
85
|
+
* const client = instrumentPostgres(postgres(DATABASE_URL), {
|
|
86
|
+
* slowQueryThreshold: 100,
|
|
87
|
+
* onQuery: (entry) => {
|
|
88
|
+
* // Send to your metrics system for noisy neighbor detection
|
|
89
|
+
* if (entry.isSlow) {
|
|
90
|
+
* metrics.recordSlowQuery({
|
|
91
|
+
* table: entry.table,
|
|
92
|
+
* operation: entry.operation,
|
|
93
|
+
* duration: entry.duration,
|
|
94
|
+
* })
|
|
95
|
+
* }
|
|
96
|
+
* }
|
|
97
|
+
* })
|
|
98
|
+
*
|
|
99
|
+
* export const db = drizzle(client)
|
|
100
|
+
* ```
|
|
101
|
+
*
|
|
102
|
+
* @example With custom database name
|
|
103
|
+
* ```typescript
|
|
104
|
+
* const sql = instrumentPostgres(postgres(DATABASE_URL), {
|
|
105
|
+
* dbName: 'myapp_production',
|
|
106
|
+
* dbSystem: 'postgresql',
|
|
107
|
+
* })
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* @param client - The postgres-js client instance
|
|
111
|
+
* @param options - Configuration options
|
|
112
|
+
* @returns Instrumented postgres-js client with the same interface
|
|
113
|
+
*/
|
|
114
|
+
export declare function instrumentPostgres<T extends PostgresSql>(client: T, options?: PostgresInstrumentConfig): T;
|
|
115
|
+
/**
|
|
116
|
+
* Check if a postgres-js client is instrumented
|
|
117
|
+
*
|
|
118
|
+
* Note: This is a best-effort check. Due to Proxy transparency,
|
|
119
|
+
* it's not always possible to detect instrumentation.
|
|
120
|
+
*/
|
|
121
|
+
export declare function isPostgresInstrumented(client: unknown): boolean;
|
|
122
|
+
export {};
|
|
123
|
+
//# sourceMappingURL=postgres.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/db/postgres.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7C;;GAEG;AACH,MAAM,WAAW,wBAAyB,SAAQ,cAAc;IAC/D;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;;GAGG;AACH,UAAU,WAAW;IAEpB,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;IAGzE,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;IACjE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IAC9D,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACtD,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;IAG7D,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACtB;AAyLD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,WAAW,EACvD,MAAM,EAAE,CAAC,EACT,OAAO,CAAC,EAAE,wBAAwB,GAChC,CAAC,CA2EH;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAI/D"}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostgreSQL Auto-Instrumentation
|
|
3
|
+
*
|
|
4
|
+
* Wraps postgres-js client for automatic span creation and metrics.
|
|
5
|
+
* Provides precise timing measurement by wrapping at the driver level.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import postgres from 'postgres'
|
|
10
|
+
* import { instrumentPostgres } from '@vestig/next/db'
|
|
11
|
+
* import { drizzle } from 'drizzle-orm/postgres-js'
|
|
12
|
+
*
|
|
13
|
+
* const client = instrumentPostgres(postgres(DATABASE_URL), {
|
|
14
|
+
* slowQueryThreshold: 100,
|
|
15
|
+
* onQuery: (entry) => {
|
|
16
|
+
* if (entry.isSlow) metrics.recordSlowQuery(entry)
|
|
17
|
+
* }
|
|
18
|
+
* })
|
|
19
|
+
*
|
|
20
|
+
* export const db = drizzle(client)
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @packageDocumentation
|
|
24
|
+
*/
|
|
25
|
+
import { span } from 'vestig';
|
|
26
|
+
import { getDatabaseConfig } from '../instrumentation/register';
|
|
27
|
+
import { createQueryLogEntry, mergeConfig } from './query-logger';
|
|
28
|
+
/**
|
|
29
|
+
* Build a parameterized query string from template literal parts
|
|
30
|
+
*/
|
|
31
|
+
function buildQueryString(strings, values) {
|
|
32
|
+
let result = strings[0] ?? '';
|
|
33
|
+
for (let i = 0; i < values.length; i++) {
|
|
34
|
+
result += `$${i + 1}${strings[i + 1] ?? ''}`;
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Execute an instrumented query with span creation
|
|
40
|
+
*/
|
|
41
|
+
async function instrumentedQuery(target, args, state) {
|
|
42
|
+
const [strings, ...values] = args;
|
|
43
|
+
const query = buildQueryString(strings, values);
|
|
44
|
+
// Create initial entry (duration will be updated after execution)
|
|
45
|
+
const entry = createQueryLogEntry(query, values, 0, state.config);
|
|
46
|
+
const spanName = `db.query ${entry.operation}${entry.table ? ` ${entry.table}` : ''}`;
|
|
47
|
+
return span(spanName, async (s) => {
|
|
48
|
+
// Set OpenTelemetry semantic conventions for database
|
|
49
|
+
s.setAttribute('db.system', state.dbSystem);
|
|
50
|
+
s.setAttribute('db.operation', entry.operation);
|
|
51
|
+
s.setAttribute('db.statement', entry.query);
|
|
52
|
+
if (entry.table)
|
|
53
|
+
s.setAttribute('db.sql.table', entry.table);
|
|
54
|
+
if (state.dbName)
|
|
55
|
+
s.setAttribute('db.name', state.dbName);
|
|
56
|
+
const start = performance.now();
|
|
57
|
+
try {
|
|
58
|
+
// Call original postgres-js function
|
|
59
|
+
const result = (await Reflect.apply(target, target, args));
|
|
60
|
+
const duration = performance.now() - start;
|
|
61
|
+
// Update entry with real duration
|
|
62
|
+
entry.duration = duration;
|
|
63
|
+
entry.isSlow = duration >= state.config.slowQueryThreshold;
|
|
64
|
+
// Set span attributes
|
|
65
|
+
s.setAttribute('db.duration_ms', Math.round(duration));
|
|
66
|
+
if (Array.isArray(result)) {
|
|
67
|
+
s.setAttribute('db.rows_affected', result.length);
|
|
68
|
+
}
|
|
69
|
+
if (entry.isSlow) {
|
|
70
|
+
s.setAttribute('db.slow_query', true);
|
|
71
|
+
}
|
|
72
|
+
s.setStatus('ok');
|
|
73
|
+
// Call user callback with complete entry
|
|
74
|
+
state.config.onQuery(entry);
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
const duration = performance.now() - start;
|
|
79
|
+
entry.duration = duration;
|
|
80
|
+
s.setAttribute('db.duration_ms', Math.round(duration));
|
|
81
|
+
s.setAttribute('db.error', true);
|
|
82
|
+
s.setStatus('error', error instanceof Error ? error.message : String(error));
|
|
83
|
+
// Still call callback on error
|
|
84
|
+
state.config.onQuery(entry);
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Execute an instrumented unsafe query
|
|
91
|
+
*/
|
|
92
|
+
async function instrumentedUnsafe(unsafeFn, query, params, state) {
|
|
93
|
+
const entry = createQueryLogEntry(query, params ?? [], 0, state.config);
|
|
94
|
+
const spanName = `db.query.unsafe ${entry.operation}${entry.table ? ` ${entry.table}` : ''}`;
|
|
95
|
+
return span(spanName, async (s) => {
|
|
96
|
+
s.setAttribute('db.system', state.dbSystem);
|
|
97
|
+
s.setAttribute('db.operation', entry.operation);
|
|
98
|
+
s.setAttribute('db.statement', entry.query);
|
|
99
|
+
s.setAttribute('db.query_type', 'unsafe');
|
|
100
|
+
if (entry.table)
|
|
101
|
+
s.setAttribute('db.sql.table', entry.table);
|
|
102
|
+
if (state.dbName)
|
|
103
|
+
s.setAttribute('db.name', state.dbName);
|
|
104
|
+
const start = performance.now();
|
|
105
|
+
try {
|
|
106
|
+
const result = await unsafeFn(query, params);
|
|
107
|
+
const duration = performance.now() - start;
|
|
108
|
+
entry.duration = duration;
|
|
109
|
+
entry.isSlow = duration >= state.config.slowQueryThreshold;
|
|
110
|
+
s.setAttribute('db.duration_ms', Math.round(duration));
|
|
111
|
+
if (Array.isArray(result)) {
|
|
112
|
+
s.setAttribute('db.rows_affected', result.length);
|
|
113
|
+
}
|
|
114
|
+
if (entry.isSlow) {
|
|
115
|
+
s.setAttribute('db.slow_query', true);
|
|
116
|
+
}
|
|
117
|
+
s.setStatus('ok');
|
|
118
|
+
state.config.onQuery(entry);
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
const duration = performance.now() - start;
|
|
123
|
+
entry.duration = duration;
|
|
124
|
+
s.setAttribute('db.duration_ms', Math.round(duration));
|
|
125
|
+
s.setAttribute('db.error', true);
|
|
126
|
+
s.setStatus('error', error instanceof Error ? error.message : String(error));
|
|
127
|
+
state.config.onQuery(entry);
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Create an instrumented begin (transaction) wrapper
|
|
134
|
+
*/
|
|
135
|
+
function createInstrumentedBegin(originalBegin, state) {
|
|
136
|
+
return async (fn) => {
|
|
137
|
+
return span('db.transaction', async (s) => {
|
|
138
|
+
s.setAttribute('db.system', state.dbSystem);
|
|
139
|
+
s.setAttribute('db.operation', 'TRANSACTION');
|
|
140
|
+
if (state.dbName)
|
|
141
|
+
s.setAttribute('db.name', state.dbName);
|
|
142
|
+
const start = performance.now();
|
|
143
|
+
try {
|
|
144
|
+
// Wrap the inner sql client passed to the transaction
|
|
145
|
+
const result = await originalBegin(async (txSql) => {
|
|
146
|
+
// Create instrumented version for transaction queries
|
|
147
|
+
const instrumentedTxSql = instrumentPostgres(txSql, {
|
|
148
|
+
...state.config,
|
|
149
|
+
dbSystem: state.dbSystem,
|
|
150
|
+
dbName: state.dbName,
|
|
151
|
+
});
|
|
152
|
+
return fn(instrumentedTxSql);
|
|
153
|
+
});
|
|
154
|
+
const duration = performance.now() - start;
|
|
155
|
+
s.setAttribute('db.duration_ms', Math.round(duration));
|
|
156
|
+
s.setStatus('ok');
|
|
157
|
+
return result;
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
const duration = performance.now() - start;
|
|
161
|
+
s.setAttribute('db.duration_ms', Math.round(duration));
|
|
162
|
+
s.setAttribute('db.error', true);
|
|
163
|
+
s.setAttribute('db.transaction_rollback', true);
|
|
164
|
+
s.setStatus('error', error instanceof Error ? error.message : String(error));
|
|
165
|
+
throw error;
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Instrument a postgres-js client for automatic span creation and metrics
|
|
172
|
+
*
|
|
173
|
+
* This function wraps the postgres-js client to automatically:
|
|
174
|
+
* - Create OTLP spans for each query
|
|
175
|
+
* - Measure precise query duration
|
|
176
|
+
* - Detect slow queries
|
|
177
|
+
* - Call the onQuery callback for external metrics
|
|
178
|
+
*
|
|
179
|
+
* @example Basic usage
|
|
180
|
+
* ```typescript
|
|
181
|
+
* import postgres from 'postgres'
|
|
182
|
+
* import { instrumentPostgres } from '@vestig/next/db'
|
|
183
|
+
*
|
|
184
|
+
* const sql = instrumentPostgres(postgres(DATABASE_URL))
|
|
185
|
+
*
|
|
186
|
+
* // All queries now create spans automatically
|
|
187
|
+
* const users = await sql`SELECT * FROM users`
|
|
188
|
+
* ```
|
|
189
|
+
*
|
|
190
|
+
* @example With Drizzle ORM
|
|
191
|
+
* ```typescript
|
|
192
|
+
* import postgres from 'postgres'
|
|
193
|
+
* import { instrumentPostgres } from '@vestig/next/db'
|
|
194
|
+
* import { drizzle } from 'drizzle-orm/postgres-js'
|
|
195
|
+
*
|
|
196
|
+
* const client = instrumentPostgres(postgres(DATABASE_URL), {
|
|
197
|
+
* slowQueryThreshold: 100,
|
|
198
|
+
* onQuery: (entry) => {
|
|
199
|
+
* // Send to your metrics system for noisy neighbor detection
|
|
200
|
+
* if (entry.isSlow) {
|
|
201
|
+
* metrics.recordSlowQuery({
|
|
202
|
+
* table: entry.table,
|
|
203
|
+
* operation: entry.operation,
|
|
204
|
+
* duration: entry.duration,
|
|
205
|
+
* })
|
|
206
|
+
* }
|
|
207
|
+
* }
|
|
208
|
+
* })
|
|
209
|
+
*
|
|
210
|
+
* export const db = drizzle(client)
|
|
211
|
+
* ```
|
|
212
|
+
*
|
|
213
|
+
* @example With custom database name
|
|
214
|
+
* ```typescript
|
|
215
|
+
* const sql = instrumentPostgres(postgres(DATABASE_URL), {
|
|
216
|
+
* dbName: 'myapp_production',
|
|
217
|
+
* dbSystem: 'postgresql',
|
|
218
|
+
* })
|
|
219
|
+
* ```
|
|
220
|
+
*
|
|
221
|
+
* @param client - The postgres-js client instance
|
|
222
|
+
* @param options - Configuration options
|
|
223
|
+
* @returns Instrumented postgres-js client with the same interface
|
|
224
|
+
*/
|
|
225
|
+
export function instrumentPostgres(client, options) {
|
|
226
|
+
// Merge with global config from registerVestig() if available
|
|
227
|
+
const globalConfig = getDatabaseConfig();
|
|
228
|
+
const mergedOptions = { ...globalConfig, ...options };
|
|
229
|
+
const config = mergeConfig(mergedOptions);
|
|
230
|
+
const dbSystem = mergedOptions?.dbSystem ?? 'postgresql';
|
|
231
|
+
const dbName = mergedOptions?.dbName;
|
|
232
|
+
const state = {
|
|
233
|
+
config,
|
|
234
|
+
dbSystem,
|
|
235
|
+
dbName,
|
|
236
|
+
};
|
|
237
|
+
// Create a proxy that intercepts both template literal calls and method access
|
|
238
|
+
return new Proxy(client, {
|
|
239
|
+
// Handle template literal calls: sql`SELECT * FROM users`
|
|
240
|
+
apply(target, _thisArg, args) {
|
|
241
|
+
return instrumentedQuery(target, args, state);
|
|
242
|
+
},
|
|
243
|
+
// Handle method access: sql.unsafe(), sql.begin(), etc.
|
|
244
|
+
get(target, prop, receiver) {
|
|
245
|
+
const value = Reflect.get(target, prop, receiver);
|
|
246
|
+
// Wrap special postgres-js methods
|
|
247
|
+
if (prop === 'unsafe' && typeof value === 'function') {
|
|
248
|
+
return (query, params) => {
|
|
249
|
+
return instrumentedUnsafe(value.bind(target), query, params, state);
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
if (prop === 'begin' && typeof value === 'function') {
|
|
253
|
+
return createInstrumentedBegin(value.bind(target), state);
|
|
254
|
+
}
|
|
255
|
+
// For file() - wrap with basic span
|
|
256
|
+
if (prop === 'file' && typeof value === 'function') {
|
|
257
|
+
return async (path, fileOptions) => {
|
|
258
|
+
return span(`db.file ${path}`, async (s) => {
|
|
259
|
+
s.setAttribute('db.system', state.dbSystem);
|
|
260
|
+
s.setAttribute('db.operation', 'FILE');
|
|
261
|
+
s.setAttribute('db.file_path', path);
|
|
262
|
+
if (state.dbName)
|
|
263
|
+
s.setAttribute('db.name', state.dbName);
|
|
264
|
+
const start = performance.now();
|
|
265
|
+
try {
|
|
266
|
+
const result = await value.call(target, path, fileOptions);
|
|
267
|
+
const duration = performance.now() - start;
|
|
268
|
+
s.setAttribute('db.duration_ms', Math.round(duration));
|
|
269
|
+
s.setStatus('ok');
|
|
270
|
+
return result;
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
const duration = performance.now() - start;
|
|
274
|
+
s.setAttribute('db.duration_ms', Math.round(duration));
|
|
275
|
+
s.setAttribute('db.error', true);
|
|
276
|
+
s.setStatus('error', error instanceof Error ? error.message : String(error));
|
|
277
|
+
throw error;
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
// Pass through all other properties unchanged
|
|
283
|
+
return value;
|
|
284
|
+
},
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Check if a postgres-js client is instrumented
|
|
289
|
+
*
|
|
290
|
+
* Note: This is a best-effort check. Due to Proxy transparency,
|
|
291
|
+
* it's not always possible to detect instrumentation.
|
|
292
|
+
*/
|
|
293
|
+
export function isPostgresInstrumented(client) {
|
|
294
|
+
// Proxy objects don't have a reliable way to detect them
|
|
295
|
+
// This is mainly for documentation purposes
|
|
296
|
+
return typeof client === 'function' && 'unsafe' in client;
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=postgres.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../src/db/postgres.ts"],"names":[],"mappings":"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"}
|
package/dist/db/types.d.ts
CHANGED
|
@@ -99,4 +99,40 @@ export declare const SENSITIVE_PATTERNS: RegExp[];
|
|
|
99
99
|
* Check if a parameter name is sensitive
|
|
100
100
|
*/
|
|
101
101
|
export declare function isSensitiveParam(name: string): boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Configuration for database auto-instrumentation
|
|
104
|
+
*
|
|
105
|
+
* Used with registerVestig() to configure database instrumentation
|
|
106
|
+
* from the instrumentation.ts file.
|
|
107
|
+
*/
|
|
108
|
+
export interface DatabaseInstrumentConfig {
|
|
109
|
+
/**
|
|
110
|
+
* Slow query threshold in milliseconds
|
|
111
|
+
* Queries exceeding this will be marked as slow
|
|
112
|
+
* @default 100
|
|
113
|
+
*/
|
|
114
|
+
slowQueryThreshold?: number;
|
|
115
|
+
/**
|
|
116
|
+
* Log level for query logging
|
|
117
|
+
* - 'all': Log all queries
|
|
118
|
+
* - 'slow': Only log slow queries
|
|
119
|
+
* - 'none': Disable logging (spans still created)
|
|
120
|
+
* @default 'slow' in production, 'all' in development
|
|
121
|
+
*/
|
|
122
|
+
logLevel?: 'all' | 'slow' | 'none';
|
|
123
|
+
/**
|
|
124
|
+
* Callback when a query completes
|
|
125
|
+
* Use this for external metrics (e.g., noisy neighbor detection)
|
|
126
|
+
*/
|
|
127
|
+
onQuery?: (entry: QueryLogEntry) => void;
|
|
128
|
+
/**
|
|
129
|
+
* Database system for OTLP semantic attributes
|
|
130
|
+
* @default 'postgresql'
|
|
131
|
+
*/
|
|
132
|
+
dbSystem?: string;
|
|
133
|
+
/**
|
|
134
|
+
* Database name for OTLP attributes
|
|
135
|
+
*/
|
|
136
|
+
dbName?: string;
|
|
137
|
+
}
|
|
102
138
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/db/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/db/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,sBAAsB;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,oBAAoB;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,mCAAmC;IACnC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAA;IAClB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,kDAAkD;IAClD,MAAM,EAAE,OAAO,CAAA;IACf,8BAA8B;IAC9B,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAA;IAC9D,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mCAAmC;IACnC,OAAO,CAAC,EAAE;QACT,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,OAAO,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACD;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAA;IAClC;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;CACxC;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B,SAAS,EAAE,IAAI,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC9B,SAAS,EAAE,IAAI,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACd,CAAA;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;CAChD;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,UAU9B,CAAA;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/db/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,sBAAsB;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,oBAAoB;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,mCAAmC;IACnC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAA;IAClB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,kDAAkD;IAClD,MAAM,EAAE,OAAO,CAAA;IACf,8BAA8B;IAC9B,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAA;IAC9D,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mCAAmC;IACnC,OAAO,CAAC,EAAE;QACT,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,OAAO,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACD;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAA;IAClC;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;CACxC;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B,SAAS,EAAE,IAAI,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC9B,SAAS,EAAE,IAAI,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACd,CAAA;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;CAChD;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,UAU9B,CAAA;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACxC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAE3B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAA;IAElC;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IAExC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;CACf"}
|
|
@@ -3,7 +3,20 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Call in your instrumentation.ts file for complete auto-instrumentation.
|
|
5
5
|
*/
|
|
6
|
+
import type { DatabaseInstrumentConfig } from '../db/types';
|
|
6
7
|
import type { RegisterVestigOptions, RegisterVestigResult } from './types';
|
|
8
|
+
/**
|
|
9
|
+
* Get the global database configuration
|
|
10
|
+
*
|
|
11
|
+
* Used internally by instrumentPostgres() to get default config
|
|
12
|
+
*/
|
|
13
|
+
export declare function getDatabaseConfig(): DatabaseInstrumentConfig | null;
|
|
14
|
+
/**
|
|
15
|
+
* Set the global database configuration
|
|
16
|
+
*
|
|
17
|
+
* Called by registerVestig() when database config is provided
|
|
18
|
+
*/
|
|
19
|
+
export declare function setDatabaseConfig(config: DatabaseInstrumentConfig | null): void;
|
|
7
20
|
/**
|
|
8
21
|
* Register vestig for Next.js instrumentation
|
|
9
22
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/instrumentation/register.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAGX,qBAAqB,EACrB,oBAAoB,EACpB,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/instrumentation/register.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,KAAK,EAGX,qBAAqB,EACrB,oBAAoB,EACpB,MAAM,SAAS,CAAA;AAUhB;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,wBAAwB,GAAG,IAAI,CAEnE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,wBAAwB,GAAG,IAAI,GAAG,IAAI,CAE/E;AAkMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,oBAAoB,CAsDnF"}
|
|
@@ -5,6 +5,29 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { instrumentFetch, registerSpanProcessor, shutdownSpanProcessors, } from 'vestig';
|
|
7
7
|
import { OTLPExporter } from 'vestig/otlp';
|
|
8
|
+
/**
|
|
9
|
+
* Global database configuration store
|
|
10
|
+
*
|
|
11
|
+
* This allows instrumentPostgres() to pick up the config set by registerVestig()
|
|
12
|
+
* without requiring users to pass it explicitly.
|
|
13
|
+
*/
|
|
14
|
+
let globalDatabaseConfig = null;
|
|
15
|
+
/**
|
|
16
|
+
* Get the global database configuration
|
|
17
|
+
*
|
|
18
|
+
* Used internally by instrumentPostgres() to get default config
|
|
19
|
+
*/
|
|
20
|
+
export function getDatabaseConfig() {
|
|
21
|
+
return globalDatabaseConfig;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Set the global database configuration
|
|
25
|
+
*
|
|
26
|
+
* Called by registerVestig() when database config is provided
|
|
27
|
+
*/
|
|
28
|
+
export function setDatabaseConfig(config) {
|
|
29
|
+
globalDatabaseConfig = config;
|
|
30
|
+
}
|
|
8
31
|
/**
|
|
9
32
|
* Parse OTEL headers from environment variable
|
|
10
33
|
* Format: key1=value1,key2=value2
|
|
@@ -102,6 +125,29 @@ function setupFetch(config, debug) {
|
|
|
102
125
|
}
|
|
103
126
|
return true;
|
|
104
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Setup database configuration if provided
|
|
130
|
+
*
|
|
131
|
+
* This stores the config globally so instrumentPostgres() can access it
|
|
132
|
+
*/
|
|
133
|
+
function setupDatabase(config, debug) {
|
|
134
|
+
const dbConfig = config?.database;
|
|
135
|
+
if (!dbConfig) {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
// Store config globally for instrumentPostgres() to use
|
|
139
|
+
setDatabaseConfig(dbConfig);
|
|
140
|
+
if (debug) {
|
|
141
|
+
console.log('[vestig] Database instrumentation configured');
|
|
142
|
+
if (dbConfig.slowQueryThreshold) {
|
|
143
|
+
console.log(`[vestig] Slow query threshold: ${dbConfig.slowQueryThreshold}ms`);
|
|
144
|
+
}
|
|
145
|
+
if (dbConfig.onQuery) {
|
|
146
|
+
console.log('[vestig] onQuery callback registered');
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
105
151
|
/**
|
|
106
152
|
* Setup console capture if configured
|
|
107
153
|
*/
|
|
@@ -220,11 +266,14 @@ export function registerVestig(options) {
|
|
|
220
266
|
// Track what was enabled
|
|
221
267
|
let otlpEnabled = false;
|
|
222
268
|
let fetchInstrumented = false;
|
|
269
|
+
let databaseConfigured = false;
|
|
223
270
|
let consoleRestore = null;
|
|
224
271
|
// Setup OTLP export
|
|
225
272
|
otlpEnabled = setupOTLP(serviceName, otlp, debug);
|
|
226
273
|
// Setup fetch instrumentation
|
|
227
274
|
fetchInstrumented = setupFetch(autoInstrument, debug);
|
|
275
|
+
// Setup database configuration
|
|
276
|
+
databaseConfigured = setupDatabase(autoInstrument, debug);
|
|
228
277
|
// Setup console capture
|
|
229
278
|
consoleRestore = setupConsole(autoInstrument, debug);
|
|
230
279
|
if (debug) {
|
|
@@ -235,11 +284,16 @@ export function registerVestig(options) {
|
|
|
235
284
|
otlpEnabled,
|
|
236
285
|
fetchInstrumented,
|
|
237
286
|
consoleInstrumented: consoleRestore !== null,
|
|
287
|
+
databaseConfigured,
|
|
238
288
|
shutdown: async () => {
|
|
239
289
|
// Restore console
|
|
240
290
|
if (consoleRestore) {
|
|
241
291
|
consoleRestore();
|
|
242
292
|
}
|
|
293
|
+
// Clear database config
|
|
294
|
+
if (databaseConfigured) {
|
|
295
|
+
setDatabaseConfig(null);
|
|
296
|
+
}
|
|
243
297
|
// Shutdown span processors (flushes pending spans)
|
|
244
298
|
await shutdownSpanProcessors();
|
|
245
299
|
if (debug) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/instrumentation/register.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/instrumentation/register.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Types for registerVestig
|
|
3
3
|
*/
|
|
4
4
|
import type { InstrumentFetchOptions, TailSamplingConfig } from 'vestig';
|
|
5
|
+
import type { DatabaseInstrumentConfig } from '../db/types';
|
|
5
6
|
/**
|
|
6
7
|
* OTLP configuration options
|
|
7
8
|
*/
|
|
@@ -59,6 +60,35 @@ export interface AutoInstrumentConfig {
|
|
|
59
60
|
* @default false
|
|
60
61
|
*/
|
|
61
62
|
console?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Database instrumentation configuration
|
|
65
|
+
*
|
|
66
|
+
* When provided, this configuration is stored globally and can be
|
|
67
|
+
* accessed by instrumentPostgres() for consistent settings.
|
|
68
|
+
*
|
|
69
|
+
* Note: You still need to wrap your postgres client with instrumentPostgres()
|
|
70
|
+
* in your database setup file. This config just provides the default settings.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* // instrumentation.ts
|
|
75
|
+
* registerVestig({
|
|
76
|
+
* autoInstrument: {
|
|
77
|
+
* database: {
|
|
78
|
+
* slowQueryThreshold: 100,
|
|
79
|
+
* onQuery: (entry) => {
|
|
80
|
+
* if (entry.isSlow) sendToMetrics(entry)
|
|
81
|
+
* }
|
|
82
|
+
* }
|
|
83
|
+
* }
|
|
84
|
+
* })
|
|
85
|
+
*
|
|
86
|
+
* // lib/db.ts
|
|
87
|
+
* const client = instrumentPostgres(postgres(DATABASE_URL))
|
|
88
|
+
* // ^ Will use the config from registerVestig()
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
database?: DatabaseInstrumentConfig;
|
|
62
92
|
}
|
|
63
93
|
/**
|
|
64
94
|
* Options for registerVestig
|
|
@@ -104,6 +134,11 @@ export interface RegisterVestigResult {
|
|
|
104
134
|
* Whether console capture was enabled
|
|
105
135
|
*/
|
|
106
136
|
consoleInstrumented: boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Whether database instrumentation config was set
|
|
139
|
+
* Note: You still need to use instrumentPostgres() in your db setup
|
|
140
|
+
*/
|
|
141
|
+
databaseConfigured: boolean;
|
|
107
142
|
/**
|
|
108
143
|
* Shutdown function to cleanup resources
|
|
109
144
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/instrumentation/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/instrumentation/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAA;AACxE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAE3D;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEhC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAE5C;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,sBAAsB,CAAA;IAExC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,QAAQ,CAAC,EAAE,wBAAwB,CAAA;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAA;IAEnB;;;OAGG;IACH,IAAI,CAAC,EAAE,UAAU,CAAA;IAEjB;;OAEG;IACH,cAAc,CAAC,EAAE,oBAAoB,CAAA;IAErC;;OAEG;IACH,YAAY,CAAC,EAAE,kBAAkB,CAAA;IAEjC;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CACf;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC;;OAEG;IACH,WAAW,EAAE,OAAO,CAAA;IAEpB;;OAEG;IACH,iBAAiB,EAAE,OAAO,CAAA;IAE1B;;OAEG;IACH,mBAAmB,EAAE,OAAO,CAAA;IAE5B;;;OAGG;IACH,kBAAkB,EAAE,OAAO,CAAA;IAE3B;;OAEG;IACH,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/wide-events/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAA;AAE9C;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACvC,8CAA8C;IAC9C,KAAK,EAAE,gBAAgB,CAAA;IACvB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAA;CACjB;AAOD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,IAAI,gBAAgB,GAAG,SAAS,CAE3D;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,IAAI,gBAAgB,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/wide-events/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAA;AAE9C;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACvC,8CAA8C;IAC9C,KAAK,EAAE,gBAAgB,CAAA;IACvB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAA;CACjB;AAOD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,IAAI,gBAAgB,GAAG,SAAS,CAE3D;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,IAAI,gBAAgB,CAWnD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,SAAS,CAIxD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,GAAG,EAAE,uBAAuB,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAEhF;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAC5C,GAAG,EAAE,uBAAuB,EAC5B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAClB,OAAO,CAAC,CAAC,CAAC,CAEZ"}
|
|
@@ -52,7 +52,9 @@ export function requireWideEvent() {
|
|
|
52
52
|
const event = getWideEvent();
|
|
53
53
|
if (!event) {
|
|
54
54
|
throw new Error('requireWideEvent() called outside of a wide event context. ' +
|
|
55
|
-
'
|
|
55
|
+
'If using in a server action, wrap your action with withWideEvent(). ' +
|
|
56
|
+
'The middleware context does not automatically propagate to server actions called from the client. ' +
|
|
57
|
+
'See: https://vestig.dev/docs/nextjs/wide-events#server-actions');
|
|
56
58
|
}
|
|
57
59
|
return event;
|
|
58
60
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/wide-events/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAapD;;GAEG;AACH,MAAM,gBAAgB,GAAG,IAAI,iBAAiB,EAA2B,CAAA;AAEzE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,YAAY;IAC3B,OAAO,gBAAgB,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAA;AAC1C,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,gBAAgB;IAC/B,MAAM,KAAK,GAAG,YAAY,EAAE,CAAA;IAC5B,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACd,6DAA6D;YAC5D,sEAAsE,
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/wide-events/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAapD;;GAEG;AACH,MAAM,gBAAgB,GAAG,IAAI,iBAAiB,EAA2B,CAAA;AAEzE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,YAAY;IAC3B,OAAO,gBAAgB,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAA;AAC1C,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,gBAAgB;IAC/B,MAAM,KAAK,GAAG,YAAY,EAAE,CAAA;IAC5B,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACd,6DAA6D;YAC5D,sEAAsE;YACtE,oGAAoG;YACpG,gEAAgE,CACjE,CAAA;IACF,CAAC;IACD,OAAO,KAAK,CAAA;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB;IAClC,MAAM,GAAG,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAA;IACvC,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAA;IAC1B,OAAO,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,SAAS,CAAA;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAI,GAA4B,EAAE,EAAW;IAC5E,OAAO,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;AACrC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAC1C,GAA4B,EAC5B,EAAoB;IAEpB,OAAO,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;AACrC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vestig/next",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "First-class Next.js 15+ integration for vestig logging library. Zero boilerplate, automatic request correlation, full type safety.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
"vestig": ">=0.2.0"
|
|
107
107
|
},
|
|
108
108
|
"dependencies": {
|
|
109
|
-
"vestig": "0.
|
|
109
|
+
"vestig": "0.20.0",
|
|
110
110
|
"web-vitals": "^4.2.4"
|
|
111
111
|
},
|
|
112
112
|
"devDependencies": {
|