fg-tracker-sdk 0.4.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/CHANGELOG.md +17 -0
- package/README.md +375 -0
- package/dist/cli/release.d.ts +3 -0
- package/dist/cli/release.d.ts.map +1 -0
- package/dist/cli/release.js +134 -0
- package/dist/cli/release.js.map +1 -0
- package/dist/cli/sourcemaps.d.ts +3 -0
- package/dist/cli/sourcemaps.d.ts.map +1 -0
- package/dist/cli/sourcemaps.js +98 -0
- package/dist/cli/sourcemaps.js.map +1 -0
- package/dist/constants.d.ts +28 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +35 -0
- package/dist/constants.js.map +1 -0
- package/dist/context.d.ts +22 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +42 -0
- package/dist/context.js.map +1 -0
- package/dist/database.d.ts +29 -0
- package/dist/database.d.ts.map +1 -0
- package/dist/database.js +157 -0
- package/dist/database.js.map +1 -0
- package/dist/express.d.ts +17 -0
- package/dist/express.d.ts.map +1 -0
- package/dist/express.js +125 -0
- package/dist/express.js.map +1 -0
- package/dist/fetch.d.ts +9 -0
- package/dist/fetch.d.ts.map +1 -0
- package/dist/fetch.js +78 -0
- package/dist/fetch.js.map +1 -0
- package/dist/global-errors.d.ts +11 -0
- package/dist/global-errors.d.ts.map +1 -0
- package/dist/global-errors.js +35 -0
- package/dist/global-errors.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +154 -0
- package/dist/index.js.map +1 -0
- package/dist/logs/nest-logger.d.ts +40 -0
- package/dist/logs/nest-logger.d.ts.map +1 -0
- package/dist/logs/nest-logger.js +99 -0
- package/dist/logs/nest-logger.js.map +1 -0
- package/dist/logs/pino.d.ts +24 -0
- package/dist/logs/pino.d.ts.map +1 -0
- package/dist/logs/pino.js +62 -0
- package/dist/logs/pino.js.map +1 -0
- package/dist/logs/shipper.d.ts +18 -0
- package/dist/logs/shipper.d.ts.map +1 -0
- package/dist/logs/shipper.js +217 -0
- package/dist/logs/shipper.js.map +1 -0
- package/dist/logs/types.d.ts +84 -0
- package/dist/logs/types.d.ts.map +1 -0
- package/dist/logs/types.js +47 -0
- package/dist/logs/types.js.map +1 -0
- package/dist/logs/winston.d.ts +31 -0
- package/dist/logs/winston.d.ts.map +1 -0
- package/dist/logs/winston.js +57 -0
- package/dist/logs/winston.js.map +1 -0
- package/dist/monitors.d.ts +8 -0
- package/dist/monitors.d.ts.map +1 -0
- package/dist/monitors.js +69 -0
- package/dist/monitors.js.map +1 -0
- package/dist/next.d.ts +9 -0
- package/dist/next.d.ts.map +1 -0
- package/dist/next.js +55 -0
- package/dist/next.js.map +1 -0
- package/dist/normalize.d.ts +12 -0
- package/dist/normalize.d.ts.map +1 -0
- package/dist/normalize.js +113 -0
- package/dist/normalize.js.map +1 -0
- package/dist/pg.d.ts +9 -0
- package/dist/pg.d.ts.map +1 -0
- package/dist/pg.js +83 -0
- package/dist/pg.js.map +1 -0
- package/dist/releases.d.ts +5 -0
- package/dist/releases.d.ts.map +1 -0
- package/dist/releases.js +30 -0
- package/dist/releases.js.map +1 -0
- package/dist/scrub.d.ts +11 -0
- package/dist/scrub.d.ts.map +1 -0
- package/dist/scrub.js +34 -0
- package/dist/scrub.js.map +1 -0
- package/dist/tracker.d.ts +99 -0
- package/dist/tracker.d.ts.map +1 -0
- package/dist/tracker.js +400 -0
- package/dist/tracker.js.map +1 -0
- package/dist/types.d.ts +264 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +98 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sourcemaps.js","sourceRoot":"","sources":["../../src/cli/sourcemaps.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constantes públicas do `fg-tracker-sdk` (antes `stread-track-sdk`).
|
|
3
|
+
* Um único lugar para header, endpoint padrão e nomes de variáveis de ambiente.
|
|
4
|
+
*/
|
|
5
|
+
/** Header da chave do projeto enviado em toda chamada autenticada por chave. */
|
|
6
|
+
export declare const API_KEY_HEADER = "x-fg-tracker-key";
|
|
7
|
+
/**
|
|
8
|
+
* Endpoint usado quando `endpoint` não é informado (API local do monorepo).
|
|
9
|
+
* Em produção passe o endpoint explicitamente (ex.: `FG_TRACKER_URL`). O domínio
|
|
10
|
+
* `https://tracker-api.fortground.com.br` é o destino futuro da API; enquanto ele não
|
|
11
|
+
* estiver no ar, use a URL de produção atual informada no painel (Conectar).
|
|
12
|
+
*/
|
|
13
|
+
export declare const DEFAULT_ENDPOINT = "http://localhost:4050";
|
|
14
|
+
/** Prefixo das variáveis de ambiente lidas pelo SDK e pelos CLIs. */
|
|
15
|
+
export declare const ENV_PREFIX = "FG_TRACKER_";
|
|
16
|
+
/** @deprecated prefixo antigo (`stread-track-sdk` ≤ 0.3); lido só como fallback, removido na 1.0. */
|
|
17
|
+
export declare const LEGACY_ENV_PREFIX = "STREAD_TRACK_";
|
|
18
|
+
/**
|
|
19
|
+
* Lê `FG_TRACKER_<name>` e, se ausente/vazia, o legado `STREAD_TRACK_<name>`.
|
|
20
|
+
* Valores são aparados; string vazia conta como ausente.
|
|
21
|
+
*/
|
|
22
|
+
export declare function readEnv(name: string, env?: NodeJS.ProcessEnv): string | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Avisa (stderr) quando um CLI é chamado pelo bin antigo `stread-track-*`.
|
|
25
|
+
* Os aliases continuam funcionando até a 1.0.
|
|
26
|
+
*/
|
|
27
|
+
export declare function warnLegacyBin(newName: string, argv1?: string | undefined): void;
|
|
28
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,gFAAgF;AAChF,eAAO,MAAM,cAAc,qBAAqB,CAAC;AAEjD;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAExD,qEAAqE;AACrE,eAAO,MAAM,UAAU,gBAAgB,CAAC;AAExC,qGAAqG;AACrG,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,GAAG,SAAS,CAE9F;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,GAAG,SAA2B,GAAG,IAAI,CAKhG"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constantes públicas do `fg-tracker-sdk` (antes `stread-track-sdk`).
|
|
3
|
+
* Um único lugar para header, endpoint padrão e nomes de variáveis de ambiente.
|
|
4
|
+
*/
|
|
5
|
+
/** Header da chave do projeto enviado em toda chamada autenticada por chave. */
|
|
6
|
+
export const API_KEY_HEADER = 'x-fg-tracker-key';
|
|
7
|
+
/**
|
|
8
|
+
* Endpoint usado quando `endpoint` não é informado (API local do monorepo).
|
|
9
|
+
* Em produção passe o endpoint explicitamente (ex.: `FG_TRACKER_URL`). O domínio
|
|
10
|
+
* `https://tracker-api.fortground.com.br` é o destino futuro da API; enquanto ele não
|
|
11
|
+
* estiver no ar, use a URL de produção atual informada no painel (Conectar).
|
|
12
|
+
*/
|
|
13
|
+
export const DEFAULT_ENDPOINT = 'http://localhost:4050';
|
|
14
|
+
/** Prefixo das variáveis de ambiente lidas pelo SDK e pelos CLIs. */
|
|
15
|
+
export const ENV_PREFIX = 'FG_TRACKER_';
|
|
16
|
+
/** @deprecated prefixo antigo (`stread-track-sdk` ≤ 0.3); lido só como fallback, removido na 1.0. */
|
|
17
|
+
export const LEGACY_ENV_PREFIX = 'STREAD_TRACK_';
|
|
18
|
+
/**
|
|
19
|
+
* Lê `FG_TRACKER_<name>` e, se ausente/vazia, o legado `STREAD_TRACK_<name>`.
|
|
20
|
+
* Valores são aparados; string vazia conta como ausente.
|
|
21
|
+
*/
|
|
22
|
+
export function readEnv(name, env = process.env) {
|
|
23
|
+
return env[`${ENV_PREFIX}${name}`]?.trim() || env[`${LEGACY_ENV_PREFIX}${name}`]?.trim() || undefined;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Avisa (stderr) quando um CLI é chamado pelo bin antigo `stread-track-*`.
|
|
27
|
+
* Os aliases continuam funcionando até a 1.0.
|
|
28
|
+
*/
|
|
29
|
+
export function warnLegacyBin(newName, argv1 = process.argv[1]) {
|
|
30
|
+
const invoked = argv1?.split(/[\\/]/).pop() ?? '';
|
|
31
|
+
if (invoked.startsWith('stread-track-')) {
|
|
32
|
+
console.error(`[fg-tracker] "${invoked}" está obsoleto: use "${newName}" (o alias será removido na 1.0).`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,gFAAgF;AAChF,MAAM,CAAC,MAAM,cAAc,GAAG,kBAAkB,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AAExD,qEAAqE;AACrE,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAC;AAExC,qGAAqG;AACrG,MAAM,CAAC,MAAM,iBAAiB,GAAG,eAAe,CAAC;AAEjD;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,MAAyB,OAAO,CAAC,GAAG;IACxE,OAAO,GAAG,CAAC,GAAG,UAAU,GAAG,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,GAAG,iBAAiB,GAAG,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;AACxG,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,QAA4B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACxF,MAAM,OAAO,GAAG,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IAClD,IAAI,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACxC,OAAO,CAAC,KAAK,CAAC,iBAAiB,OAAO,yBAAyB,OAAO,mCAAmC,CAAC,CAAC;IAC7G,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
export interface SpanContext {
|
|
3
|
+
traceId: string;
|
|
4
|
+
spanId: string;
|
|
5
|
+
/** `false` quando o trace foi descartado pela amostragem (spans não são enviados, mas o contexto se propaga). */
|
|
6
|
+
sampled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/** Contexto assíncrono compartilhado: quem é o span pai da operação corrente. */
|
|
9
|
+
export declare const als: AsyncLocalStorage<SpanContext>;
|
|
10
|
+
export declare function newSpanId(): string;
|
|
11
|
+
export declare function newTraceId(): string;
|
|
12
|
+
/**
|
|
13
|
+
* Contexto de span corrente (traceId/spanId) sem precisar do tracker em mãos —
|
|
14
|
+
* usado pelo envio de logs para correlacionar automaticamente com o trace.
|
|
15
|
+
*/
|
|
16
|
+
export declare function currentSpanContext(): SpanContext | undefined;
|
|
17
|
+
export declare const TRACEPARENT_HEADER = "traceparent";
|
|
18
|
+
/** Header `traceparent` (`00-<traceId>-<spanId>-01`; flag `00` quando não amostrado) do contexto informado. */
|
|
19
|
+
export declare function formatTraceparent(ctx: SpanContext): string;
|
|
20
|
+
/** Lê um `traceparent` recebido; `undefined` quando ausente, malformado ou com ids nulos. */
|
|
21
|
+
export declare function parseTraceparent(value: string | string[] | undefined | null): SpanContext | undefined;
|
|
22
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,iHAAiH;IACjH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,iFAAiF;AACjF,eAAO,MAAM,GAAG,gCAAuC,CAAC;AAExD,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,WAAW,GAAG,SAAS,CAE5D;AAMD,eAAO,MAAM,kBAAkB,gBAAgB,CAAC;AAGhD,+GAA+G;AAC/G,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,CAE1D;AAED,6FAA6F;AAC7F,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,GAAG,IAAI,GAAG,WAAW,GAAG,SAAS,CAUrG"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
import { randomBytes } from 'node:crypto';
|
|
3
|
+
/** Contexto assíncrono compartilhado: quem é o span pai da operação corrente. */
|
|
4
|
+
export const als = new AsyncLocalStorage();
|
|
5
|
+
export function newSpanId() {
|
|
6
|
+
return randomBytes(8).toString('hex'); // 16 hex
|
|
7
|
+
}
|
|
8
|
+
export function newTraceId() {
|
|
9
|
+
return randomBytes(16).toString('hex'); // 32 hex
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Contexto de span corrente (traceId/spanId) sem precisar do tracker em mãos —
|
|
13
|
+
* usado pelo envio de logs para correlacionar automaticamente com o trace.
|
|
14
|
+
*/
|
|
15
|
+
export function currentSpanContext() {
|
|
16
|
+
return als.getStore();
|
|
17
|
+
}
|
|
18
|
+
/* ------------------------------------------------------------------ */
|
|
19
|
+
/* W3C Trace Context (tracing distribuído, CONTRATO.md §16) */
|
|
20
|
+
/* ------------------------------------------------------------------ */
|
|
21
|
+
export const TRACEPARENT_HEADER = 'traceparent';
|
|
22
|
+
const TRACEPARENT_RE = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/i;
|
|
23
|
+
/** Header `traceparent` (`00-<traceId>-<spanId>-01`; flag `00` quando não amostrado) do contexto informado. */
|
|
24
|
+
export function formatTraceparent(ctx) {
|
|
25
|
+
return `00-${ctx.traceId}-${ctx.spanId}-${ctx.sampled === false ? '00' : '01'}`;
|
|
26
|
+
}
|
|
27
|
+
/** Lê um `traceparent` recebido; `undefined` quando ausente, malformado ou com ids nulos. */
|
|
28
|
+
export function parseTraceparent(value) {
|
|
29
|
+
const raw = Array.isArray(value) ? value[0] : value;
|
|
30
|
+
if (!raw)
|
|
31
|
+
return undefined;
|
|
32
|
+
const match = TRACEPARENT_RE.exec(raw.trim());
|
|
33
|
+
if (!match)
|
|
34
|
+
return undefined;
|
|
35
|
+
const traceId = match[2].toLowerCase();
|
|
36
|
+
const spanId = match[3].toLowerCase();
|
|
37
|
+
if (/^0+$/.test(traceId) || /^0+$/.test(spanId))
|
|
38
|
+
return undefined;
|
|
39
|
+
const sampled = (parseInt(match[4], 16) & 1) === 1;
|
|
40
|
+
return { traceId, spanId, sampled };
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAS1C,iFAAiF;AACjF,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,iBAAiB,EAAe,CAAC;AAExD,MAAM,UAAU,SAAS;IACvB,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;AAClD,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;AACnD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC;AAED,wEAAwE;AACxE,yEAAyE;AACzE,wEAAwE;AAExE,MAAM,CAAC,MAAM,kBAAkB,GAAG,aAAa,CAAC;AAChD,MAAM,cAAc,GAAG,8DAA8D,CAAC;AAEtF,+GAA+G;AAC/G,MAAM,UAAU,iBAAiB,CAAC,GAAgB;IAChD,OAAO,MAAM,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAClF,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,gBAAgB,CAAC,KAA2C;IAC1E,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACpD,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9C,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,CAAC;IACvC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IAClE,MAAM,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IACpD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ActiveSpan } from './types.js';
|
|
2
|
+
import type { TrackerCore } from './tracker.js';
|
|
3
|
+
export declare function databaseError(span: ActiveSpan | undefined, error: unknown): void;
|
|
4
|
+
export interface DatabaseInstrumentationOptions {
|
|
5
|
+
/** Database system, e.g. postgresql, mysql, sqlite, mongodb, redis, oracle. */
|
|
6
|
+
system: string;
|
|
7
|
+
/** Methods that complete synchronously, through a Promise, or an error-first callback. */
|
|
8
|
+
methods?: string[];
|
|
9
|
+
operation?: (method: string, args: unknown[]) => string;
|
|
10
|
+
/** SQL only. Never return parameter values, documents, keys or connection URLs. */
|
|
11
|
+
statement?: (method: string, args: unknown[]) => string | undefined;
|
|
12
|
+
/** Enable only for APIs with a final error-first callback. */
|
|
13
|
+
callbacks?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface DatabaseOperation {
|
|
16
|
+
system: string;
|
|
17
|
+
operation: string;
|
|
18
|
+
statement?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function startDatabaseSpan(core: TrackerCore, operation: DatabaseOperation): import("./tracker.js").ActiveSpanImpl | undefined;
|
|
21
|
+
/** Portable adapter for completed operations. Cursor/stream lifecycles need a driver adapter. */
|
|
22
|
+
export declare function instrumentDatabaseClient<T extends object>(core: TrackerCore, client: T, options: DatabaseInstrumentationOptions): T;
|
|
23
|
+
export interface PostgresSqlLike {
|
|
24
|
+
(...args: any[]): any;
|
|
25
|
+
unsafe: (...args: any[]) => any;
|
|
26
|
+
}
|
|
27
|
+
/** Postgres.js lazy queries, including Drizzle, scoped transactions and reservations. */
|
|
28
|
+
export declare function instrumentPostgresClient<T extends PostgresSqlLike>(core: TrackerCore, sql: T): T;
|
|
29
|
+
//# sourceMappingURL=database.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAKhD,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,EAAE,KAAK,EAAE,OAAO,QAKzE;AAED,MAAM,WAAW,8BAA8B;IAC7C,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAC;IACf,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,CAAC;IACxD,mFAAmF;IACnF,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,GAAG,SAAS,CAAC;IACpE,8DAA8D;IAC9D,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AACD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,qDAIhF;AAED,iGAAiG;AACjG,wBAAgB,wBAAwB,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,8BAA8B,GAAG,CAAC,CAsCnI;AAED,MAAM,WAAW,eAAe;IAC9B,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IACtB,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;CACjC;AAED,yFAAyF;AACzF,wBAAgB,wBAAwB,CAAC,CAAC,SAAS,eAAe,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CA6DhG"}
|
package/dist/database.js
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { normalizeSql } from './normalize.js';
|
|
2
|
+
const genericClients = new WeakMap();
|
|
3
|
+
const postgresClients = new WeakMap();
|
|
4
|
+
export function databaseError(span, error) {
|
|
5
|
+
if (!span)
|
|
6
|
+
return;
|
|
7
|
+
span.error = { name: 'DatabaseError', message: 'Database operation failed' };
|
|
8
|
+
const code = typeof error === 'object' && error ? error.code : undefined;
|
|
9
|
+
if (typeof code === 'string' && /^[A-Z0-9_]{3,40}$/.test(code))
|
|
10
|
+
span.setAttribute('db.error_code', code);
|
|
11
|
+
}
|
|
12
|
+
export function startDatabaseSpan(core, operation) {
|
|
13
|
+
if (!core.enabled || !core.currentContext())
|
|
14
|
+
return;
|
|
15
|
+
return core.startSpan('db.query', operation.statement ? normalizeSql(operation.statement) : operation.operation, { 'db.system': operation.system, 'db.operation': operation.operation });
|
|
16
|
+
}
|
|
17
|
+
/** Portable adapter for completed operations. Cursor/stream lifecycles need a driver adapter. */
|
|
18
|
+
export function instrumentDatabaseClient(core, client, options) {
|
|
19
|
+
const registered = genericClients.get(core) ?? new WeakMap();
|
|
20
|
+
genericClients.set(core, registered);
|
|
21
|
+
if (registered.has(client))
|
|
22
|
+
return registered.get(client);
|
|
23
|
+
const methods = new Set(options.methods ?? ['query', 'execute']);
|
|
24
|
+
const cache = new Map();
|
|
25
|
+
const proxy = new Proxy(client, {
|
|
26
|
+
get(target, key, receiver) {
|
|
27
|
+
const original = Reflect.get(target, key, target);
|
|
28
|
+
if (typeof original !== 'function')
|
|
29
|
+
return original;
|
|
30
|
+
if (cache.has(key))
|
|
31
|
+
return cache.get(key);
|
|
32
|
+
const method = String(key);
|
|
33
|
+
const wrapped = !methods.has(method) ? original.bind(target) : (...args) => {
|
|
34
|
+
const span = startDatabaseSpan(core, { system: options.system, operation: options.operation?.(method, args) ?? method,
|
|
35
|
+
statement: options.statement?.(method, args) });
|
|
36
|
+
if (!span)
|
|
37
|
+
return Reflect.apply(original, target, args);
|
|
38
|
+
const end = (error) => { if (error)
|
|
39
|
+
databaseError(span, error); span.end(); };
|
|
40
|
+
const callback = options.callbacks && typeof args.at(-1) === 'function' ? args.at(-1) : undefined;
|
|
41
|
+
if (callback)
|
|
42
|
+
args[args.length - 1] = function (...values) {
|
|
43
|
+
end(values[0]);
|
|
44
|
+
return Reflect.apply(callback, this, values);
|
|
45
|
+
};
|
|
46
|
+
try {
|
|
47
|
+
const result = Reflect.apply(original, target, args);
|
|
48
|
+
if (callback)
|
|
49
|
+
return result;
|
|
50
|
+
if (result && typeof result.then === 'function')
|
|
51
|
+
return result.then((value) => { end(); return value; }, (error) => { end(error); throw error; });
|
|
52
|
+
// A cursor is not a completed query. Do not silently report its creation as execution.
|
|
53
|
+
if (result && (typeof result.toArray === 'function' || typeof result.on === 'function' || result[Symbol.asyncIterator])) {
|
|
54
|
+
span.setAttribute('db.measurement', 'cursor_creation_only');
|
|
55
|
+
}
|
|
56
|
+
end();
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
end(error);
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
cache.set(key, wrapped);
|
|
65
|
+
return wrapped;
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
registered.set(client, proxy);
|
|
69
|
+
registered.set(proxy, proxy);
|
|
70
|
+
return proxy;
|
|
71
|
+
}
|
|
72
|
+
/** Postgres.js lazy queries, including Drizzle, scoped transactions and reservations. */
|
|
73
|
+
export function instrumentPostgresClient(core, sql) {
|
|
74
|
+
const clients = postgresClients.get(core) ?? new WeakMap();
|
|
75
|
+
postgresClients.set(core, clients);
|
|
76
|
+
const queries = new WeakMap();
|
|
77
|
+
function queryProxy(query, statement) {
|
|
78
|
+
if (!query || typeof query.then !== 'function' || typeof query.values !== 'function')
|
|
79
|
+
return query;
|
|
80
|
+
if (queries.has(query))
|
|
81
|
+
return queries.get(query);
|
|
82
|
+
let execution;
|
|
83
|
+
const execute = () => {
|
|
84
|
+
if (!execution) {
|
|
85
|
+
const span = startDatabaseSpan(core, { system: 'postgresql', operation: 'query', statement });
|
|
86
|
+
try {
|
|
87
|
+
execution = query.then((value) => { span?.end(); return value; }, (error) => {
|
|
88
|
+
databaseError(span, error);
|
|
89
|
+
span?.end();
|
|
90
|
+
throw error;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
databaseError(span, error);
|
|
95
|
+
span?.end();
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return execution;
|
|
100
|
+
};
|
|
101
|
+
const proxy = new Proxy(query, {
|
|
102
|
+
get(target, key) {
|
|
103
|
+
if (key === 'then' || key === 'catch' || key === 'finally')
|
|
104
|
+
return (...args) => {
|
|
105
|
+
const pending = execute();
|
|
106
|
+
return Reflect.apply(pending[key], pending, args);
|
|
107
|
+
};
|
|
108
|
+
if (key === 'execute')
|
|
109
|
+
return () => { void execute().catch(() => { }); return proxy; };
|
|
110
|
+
const value = Reflect.get(target, key, target);
|
|
111
|
+
if (typeof value !== 'function')
|
|
112
|
+
return value;
|
|
113
|
+
return (...args) => {
|
|
114
|
+
const result = Reflect.apply(value, target, args);
|
|
115
|
+
return result === target ? proxy : result;
|
|
116
|
+
};
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
queries.set(query, proxy);
|
|
120
|
+
queries.set(proxy, proxy);
|
|
121
|
+
return proxy;
|
|
122
|
+
}
|
|
123
|
+
function wrap(client) {
|
|
124
|
+
if (clients.has(client))
|
|
125
|
+
return clients.get(client);
|
|
126
|
+
const methods = new Map();
|
|
127
|
+
const proxy = new Proxy(client, {
|
|
128
|
+
apply(target, thisArg, args) {
|
|
129
|
+
const statement = Array.isArray(args[0]) && 'raw' in args[0] ? args[0].join(' ? ') : 'postgres query';
|
|
130
|
+
return queryProxy(Reflect.apply(target, thisArg, args), statement);
|
|
131
|
+
},
|
|
132
|
+
get(target, key) {
|
|
133
|
+
const value = Reflect.get(target, key, target);
|
|
134
|
+
if (typeof value !== 'function')
|
|
135
|
+
return value;
|
|
136
|
+
if (methods.has(key))
|
|
137
|
+
return methods.get(key);
|
|
138
|
+
const fn = (...args) => {
|
|
139
|
+
if (key === 'begin' || key === 'savepoint') {
|
|
140
|
+
args = args.map(arg => typeof arg === 'function' ? (scoped) => arg(wrap(scoped)) : arg);
|
|
141
|
+
}
|
|
142
|
+
const result = Reflect.apply(value, target, args);
|
|
143
|
+
if (key === 'reserve')
|
|
144
|
+
return result.then(wrap);
|
|
145
|
+
return key === 'unsafe' ? queryProxy(result, typeof args[0] === 'string' ? args[0] : 'postgres query') : result;
|
|
146
|
+
};
|
|
147
|
+
methods.set(key, fn);
|
|
148
|
+
return fn;
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
clients.set(client, proxy);
|
|
152
|
+
clients.set(proxy, proxy);
|
|
153
|
+
return proxy;
|
|
154
|
+
}
|
|
155
|
+
return wrap(sql);
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=database.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,cAAc,GAAG,IAAI,OAAO,EAAwC,CAAC;AAC3E,MAAM,eAAe,GAAG,IAAI,OAAO,EAAqC,CAAC;AACzE,MAAM,UAAU,aAAa,CAAC,IAA4B,EAAE,KAAc;IACxE,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,IAAI,CAAC,KAAK,GAAG,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,2BAA2B,EAAE,CAAC;IAC7E,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAE,KAA4B,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACjG,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;AAC3G,CAAC;AAmBD,MAAM,UAAU,iBAAiB,CAAC,IAAiB,EAAE,SAA4B;IAC/E,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;QAAE,OAAO;IACpD,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,EAC7G,EAAE,WAAW,EAAE,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,wBAAwB,CAAmB,IAAiB,EAAE,MAAS,EAAE,OAAuC;IAC9H,MAAM,UAAU,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,EAAkB,CAAC;IAC7E,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACrC,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC;QAAE,OAAO,UAAU,CAAC,GAAG,CAAC,MAAM,CAAM,CAAC;IAC/D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC9C,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE;QAC9B,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ;YACvB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;YAClD,IAAI,OAAO,QAAQ,KAAK,UAAU;gBAAE,OAAO,QAAQ,CAAC;YACpD,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAC3B,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAe,EAAE,EAAE;gBACpF,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,MAAM;oBACnH,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;gBAClD,IAAI,CAAC,IAAI;oBAAE,OAAO,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;gBACxD,MAAM,GAAG,GAAG,CAAC,KAAe,EAAE,EAAE,GAAG,IAAI,KAAK;oBAAE,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;gBACxF,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAa,CAAC,CAAC,CAAC,SAAS,CAAC;gBAC9G,IAAI,QAAQ;oBAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,UAAyB,GAAG,MAAiB;wBACjF,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;wBAAC,OAAO,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;oBAC/D,CAAC,CAAC;gBACF,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;oBACrD,IAAI,QAAQ;wBAAE,OAAO,MAAM,CAAC;oBAC5B,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU;wBAAE,OAAO,MAAM,CAAC,IAAI,CACjE,CAAC,KAAc,EAAE,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,EAC5C,CAAC,KAAc,EAAE,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;oBACpD,uFAAuF;oBACvF,IAAI,MAAM,IAAI,CAAC,OAAO,MAAM,CAAC,OAAO,KAAK,UAAU,IAAI,OAAO,MAAM,CAAC,EAAE,KAAK,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;wBACxH,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,sBAAsB,CAAC,CAAC;oBAC9D,CAAC;oBACD,GAAG,EAAE,CAAC;oBAAC,OAAO,MAAM,CAAC;gBACvB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAAC,GAAG,CAAC,KAAK,CAAC,CAAC;oBAAC,MAAM,KAAK,CAAC;gBAAC,CAAC;YAC9C,CAAC,CAAC;YACF,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAAC,OAAO,OAAO,CAAC;QAC1C,CAAC;KACF,CAAC,CAAC;IACH,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAAC,OAAO,KAAK,CAAC;AAC5E,CAAC;AAOD,yFAAyF;AACzF,MAAM,UAAU,wBAAwB,CAA4B,IAAiB,EAAE,GAAM;IAC3F,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,EAAe,CAAC;IACxE,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAe,CAAC;IAC3C,SAAS,UAAU,CAAC,KAAU,EAAE,SAAiB;QAC/C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,UAAU;YAAE,OAAO,KAAK,CAAC;QACnG,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAClD,IAAI,SAAuC,CAAC;QAC5C,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;gBAC9F,IAAI,CAAC;oBACH,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,KAAc,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAc,EAAE,EAAE;wBAC5F,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;wBAAC,IAAI,EAAE,GAAG,EAAE,CAAC;wBAAC,MAAM,KAAK,CAAC;oBACvD,CAAC,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAAC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;oBAAC,IAAI,EAAE,GAAG,EAAE,CAAC;oBAAC,MAAM,KAAK,CAAC;gBAAC,CAAC;YAC3E,CAAC;YACD,OAAO,SAAU,CAAC;QACpB,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,KAAK,EAAE;YAC7B,GAAG,CAAC,MAAM,EAAE,GAAG;gBACb,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,SAAS;oBAAE,OAAO,CAAC,GAAG,IAAW,EAAE,EAAE;wBACpF,MAAM,OAAO,GAAG,OAAO,EAAE,CAAC;wBAAC,OAAO,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;oBAC/E,CAAC,CAAC;gBACF,IAAI,GAAG,KAAK,SAAS;oBAAE,OAAO,GAAG,EAAE,GAAG,KAAK,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;gBACtF,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC/C,IAAI,OAAO,KAAK,KAAK,UAAU;oBAAE,OAAO,KAAK,CAAC;gBAC9C,OAAO,CAAC,GAAG,IAAW,EAAE,EAAE;oBACxB,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;oBAClD,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;gBAC5C,CAAC,CAAC;YACJ,CAAC;SACF,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAAC,OAAO,KAAK,CAAC;IACrE,CAAC;IACD,SAAS,IAAI,CAAC,MAAW;QACvB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE;YAC9B,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI;gBACzB,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC;gBACtG,OAAO,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;YACrE,CAAC;YACD,GAAG,CAAC,MAAM,EAAE,GAAG;gBACb,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC/C,IAAI,OAAO,KAAK,KAAK,UAAU;oBAAE,OAAO,KAAK,CAAC;gBAC9C,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;oBAAE,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC9C,MAAM,EAAE,GAAG,CAAC,GAAG,IAAW,EAAE,EAAE;oBAC5B,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;wBAC3C,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,MAAW,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;oBAC/F,CAAC;oBACD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;oBAClD,IAAI,GAAG,KAAK,SAAS;wBAAE,OAAQ,MAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAClE,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;gBAClH,CAAC,CAAC;gBACF,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBAAC,OAAO,EAAE,CAAC;YAClC,CAAC;SACF,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAAC,OAAO,KAAK,CAAC;IACtE,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { TrackerCore } from './tracker.js';
|
|
2
|
+
import type { ExpressErrorMiddleware, ExpressLikeRequest, ExpressMiddleware, ExpressOptions, UserRef } from './types.js';
|
|
3
|
+
/** Usuário padrão: `req.user.id` (passport, Nest guards) com e-mail/nome quando existirem. */
|
|
4
|
+
export declare function defaultIdentify(req: ExpressLikeRequest): UserRef | undefined;
|
|
5
|
+
/**
|
|
6
|
+
* Middleware Express: um span raiz `http.server` por request. Deve ser o
|
|
7
|
+
* primeiro middleware para que tudo o que vier depois (handlers, queries,
|
|
8
|
+
* fetch) enxergue o contexto via AsyncLocalStorage. Continua traces recebidos
|
|
9
|
+
* via `traceparent` (tracing distribuído) e associa o usuário ao fim da resposta.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createExpressMiddleware(core: TrackerCore, options?: ExpressOptions): ExpressMiddleware;
|
|
12
|
+
/**
|
|
13
|
+
* Middleware de erro (4 argumentos): grava a exceção real no span da requisição e
|
|
14
|
+
* repassa para o próximo handler de erro. Registre depois das rotas.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createExpressErrorHandler(core: TrackerCore): ExpressErrorMiddleware;
|
|
17
|
+
//# sourceMappingURL=express.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../src/express.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAuB,iBAAiB,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAgB9I,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,GAAG,SAAS,CAS5E;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,GAAE,cAAmB,GAAG,iBAAiB,CAyE1G;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,WAAW,GAAG,sBAAsB,CAMnF"}
|
package/dist/express.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { parseTraceparent } from './context.js';
|
|
2
|
+
import { normalizePath } from './normalize.js';
|
|
3
|
+
function headerValue(v) {
|
|
4
|
+
return Array.isArray(v) ? v[0] : v;
|
|
5
|
+
}
|
|
6
|
+
function resolveRoute(req, fallbackPath) {
|
|
7
|
+
const routePath = req.route?.path;
|
|
8
|
+
if (typeof routePath === 'string' && routePath.length > 0) {
|
|
9
|
+
const base = req.baseUrl ?? '';
|
|
10
|
+
const full = `${base}${routePath === '/' && base ? '' : routePath}`;
|
|
11
|
+
return full || '/';
|
|
12
|
+
}
|
|
13
|
+
return normalizePath(fallbackPath);
|
|
14
|
+
}
|
|
15
|
+
/** Usuário padrão: `req.user.id` (passport, Nest guards) com e-mail/nome quando existirem. */
|
|
16
|
+
export function defaultIdentify(req) {
|
|
17
|
+
const user = req.user;
|
|
18
|
+
if (!user || typeof user !== 'object')
|
|
19
|
+
return undefined;
|
|
20
|
+
const id = user.id ?? user.sub;
|
|
21
|
+
if (id === undefined || id === null || id === '')
|
|
22
|
+
return undefined;
|
|
23
|
+
const ref = { id: typeof id === 'number' ? id : String(id) };
|
|
24
|
+
if (typeof user.email === 'string')
|
|
25
|
+
ref.email = user.email;
|
|
26
|
+
if (typeof user.name === 'string')
|
|
27
|
+
ref.name = user.name;
|
|
28
|
+
return ref;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Middleware Express: um span raiz `http.server` por request. Deve ser o
|
|
32
|
+
* primeiro middleware para que tudo o que vier depois (handlers, queries,
|
|
33
|
+
* fetch) enxergue o contexto via AsyncLocalStorage. Continua traces recebidos
|
|
34
|
+
* via `traceparent` (tracing distribuído) e associa o usuário ao fim da resposta.
|
|
35
|
+
*/
|
|
36
|
+
export function createExpressMiddleware(core, options = {}) {
|
|
37
|
+
const identify = options.identify === false ? null : (options.identify ?? defaultIdentify);
|
|
38
|
+
const continueTrace = options.continueTrace ?? true;
|
|
39
|
+
return function fgTrackerMiddleware(req, res, next) {
|
|
40
|
+
if (!core.enabled) {
|
|
41
|
+
next();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const method = (req.method ?? 'GET').toUpperCase();
|
|
45
|
+
const rawUrl = req.originalUrl ?? req.url ?? '/';
|
|
46
|
+
const initialRoute = normalizePath(rawUrl);
|
|
47
|
+
const ip = req.ip ?? headerValue(req.headers['x-forwarded-for'])?.split(',')[0]?.trim() ?? req.socket?.remoteAddress ?? null;
|
|
48
|
+
const requestId = headerValue(req.headers['x-request-id']) ?? null;
|
|
49
|
+
const attributes = {
|
|
50
|
+
url: rawUrl,
|
|
51
|
+
userAgent: headerValue(req.headers['user-agent']) ?? null,
|
|
52
|
+
ip,
|
|
53
|
+
...(requestId ? { requestId } : {}),
|
|
54
|
+
};
|
|
55
|
+
// Raiz: ignora qualquer contexto herdado (ex.: keep-alive reutilizando o socket);
|
|
56
|
+
// um `traceparent` válido continua o trace do serviço a montante.
|
|
57
|
+
const remote = continueTrace ? parseTraceparent(req.headers['traceparent']) : undefined;
|
|
58
|
+
const span = remote
|
|
59
|
+
? core.startRemoteRoot('http.server', `${method} ${initialRoute}`, attributes, remote)
|
|
60
|
+
: core.startSpan('http.server', `${method} ${initialRoute}`, attributes, null);
|
|
61
|
+
span.method = method;
|
|
62
|
+
span.route = initialRoute;
|
|
63
|
+
if (typeof res.setHeader === 'function' && typeof res.getHeader === 'function' && !res.getHeader('x-trace-id')) {
|
|
64
|
+
try {
|
|
65
|
+
res.setHeader('x-trace-id', span.traceId);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
/* headers já enviados */
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
let done = false;
|
|
72
|
+
const finish = (aborted) => {
|
|
73
|
+
if (done)
|
|
74
|
+
return;
|
|
75
|
+
done = true;
|
|
76
|
+
const route = resolveRoute(req, rawUrl);
|
|
77
|
+
span.route = route;
|
|
78
|
+
span.name = `${method} ${route}`;
|
|
79
|
+
span.statusCode = res.statusCode ?? null;
|
|
80
|
+
if (identify) {
|
|
81
|
+
try {
|
|
82
|
+
const user = identify(req);
|
|
83
|
+
if (user)
|
|
84
|
+
span.setUser(user);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
/* identificação é best-effort */
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (aborted) {
|
|
91
|
+
span.setAttribute('aborted', true);
|
|
92
|
+
if (!span.error)
|
|
93
|
+
span.error = { name: 'ClientAborted', message: 'conexão encerrada antes da resposta' };
|
|
94
|
+
}
|
|
95
|
+
else if (typeof res.statusCode === 'number' && res.statusCode >= 500 && !span.error) {
|
|
96
|
+
span.error = { name: 'HttpError', message: `HTTP ${res.statusCode}` };
|
|
97
|
+
}
|
|
98
|
+
span.end();
|
|
99
|
+
};
|
|
100
|
+
res.once('finish', () => finish(false));
|
|
101
|
+
res.once('close', () => finish(!done));
|
|
102
|
+
core.runInSpan(span, () => {
|
|
103
|
+
try {
|
|
104
|
+
next();
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
span.setError(err);
|
|
108
|
+
throw err;
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Middleware de erro (4 argumentos): grava a exceção real no span da requisição e
|
|
115
|
+
* repassa para o próximo handler de erro. Registre depois das rotas.
|
|
116
|
+
*/
|
|
117
|
+
export function createExpressErrorHandler(core) {
|
|
118
|
+
return function fgTrackerErrorHandler(err, _req, _res, next) {
|
|
119
|
+
const span = core.rootSpan() ?? core.currentSpan();
|
|
120
|
+
if (span && !span.error)
|
|
121
|
+
span.setError(err);
|
|
122
|
+
next(err);
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=express.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express.js","sourceRoot":"","sources":["../src/express.ts"],"names":[],"mappings":"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"}
|
package/dist/fetch.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type TrackerCore } from './tracker.js';
|
|
2
|
+
/**
|
|
3
|
+
* Retorna um `fetch` que cria spans `http.client` nomeados
|
|
4
|
+
* `${method} ${origin}${pathname normalizado}` e propaga o contexto do trace
|
|
5
|
+
* (`traceparent`) para o próximo serviço continuar o mesmo trace (CONTRATO.md §16).
|
|
6
|
+
* Chamadas para o próprio endpoint do FG Tracker não são instrumentadas.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createInstrumentedFetch(core: TrackerCore, fetchImpl?: typeof globalThis.fetch): typeof globalThis.fetch;
|
|
9
|
+
//# sourceMappingURL=fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../src/fetch.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAiCjE;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,GAAE,OAAO,UAAU,CAAC,KAAwB,GAAG,OAAO,UAAU,CAAC,KAAK,CA6BzI"}
|
package/dist/fetch.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { formatTraceparent, TRACEPARENT_HEADER } from './context.js';
|
|
2
|
+
import { normalizePath } from './normalize.js';
|
|
3
|
+
import { shouldPropagate } from './tracker.js';
|
|
4
|
+
function describe(input, init) {
|
|
5
|
+
let raw;
|
|
6
|
+
let method = init?.method;
|
|
7
|
+
if (typeof input === 'string')
|
|
8
|
+
raw = input;
|
|
9
|
+
else if (input instanceof URL)
|
|
10
|
+
raw = input.toString();
|
|
11
|
+
else {
|
|
12
|
+
raw = input.url;
|
|
13
|
+
method = method ?? input.method;
|
|
14
|
+
}
|
|
15
|
+
let url = null;
|
|
16
|
+
try {
|
|
17
|
+
url = new URL(raw);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
url = null;
|
|
21
|
+
}
|
|
22
|
+
return { method: (method ?? 'GET').toUpperCase(), url, raw };
|
|
23
|
+
}
|
|
24
|
+
/** Acrescenta o `traceparent` ao request sem perder headers já definidos (Request, Headers, array ou objeto). */
|
|
25
|
+
function withTraceparent(input, init, value) {
|
|
26
|
+
if (input instanceof Request && !init?.headers) {
|
|
27
|
+
if (input.headers.has(TRACEPARENT_HEADER))
|
|
28
|
+
return { input, init };
|
|
29
|
+
const headers = new Headers(input.headers);
|
|
30
|
+
headers.set(TRACEPARENT_HEADER, value);
|
|
31
|
+
return { input: new Request(input, { headers }), init };
|
|
32
|
+
}
|
|
33
|
+
const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : undefined));
|
|
34
|
+
if (!headers.has(TRACEPARENT_HEADER))
|
|
35
|
+
headers.set(TRACEPARENT_HEADER, value);
|
|
36
|
+
return { input, init: { ...init, headers } };
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Retorna um `fetch` que cria spans `http.client` nomeados
|
|
40
|
+
* `${method} ${origin}${pathname normalizado}` e propaga o contexto do trace
|
|
41
|
+
* (`traceparent`) para o próximo serviço continuar o mesmo trace (CONTRATO.md §16).
|
|
42
|
+
* Chamadas para o próprio endpoint do FG Tracker não são instrumentadas.
|
|
43
|
+
*/
|
|
44
|
+
export function createInstrumentedFetch(core, fetchImpl = globalThis.fetch) {
|
|
45
|
+
const base = fetchImpl;
|
|
46
|
+
const ownEndpoint = core.options.endpoint;
|
|
47
|
+
return async function fgTrackerFetch(input, init) {
|
|
48
|
+
if (!core.enabled || !core.currentContext())
|
|
49
|
+
return base(input, init);
|
|
50
|
+
const { method, url, raw } = describe(input, init);
|
|
51
|
+
if (!url || raw.startsWith(ownEndpoint))
|
|
52
|
+
return base(input, init);
|
|
53
|
+
const name = `${method} ${url.origin}${normalizePath(url.pathname)}`;
|
|
54
|
+
const span = core.startSpan('http.client', name, { url: url.origin + url.pathname + url.search, host: url.host });
|
|
55
|
+
span.method = method;
|
|
56
|
+
span.route = normalizePath(url.pathname);
|
|
57
|
+
let request = { input, init };
|
|
58
|
+
if (shouldPropagate(core.options.propagateTraceTo, url)) {
|
|
59
|
+
request = withTraceparent(input, init, formatTraceparent({ traceId: span.traceId, spanId: span.spanId, sampled: span.sampled }));
|
|
60
|
+
span.setAttribute('propagated', true);
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const res = await core.runInSpan(span, () => base(request.input, request.init));
|
|
64
|
+
span.statusCode = res.status;
|
|
65
|
+
if (res.status >= 500)
|
|
66
|
+
span.error = { name: 'HttpError', message: `HTTP ${res.status}` };
|
|
67
|
+
return res;
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
span.setError(err);
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
span.end();
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../src/fetch.ts"],"names":[],"mappings":"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"}
|