fg-tracker-sdk 0.8.1 → 0.10.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 +26 -0
- package/README.md +37 -12
- package/dist/cli/release.js +1 -1
- package/dist/cli/sourcemaps.js +1 -1
- package/dist/context.d.ts +7 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js.map +1 -1
- package/dist/exit-hooks.d.ts +23 -0
- package/dist/exit-hooks.d.ts.map +1 -0
- package/dist/exit-hooks.js +88 -0
- package/dist/exit-hooks.js.map +1 -0
- package/dist/fetch.d.ts +1 -1
- package/dist/fetch.js +1 -1
- package/dist/global-errors.d.ts +8 -5
- package/dist/global-errors.d.ts.map +1 -1
- package/dist/global-errors.js +59 -10
- package/dist/global-errors.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/infra/aggregator.d.ts +5 -0
- package/dist/infra/aggregator.d.ts.map +1 -1
- package/dist/infra/aggregator.js.map +1 -1
- package/dist/infra/lambda.d.ts +1 -1
- package/dist/infra/lambda.d.ts.map +1 -1
- package/dist/infra/lambda.js +3 -2
- package/dist/infra/lambda.js.map +1 -1
- package/dist/logs/nest-logger.d.ts +1 -1
- package/dist/logs/nest-logger.js +1 -1
- package/dist/logs/shipper.d.ts +5 -4
- package/dist/logs/shipper.d.ts.map +1 -1
- package/dist/logs/shipper.js +170 -52
- package/dist/logs/shipper.js.map +1 -1
- package/dist/logs/types.d.ts +19 -3
- package/dist/logs/types.d.ts.map +1 -1
- package/dist/monitors.d.ts.map +1 -1
- package/dist/monitors.js +3 -0
- package/dist/monitors.js.map +1 -1
- package/dist/scrub.d.ts +5 -0
- package/dist/scrub.d.ts.map +1 -1
- package/dist/scrub.js +17 -1
- package/dist/scrub.js.map +1 -1
- package/dist/tracker.d.ts +101 -6
- package/dist/tracker.d.ts.map +1 -1
- package/dist/tracker.js +468 -92
- package/dist/tracker.js.map +1 -1
- package/dist/transport.d.ts +115 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +323 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +50 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Changelog — fg-tracker-sdk
|
|
2
2
|
|
|
3
|
+
## 0.10.0
|
|
4
|
+
|
|
5
|
+
Transporte confiável (CONTRATO.md §4.3). Nenhuma API pública removida; opções novas são aditivas.
|
|
6
|
+
|
|
7
|
+
- **Timeout de 10 s no POST de ingestão** (`requestTimeoutMs`). Antes, com a rede engolindo pacotes, `flush()`/`shutdown()` esperavam o timeout do undici (~300 s).
|
|
8
|
+
- **Backoff exponencial com jitter e `Retry-After`** em rede, 408, 429 e 5xx (1 s → 60 s; `Retry-After` limitado a 5 min). Antes o lote era reenviado a cada flush, sem espera. Durante o backoff, `flush()` volta sem enviar.
|
|
9
|
+
- **Lotes limitados por bytes** (`maxBatchBytes`, 1,5 MiB; a API recusa acima de 2 MiB) e **413 divide o lote** (spans e agregados de infra) em vez de descartá-lo; um 202 cujo corpo cai no meio não confirma o lote. Fila limitada também em memória (`maxQueueBytes`, 32 MiB). `attributes`/`error` acima de 60 KiB são cortados com `attributes['fg.truncated'] = true` em vez de a API recusar o span; atributo circular, BigInt ou `toJSON` que lança não trava a fila nem lança para a aplicação.
|
|
10
|
+
- **gzip** nos lotes ≥ 4 KiB (`compression`), ligado com o `fetch` global e desligado com `fetch` próprio (o corpo continua string). Se a API responder 400/415 ao corpo comprimido, o SDK desliga o gzip no processo e reenvia sem.
|
|
11
|
+
- **Recusa parcial**: spans recusados num 202 (`rejected`) não são reenviados; agregados de infra em `infra.retryableIds` voltam para a fila com o mesmo id e esperam o backoff, que continua crescendo enquanto a falha durar.
|
|
12
|
+
- **Agregados de infra com `id`** (`<emissor>:<sequência>`): o reenvio não soma de novo na API.
|
|
13
|
+
- **Encerramento com prazo**: `shutdown({ timeoutMs })` (padrão `shutdownTimeoutMs` = 10 s) volta no prazo mesmo com a API muda e aborta a requisição pendente. Prazos que se sobrepõem (sinal de saída e `shutdown` da aplicação) valem pelo menor, inclusive durante a espera de backoff.
|
|
14
|
+
- **Envio na saída do processo** (`exitHooks`, padrão ligado): `beforeExit` envia o que ficou (scripts e jobs sem `shutdown()`); SIGTERM/SIGINT enviam (inclusive o lote que já está em voo) e reemitem o sinal quando a aplicação não o trata; com handler da aplicação (inclusive `process.once` assíncrono), ela decide e o SDK nunca mata o processo. Não instala na Lambda nem em worker threads. Um registro por processo, compartilhado também entre cópias do pacote (duas versões instaladas não se tomam por handler da aplicação). **Efeito ao atualizar:** um processo que recebe SIGTERM/SIGINT com spans na fila passa a levar até `shutdownTimeoutMs` para sair; `exitHooks: false` volta ao comportamento anterior.
|
|
15
|
+
- **`captureGlobalErrors`**: sem outro listener de `uncaughtException`, o SDK envia a fila (até 2 s) antes de o processo sair com código 1, como o Node; antes o envio era cortado pela saída. Vários trackers com a opção não engolem mais a exceção nem a rejeição não tratada. Com handler `uncaughtException` da aplicação (inclusive `process.once` assíncrono), ela decide.
|
|
16
|
+
- **`wrapLambda` sem a extensão**: o fim da invocação espera no máximo `flushTimeoutMs`, sem esperar backoff, e a requisição é abortada no prazo.
|
|
17
|
+
- **Logs** (`createLogShipper`, pino, winston, Nest): mesmo transporte, um `eventId` por linha (a API deduplica o reenvio) e `shutdown({ timeoutMs })`. Opções novas: `maxBatchBytes`, `maxQueueBytes`, `requestTimeoutMs`, `shutdownTimeoutMs`, `compression`, `exitHooks`.
|
|
18
|
+
- **`sendUnsampledErrors`** (padrão `false`): com amostragem, envia o span que falhou num trace não amostrado e a raiz local dele (`attributes['sampling.kept'] = 'error'`). Spans que fecharam antes do erro não voltam. Traces excluídos por `ignoreTransactions` nunca são enviados, nem com esta opção. Desligado por padrão porque a API ainda conta essas raízes nas métricas.
|
|
19
|
+
- Requer, para a dedupe de logs e agregados, a API com `track_ingest_dedupe` (mesmo PR). Com APIs anteriores os campos novos são ignorados e o envio funciona como antes.
|
|
20
|
+
|
|
21
|
+
## 0.9.0
|
|
22
|
+
|
|
23
|
+
Reúne o que entrou na `main` desde a 0.8.1 (PR #14) e a renomeação para FG Tracker.
|
|
24
|
+
|
|
25
|
+
- Comentários dos tipos (JSDoc) e documentação passam a dizer **FG Tracker**. APIs, exports, variáveis e mensagens não mudam.
|
|
26
|
+
- **Check-in de job leva o ambiente do tracker** (`environment` no body de `POST /v1/monitors/:slug/checkin`). A API mantém um monitor por slug e ambiente: um job de desenvolvimento não deixa mais "no ar" o monitor de um job de produção que parou. `CheckInOptions.environment` troca o ambiente de um job (`'staging'`) ou o omite (`false`). Com APIs anteriores o campo é ignorado e o check-in vai para o monitor único do slug, como antes.
|
|
27
|
+
- **Efeito ao atualizar**: com a API atual, o primeiro check-in de cada ambiente cria o monitor `(slug, ambiente)` herdando a config do monitor sem ambiente. O monitor antigo, sem ambiente, deixa de receber check-ins desses clientes e passa a avisar `monitor_down` ("provável migração"). Depois de atualizar todos os clientes de um job, pause ou remova o monitor sem ambiente, ou atribua a ele um ambiente para manter o histórico (CONTRATO.md §18).
|
|
28
|
+
|
|
3
29
|
## 0.8.1 — 2026-10-01
|
|
4
30
|
|
|
5
31
|
- Atualiza o nome visível do produto para **FG Track** nas mensagens e na documentação do pacote. APIs e identificadores de integração permanecem compatíveis.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# fg-tracker-sdk
|
|
2
2
|
|
|
3
|
-
Instrumentação Node para o [FG
|
|
3
|
+
Instrumentação Node para o [FG Tracker](../../README.md) e envio de logs (pino, winston, NestJS Logger). Única dependência de runtime: `pino-abstract-transport` (a instrumentação AWS usa tipos estruturais, sem `@aws-sdk/*`); usa `AsyncLocalStorage` para encadear spans e o `fetch` global do Node para enviar lotes ao `POST /v1/ingest`.
|
|
4
4
|
|
|
5
5
|
Requisitos: Node ≥ 20 (recomendado 24). O pacote é ESM; em projetos CommonJS (NestJS) funciona com `require()` no Node ≥ 22.12 ou via `import()` dinâmico.
|
|
6
6
|
|
|
@@ -33,7 +33,7 @@ tracker.instrumentPg(pool); // pg.Pool → spans db.query com qu
|
|
|
33
33
|
await tracker.span('custom', 'send-email', async (span) => { span.setAttribute('to', email); });
|
|
34
34
|
export const GET = tracker.wrapNextRoute(async (req) => Response.json({ ok: true }));
|
|
35
35
|
const fetchTracked = tracker.wrapFetch(); // fetch instrumentado → spans http.client
|
|
36
|
-
await tracker.flush(); await tracker.shutdown();
|
|
36
|
+
await tracker.flush(); await tracker.shutdown(); // shutdown espera no máximo 10 s
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
| opção | default | descrição |
|
|
@@ -44,6 +44,13 @@ await tracker.flush(); await tracker.shutdown();
|
|
|
44
44
|
| `flushIntervalMs` | `2000` | intervalo de envio |
|
|
45
45
|
| `maxBatchSize` | `200` | ≥ N spans na fila dispara envio imediato |
|
|
46
46
|
| `maxQueueSize` | `5000` | acima disso descarta os spans mais antigos |
|
|
47
|
+
| `maxQueueBytes` | `32 MiB` | memória máxima da fila (JSON dos spans); acima disso descarta os mais antigos |
|
|
48
|
+
| `maxBatchBytes` | `1,5 MiB` | teto do corpo de cada POST (antes do gzip); um 413 divide o lote |
|
|
49
|
+
| `requestTimeoutMs` | `10000` | timeout de cada POST |
|
|
50
|
+
| `shutdownTimeoutMs` | `10000` | prazo do `shutdown()` e do envio na saída do processo |
|
|
51
|
+
| `compression` | `'gzip'` (`'none'` com `fetch` próprio) | gzip para lotes ≥ 4 KiB; desliga sozinho se a API responder 400/415 ao corpo comprimido |
|
|
52
|
+
| `exitHooks` | `true` | envia a fila no `beforeExit` e em SIGTERM/SIGINT (veja **Envio, retry e encerramento**) |
|
|
53
|
+
| `sendUnsampledErrors` | `false` | com amostragem, envia o span que falhou num trace não amostrado e a raiz local dele |
|
|
47
54
|
| `enabled` | `true` | `false` desliga tudo sem tirar o código |
|
|
48
55
|
| `debug` | `false` | loga cada envio |
|
|
49
56
|
| `release` | detectada | versão em execução (`FG_TRACKER_RELEASE`, `GITHUB_SHA`, `VERCEL_GIT_COMMIT_SHA`… → `${serviceName}@${sha}`); `false` desliga |
|
|
@@ -54,7 +61,7 @@ await tracker.flush(); await tracker.shutdown();
|
|
|
54
61
|
| `autoSpanMinDurationMs` | `5` | duração mínima para um trecho medido com `measure`/`instrumentNest` virar span |
|
|
55
62
|
| `measureEventLoopLag` | `true` | mede o atraso do event loop na requisição e grava `eventLoop.maxLagMs`/`eventLoop.blockedMs` no span raiz quando o loop trava |
|
|
56
63
|
| `eventLoopLagThresholdMs` | `50` | atraso mínimo para virar atributo |
|
|
57
|
-
| `captureGlobalErrors` | `false` | `
|
|
64
|
+
| `captureGlobalErrors` | `false` | `uncaughtException` + `unhandledRejection` viram spans com erro; sem outro listener de `uncaughtException`, envia a fila (até 2 s) antes de sair com código 1 |
|
|
58
65
|
| `tracesSampleRate` | `1` | fração de traces enviados (decidida na raiz; filhos seguem; `traceparent` sai com `-00` quando não amostrado) |
|
|
59
66
|
| `tracesSampler` | — | `(ctx: { kind, name, attributes, parentSampled? }) => taxa` por operação (ex.: `0` para `GET /health`) |
|
|
60
67
|
| `ignoreTransactions` | `[]` | nomes de raiz (string/RegExp) que nunca são enviados |
|
|
@@ -63,6 +70,19 @@ await tracker.flush(); await tracker.shutdown();
|
|
|
63
70
|
| `beforeSend` | — | `(span) => span \| null`, último filtro antes da fila |
|
|
64
71
|
| `infra` | `{ enabled: true, idleIntervalMs: 60000 }` | agregados de infraestrutura (veja **Infraestrutura**); nunca amostrados |
|
|
65
72
|
|
|
73
|
+
## Envio, retry e encerramento
|
|
74
|
+
|
|
75
|
+
O envio segue o CONTRATO.md §4.3 e vale também para o shipper de logs:
|
|
76
|
+
|
|
77
|
+
- **Timeout** de 10 s por POST e uma requisição por vez.
|
|
78
|
+
- **Rede, timeout, 408, 429 e 5xx**: o lote volta inteiro para a fila e o próximo envio espera um backoff exponencial com jitter (1 s, 2 s, 4 s… até 60 s) ou o `Retry-After` da resposta, o que for maior (limitado a 5 min). Durante a espera, `flush()` volta sem enviar.
|
|
79
|
+
- **413**: o lote é dividido até caber. **Outro 4xx**: o lote é descartado (repetir daria o mesmo erro).
|
|
80
|
+
- **202 parcial**: spans recusados pela validação da API (`rejected`) não são reenviados. Agregados de infra com falha transitória (`infra.retryableIds`) voltam para a fila com o mesmo `id` e esperam o backoff. O reenvio não duplica: spans, logs, pageviews e agregados têm identidade e a API deduplica.
|
|
81
|
+
- **Memória**: lotes de até 1,5 MiB e 1000 spans; fila de até 5000 spans e 32 MiB. `attributes` ou `error` acima de 60 KiB são cortados antes do envio, com `attributes['fg.truncated'] = true` (a API recusaria o span acima de 64 KiB).
|
|
82
|
+
- **`shutdown({ timeoutMs })`** envia o que der em até 10 s (padrão `shutdownTimeoutMs`) e aborta a requisição pendente no prazo. Com a API muda, volta no prazo; o que sobrou é descartado e contado.
|
|
83
|
+
- **Saída sem `shutdown()`** (`exitHooks`, ligado por padrão): scripts e jobs que terminam sozinhos enviam a fila no `beforeExit`. Em SIGTERM/SIGINT o SDK envia a fila e, se a aplicação não trata o sinal, o reemite: o processo sai como sairia sem o SDK. Se a aplicação tem o próprio handler, ela decide quando sair; chame `await tracker.shutdown()` nele. Na Lambda use `wrapLambda` (abaixo).
|
|
84
|
+
- **Amostragem**: com `tracesSampleRate < 1`, a decisão é por trace, na raiz. Com `sendUnsampledErrors: true`, o span que falhou num trace não amostrado e a raiz local dele são enviados mesmo assim, marcados `attributes['sampling.kept'] = 'error'`. Os spans que fecharam antes do erro já foram descartados e não voltam: preservar o trace inteiro exige amostragem no coletor. O padrão é desligado porque a API ainda conta essas raízes em requests e taxa de erro.
|
|
85
|
+
|
|
66
86
|
## Erros, usuários, releases e jobs
|
|
67
87
|
|
|
68
88
|
```ts
|
|
@@ -86,6 +106,8 @@ O CLI `fg-tracker-release` lê `git log`/`git show` e envia commits, arquivos e
|
|
|
86
106
|
|
|
87
107
|
Jobs com crontab: `tracker.checkIn('relatorio', run, { cron: '0 3 * * *', timezone: 'America/Sao_Paulo', maxRuntimeSeconds: 1800 })` — o monitor calcula o próximo disparo no fuso, marca `timeout` quando passa do tempo máximo e aceita `failureThreshold`/`recoveryThreshold` na tela.
|
|
88
108
|
|
|
109
|
+
Ambientes nos check-ins: o check-in leva o `environment` do tracker, e cada ambiente tem o seu monitor (status, histórico e alertas) para o mesmo slug, então um job de dev não mascara um de produção que parou. `{ environment: 'staging' }` troca o ambiente de um job e `{ environment: false }` envia sem ambiente (vai para o monitor sem ambiente, o de clientes anteriores). Na primeira vez que um ambiente faz check-in, o monitor dele herda nome e configuração do monitor existente com o mesmo slug. O monitor sem ambiente antigo continua sendo cobrado (um cliente antigo pode ter parado) e aparece como "legado" quando os check-ins com ambiente chegam depois do último sem ambiente: depois de atualizar todos os clientes, pause ou remova esse monitor, ou atribua a ele um ambiente na edição para manter o histórico.
|
|
110
|
+
|
|
89
111
|
Source maps do front (para o `fg-tracker-browser`): `FG_TRACKER_KEY=stk_... npx fg-tracker-sourcemaps --dir dist --release web@$GITHUB_SHA --url-prefix ~/assets` sobe os `.map` de uma release; a API traduz o stack minificado na ingestão.
|
|
90
112
|
|
|
91
113
|
Falhas de envio são logadas **uma vez** e o lote é reenviado no próximo flush (respostas 4xx descartam o lote — normalmente é chave inválida). O timer usa `unref()`, então não segura o processo vivo; chame `shutdown()` no encerramento para não perder os últimos spans.
|
|
@@ -176,7 +198,7 @@ const res = await fetchTracked('https://api.github.com/repos/FORTGROUND/fg-track
|
|
|
176
198
|
globalThis.fetch = tracker.wrapFetch(globalThis.fetch);
|
|
177
199
|
```
|
|
178
200
|
|
|
179
|
-
Cada chamada vira um span `http.client` nomeado `${method} ${origin}${pathname normalizado}` (ex.: `GET https://api.github.com/repos/:id`). É isso que alimenta a detecção de **LOOP**: a mesma chamada repetida ≥ `loop_threshold` vezes sob o mesmo pai. Chamadas ao próprio endpoint do FG
|
|
201
|
+
Cada chamada vira um span `http.client` nomeado `${method} ${origin}${pathname normalizado}` (ex.: `GET https://api.github.com/repos/:id`). É isso que alimenta a detecção de **LOOP**: a mesma chamada repetida ≥ `loop_threshold` vezes sob o mesmo pai. Chamadas ao próprio endpoint do FG Tracker são ignoradas.
|
|
180
202
|
|
|
181
203
|
## node:http e node:https (automático)
|
|
182
204
|
|
|
@@ -191,7 +213,7 @@ O `fetch` cobre quem chama `fetch`. Todo o resto do ecossistema Node continua fa
|
|
|
191
213
|
|
|
192
214
|
Vale para qualquer cliente, inclusive um que você nem sabe que existe dentro de uma dependência — e não depende de lembrar de envolver cada cliente. A implementação usa [`diagnostics_channel`](https://nodejs.org/api/diagnostics_channel.html), o ponto de observação que o próprio Node publica: nada é substituído por monkeypatch, nada quebra se outra biblioteca instrumentar o mesmo módulo, e a ordem de import não importa.
|
|
193
215
|
|
|
194
|
-
As regras são as mesmas do `fetch`: span `http.client` com o mesmo nome e `attributes.host`, só dentro de um trace em andamento (um poller de background não vira trace órfão), `traceparent` propagado conforme `propagateTraceTo` e sem tocar num header que o chamador já definiu, 5xx marcando erro no span, e chamadas ao próprio endpoint do FG
|
|
216
|
+
As regras são as mesmas do `fetch`: span `http.client` com o mesmo nome e `attributes.host`, só dentro de um trace em andamento (um poller de background não vira trace órfão), `traceparent` propagado conforme `propagateTraceTo` e sem tocar num header que o chamador já definiu, 5xx marcando erro no span, e chamadas ao próprio endpoint do FG Tracker ignoradas.
|
|
195
217
|
|
|
196
218
|
Para desligar:
|
|
197
219
|
|
|
@@ -298,7 +320,7 @@ curl -X POST http://localhost:4050/v1/ingest \
|
|
|
298
320
|
|
|
299
321
|
## Logs (`POST /v1/logs`)
|
|
300
322
|
|
|
301
|
-
O SDK envia linhas de log para a plataforma em lote (`flushIntervalMs` 2 s, `maxBatch` 200, fila de 5000 descartando as mais antigas,
|
|
323
|
+
O SDK envia linhas de log para a plataforma em lote (`flushIntervalMs` 2 s, `maxBatch` 200, fila de 5000 linhas e 16 MiB descartando as mais antigas), com o mesmo transporte do tracker (veja **Envio, retry e encerramento**). Cada linha leva um `eventId`: o reenvio de um lote que a API já gravou não duplica. Quando a linha nasce dentro de um span do tracker (request Express/Nest, `tracker.span`), `traceId`/`spanId` são anexados automaticamente e a linha aparece ligada ao trace no explorador `/logs`.
|
|
302
324
|
|
|
303
325
|
### Shipper cru
|
|
304
326
|
|
|
@@ -317,6 +339,9 @@ await logs.flush(); await logs.shutdown();
|
|
|
317
339
|
| `service` | — | nome do serviço (obrigatório) |
|
|
318
340
|
| `env`, `host` | — / `os.hostname()` | ambiente e host; `host: false` desliga |
|
|
319
341
|
| `flushIntervalMs`, `maxBatch`, `maxQueueSize` | `2000`, `200`, `5000` | lote e fila |
|
|
342
|
+
| `maxBatchBytes`, `maxQueueBytes` | `1,5 MiB`, `16 MiB` | bytes por POST e memória da fila |
|
|
343
|
+
| `requestTimeoutMs`, `shutdownTimeoutMs` | `10000`, `10000` | timeout por POST e prazo do `shutdown()` |
|
|
344
|
+
| `compression`, `exitHooks` | `'gzip'` (`'none'` com `fetch` próprio), `true` | como no tracker |
|
|
320
345
|
| `tracker` | — | correlação com o span corrente (sem ele usa o contexto global do SDK, que funciona quando o tracker está no mesmo processo) |
|
|
321
346
|
| `minLevel` | `trace` | nível mínimo enviado |
|
|
322
347
|
|
|
@@ -387,14 +412,14 @@ curl -X POST http://localhost:4050/v1/logs \\
|
|
|
387
412
|
-H 'content-type: application/json' \\
|
|
388
413
|
-H 'x-fg-tracker-key: stk_demo_0000000000000000000000000000' \\
|
|
389
414
|
-d '{ "logs": [
|
|
390
|
-
{ "ts": "2026-09-12T12:00:00.000Z", "level": "info", "service": "minha-api", "message": "user logged in",
|
|
415
|
+
{ "eventId": "9f1c2a7e4b0d4c4e8a51f0d2b3c4d5e6", "ts": "2026-09-12T12:00:00.000Z", "level": "info", "service": "minha-api", "message": "user logged in",
|
|
391
416
|
"context": { "userId": 42 }, "traceId": "0123456789abcdef0123456789abcdef", "requestId": "req-1", "env": "production" },
|
|
392
417
|
{ "level": "error", "service": "worker", "message": "ECONNRESET while calling payment gateway" }
|
|
393
418
|
] }'
|
|
394
|
-
# → 202 { "accepted": 2 }
|
|
419
|
+
# → 202 { "accepted": 2, "duplicates": 0 }
|
|
395
420
|
```
|
|
396
421
|
|
|
397
|
-
Limites: 500 linhas por lote, 32 KB por mensagem, `context` truncado a 8 KB, `ts` fora da retenção vira `now()`.
|
|
422
|
+
Limites: 500 linhas por lote, 32 KB por mensagem, `context` truncado a 8 KB, `ts` fora da retenção vira `now()`. `eventId` é opcional: com ele, reenviar a mesma linha não grava de novo (48 h); sem ele, cada envio grava.
|
|
398
423
|
|
|
399
424
|
## Infraestrutura
|
|
400
425
|
|
|
@@ -479,7 +504,7 @@ export const handler = tracker.wrapLambda(async (event, context) => {
|
|
|
479
504
|
```
|
|
480
505
|
|
|
481
506
|
- Cria um span raiz `custom` `lambda <função>` por invocação (`faas.coldStart`, `faas.requestId`); desligue com `{ span: false }`.
|
|
482
|
-
- **Sem a camada da extensão**: aguarda
|
|
507
|
+
- **Sem a camada da extensão**: aguarda o envio (até `flushTimeoutMs`) ao fim de cada invocação, para spans e agregados não se perderem no congelamento do ambiente. Não espera backoff e aborta a requisição no prazo: com a API fora, a invocação atrasa no máximo `flushTimeoutMs`.
|
|
483
508
|
- **Com a camada** (`/opt/extensions/fg-tracker-extension` existe): não bloqueia a resposta; a fila sobrevive ao congelamento e é enviada no SIGTERM do encerramento (quando nenhum outro handler de SIGTERM está registrado).
|
|
484
509
|
- Handlers com callback não são suportados (use `async`).
|
|
485
510
|
|
|
@@ -512,7 +537,7 @@ O pacote foi renomeado de `stread-track-sdk` (0.3.0) para `fg-tracker-sdk` (0.4.
|
|
|
512
537
|
| pino `target: 'stread-track-sdk/pino'` | `target: 'fg-tracker-sdk/pino'` | troque junto com o nome do pacote |
|
|
513
538
|
| prefixo de log `[stread-track]` | `[fg-tracker]` | — |
|
|
514
539
|
|
|
515
|
-
Passo a passo: `pnpm remove stread-track-sdk && pnpm add fg-tracker-sdk@^0.4.0`, troque os imports (`from 'stread-track-sdk'` → `from 'fg-tracker-sdk'`, inclusive `/pino` e `/winston`) e, quando quiser, renomeie as variáveis de ambiente e os bins no CI. A API precisa aceitar `x-fg-tracker-key` (versão da API a partir desta mudança) — a produção do FG
|
|
540
|
+
Passo a passo: `pnpm remove stread-track-sdk && pnpm add fg-tracker-sdk@^0.4.0`, troque os imports (`from 'stread-track-sdk'` → `from 'fg-tracker-sdk'`, inclusive `/pino` e `/winston`) e, quando quiser, renomeie as variáveis de ambiente e os bins no CI. A API precisa aceitar `x-fg-tracker-key` (versão da API a partir desta mudança) — a produção do FG Tracker já aceita.
|
|
516
541
|
|
|
517
542
|
## Build
|
|
518
543
|
|
|
@@ -552,5 +577,5 @@ the SDK. Unknown drivers require explicit binding at the operation boundary;
|
|
|
552
577
|
there is no universal automatic monkey patch. Operations outside an active trace
|
|
553
578
|
are executed normally without orphan query traces. Database error values remain
|
|
554
579
|
in the application; exports contain a generic error and an optional error code.
|
|
555
|
-
Use `
|
|
580
|
+
Use `tracker_detect_databases` in the MCP to select the adapter from the actual
|
|
556
581
|
application dependencies/imports and then implement it at the active client.
|
package/dist/cli/release.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* CLI `fg-tracker-release` (alias obsoleto: `stread-track-release`): registra uma release no FG
|
|
3
|
+
* CLI `fg-tracker-release` (alias obsoleto: `stread-track-release`): registra uma release no FG Tracker a partir do git
|
|
4
4
|
* (commits e arquivos/linhas alterados desde a versão anterior), para o painel
|
|
5
5
|
* apontar commits e PRs suspeitos de cada erro (CONTRATO.md §15).
|
|
6
6
|
*
|
package/dist/cli/sourcemaps.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* CLI `fg-tracker-sourcemaps` (alias obsoleto: `stread-track-sourcemaps`): envia os `.map` de um build para o FG
|
|
3
|
+
* CLI `fg-tracker-sourcemaps` (alias obsoleto: `stread-track-sourcemaps`): envia os `.map` de um build para o FG Tracker
|
|
4
4
|
* (`POST /v1/sourcemaps`), para os stacks do navegador chegarem simbolizados
|
|
5
5
|
* (CONTRATO.md §24).
|
|
6
6
|
*
|
package/dist/context.d.ts
CHANGED
|
@@ -4,6 +4,13 @@ export interface SpanContext {
|
|
|
4
4
|
spanId: string;
|
|
5
5
|
/** `false` quando o trace foi descartado pela amostragem (spans não são enviados, mas o contexto se propaga). */
|
|
6
6
|
sampled?: boolean;
|
|
7
|
+
/** Trace excluído por `ignoreTransactions` (não é decisão de amostragem): nada dele é enviado. */
|
|
8
|
+
ignored?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* `spanId` da raiz local (span sem pai neste serviço) do ramo. Um mesmo trace distribuído pode ter
|
|
11
|
+
* várias raízes locais no processo (duas requisições do mesmo trace).
|
|
12
|
+
*/
|
|
13
|
+
localRootId?: string;
|
|
7
14
|
}
|
|
8
15
|
/** Contexto assíncrono compartilhado: quem é o span pai da operação corrente. */
|
|
9
16
|
export declare const als: AsyncLocalStorage<SpanContext>;
|
package/dist/context.d.ts.map
CHANGED
|
@@ -1 +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;
|
|
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;IAClB,kGAAkG;IAClG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;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.map
CHANGED
|
@@ -1 +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;
|
|
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;AAgB1C,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,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Envio da fila na saída do processo (CONTRATO.md §4.3), para scripts e jobs que não chamam
|
|
3
|
+
* `shutdown()`:
|
|
4
|
+
* - `beforeExit` (o event loop esvaziou): envia o que ficou, com prazo; se nada novo entrou
|
|
5
|
+
* desde a última tentativa, não tenta de novo (o processo sai mesmo com a API fora);
|
|
6
|
+
* - SIGTERM/SIGINT: envia com prazo e, se ninguém mais trata o sinal, o reemite para o Node
|
|
7
|
+
* encerrar como encerraria sem o SDK. Com outro listener (inclusive `process.once`, checado na
|
|
8
|
+
* entrega do sinal), quem decide a saída é ele, e o SDK nunca mata o processo.
|
|
9
|
+
* Um registro por processo (um listener por evento), seja quantos trackers, shippers ou cópias do
|
|
10
|
+
* pacote houver.
|
|
11
|
+
* Fora da thread principal e dentro da Lambda (que tem o próprio fluxo, ver `wrapLambda`) não instala.
|
|
12
|
+
*/
|
|
13
|
+
export interface ExitParticipant {
|
|
14
|
+
/** Há algo novo para enviar desde a última tentativa de saída? */
|
|
15
|
+
hasPendingForExit(): boolean;
|
|
16
|
+
/** Envia o que der até `deadline` (epoch ms). Nunca lança. */
|
|
17
|
+
flushForExit(deadline: number): Promise<void>;
|
|
18
|
+
readonly exitTimeoutMs: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function exitHooksSupported(): boolean;
|
|
21
|
+
/** Registra o participante; devolve a função que o remove (chamada no `shutdown()`). */
|
|
22
|
+
export declare function registerExitFlush(participant: ExitParticipant): () => void;
|
|
23
|
+
//# sourceMappingURL=exit-hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exit-hooks.d.ts","sourceRoot":"","sources":["../src/exit-hooks.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC9B,kEAAkE;IAClE,iBAAiB,IAAI,OAAO,CAAC;IAC7B,8DAA8D;IAC9D,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AA6DD,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED,wFAAwF;AACxF,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,eAAe,GAAG,MAAM,IAAI,CAkB1E"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { isMainThread } from 'node:worker_threads';
|
|
2
|
+
const SIGNALS = ['SIGTERM', 'SIGINT'];
|
|
3
|
+
const REGISTRY_KEY = Symbol.for('fg-tracker.exit-hooks.v1');
|
|
4
|
+
function registry() {
|
|
5
|
+
const holder = globalThis;
|
|
6
|
+
const existing = holder[REGISTRY_KEY];
|
|
7
|
+
if (existing)
|
|
8
|
+
return existing;
|
|
9
|
+
const created = {
|
|
10
|
+
participants: new Set(),
|
|
11
|
+
beforeExitInstalled: false,
|
|
12
|
+
signalsInstalled: false,
|
|
13
|
+
exiting: null,
|
|
14
|
+
handlingSignal: false,
|
|
15
|
+
appHandlesSignal: false,
|
|
16
|
+
onBeforeExit: () => {
|
|
17
|
+
// A promessa (sockets, timers do prazo) mantém o loop vivo; quando terminar, `beforeExit`
|
|
18
|
+
// volta a disparar e, sem nada novo, o processo sai.
|
|
19
|
+
if (created.exiting)
|
|
20
|
+
return;
|
|
21
|
+
created.exiting = flushAll(created).finally(() => {
|
|
22
|
+
created.exiting = null;
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
onSignal: (signal) => {
|
|
26
|
+
if (created.handlingSignal) {
|
|
27
|
+
// Segundo sinal durante o envio: sem handler da aplicação, sai já, como sem o SDK.
|
|
28
|
+
if (!created.appHandlesSignal)
|
|
29
|
+
reraise(created, signal);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
created.handlingSignal = true;
|
|
33
|
+
created.appHandlesSignal = process.listeners(signal).some((listener) => listener !== created.onSignal);
|
|
34
|
+
void flushAll(created).finally(() => {
|
|
35
|
+
created.handlingSignal = false;
|
|
36
|
+
if (!created.appHandlesSignal)
|
|
37
|
+
reraise(created, signal);
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
holder[REGISTRY_KEY] = created;
|
|
42
|
+
return created;
|
|
43
|
+
}
|
|
44
|
+
export function exitHooksSupported() {
|
|
45
|
+
return isMainThread && !process.env.AWS_LAMBDA_FUNCTION_NAME;
|
|
46
|
+
}
|
|
47
|
+
/** Registra o participante; devolve a função que o remove (chamada no `shutdown()`). */
|
|
48
|
+
export function registerExitFlush(participant) {
|
|
49
|
+
if (!exitHooksSupported())
|
|
50
|
+
return () => undefined;
|
|
51
|
+
const state = registry();
|
|
52
|
+
state.participants.add(participant);
|
|
53
|
+
if (!state.beforeExitInstalled) {
|
|
54
|
+
state.beforeExitInstalled = true;
|
|
55
|
+
process.on('beforeExit', state.onBeforeExit);
|
|
56
|
+
}
|
|
57
|
+
if (!state.signalsInstalled) {
|
|
58
|
+
state.signalsInstalled = true;
|
|
59
|
+
// Na frente da lista: quando o sinal chega, os handlers da aplicação (inclusive `once`, que o
|
|
60
|
+
// EventEmitter remove ao chamar) ainda estão lá, e a decisão de reemitir é tomada nesse instante.
|
|
61
|
+
for (const signal of SIGNALS)
|
|
62
|
+
process.prependListener(signal, state.onSignal);
|
|
63
|
+
}
|
|
64
|
+
return () => {
|
|
65
|
+
state.participants.delete(participant);
|
|
66
|
+
if (state.participants.size === 0)
|
|
67
|
+
uninstallSignals(state);
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function flushAll(state) {
|
|
71
|
+
const now = Date.now();
|
|
72
|
+
const pending = [...state.participants].filter((participant) => participant.hasPendingForExit());
|
|
73
|
+
if (pending.length === 0)
|
|
74
|
+
return Promise.resolve();
|
|
75
|
+
return Promise.all(pending.map((participant) => participant.flushForExit(now + participant.exitTimeoutMs))).then(() => undefined);
|
|
76
|
+
}
|
|
77
|
+
function reraise(state, signal) {
|
|
78
|
+
uninstallSignals(state);
|
|
79
|
+
process.kill(process.pid, signal);
|
|
80
|
+
}
|
|
81
|
+
function uninstallSignals(state) {
|
|
82
|
+
if (!state.signalsInstalled)
|
|
83
|
+
return;
|
|
84
|
+
state.signalsInstalled = false;
|
|
85
|
+
for (const signal of SIGNALS)
|
|
86
|
+
process.off(signal, state.onSignal);
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=exit-hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exit-hooks.js","sourceRoot":"","sources":["../src/exit-hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/fetch.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { type TrackerCore } from './tracker.js';
|
|
|
3
3
|
* Retorna um `fetch` que cria spans `http.client` nomeados
|
|
4
4
|
* `${method} ${origin}${pathname normalizado}` e propaga o contexto do trace
|
|
5
5
|
* (`traceparent`) para o próximo serviço continuar o mesmo trace (CONTRATO.md §16).
|
|
6
|
-
* Chamadas para o próprio endpoint do FG
|
|
6
|
+
* Chamadas para o próprio endpoint do FG Tracker não são instrumentadas.
|
|
7
7
|
*/
|
|
8
8
|
export declare function createInstrumentedFetch(core: TrackerCore, fetchImpl?: typeof globalThis.fetch): typeof globalThis.fetch;
|
|
9
9
|
//# sourceMappingURL=fetch.d.ts.map
|
package/dist/fetch.js
CHANGED
|
@@ -39,7 +39,7 @@ function withTraceparent(input, init, value) {
|
|
|
39
39
|
* Retorna um `fetch` que cria spans `http.client` nomeados
|
|
40
40
|
* `${method} ${origin}${pathname normalizado}` e propaga o contexto do trace
|
|
41
41
|
* (`traceparent`) para o próximo serviço continuar o mesmo trace (CONTRATO.md §16).
|
|
42
|
-
* Chamadas para o próprio endpoint do FG
|
|
42
|
+
* Chamadas para o próprio endpoint do FG Tracker não são instrumentadas.
|
|
43
43
|
*/
|
|
44
44
|
export function createInstrumentedFetch(core, fetchImpl = globalThis.fetch) {
|
|
45
45
|
const base = fetchImpl;
|
package/dist/global-errors.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { TrackerCore } from './tracker.js';
|
|
2
|
+
/** Prazo do envio antes de encerrar por exceção não tratada. */
|
|
3
|
+
export declare const FATAL_FLUSH_TIMEOUT_MS = 2000;
|
|
2
4
|
/**
|
|
3
5
|
* Captura global de erros do processo (opcional, `captureGlobalErrors: true`):
|
|
4
|
-
* - `uncaughtExceptionMonitor`
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* - `uncaughtExceptionMonitor` registra o erro como span `custom` (`process.uncaughtException`);
|
|
7
|
+
* - sem outro listener de `uncaughtException`, o Node encerraria antes de o envio terminar: o SDK
|
|
8
|
+
* envia a fila com prazo de 2 s (limitado a `shutdownTimeoutMs`), escreve o erro no stderr e sai
|
|
9
|
+
* com código 1, como o Node. Com outro listener, quem decide o destino do processo é ele;
|
|
10
|
+
* - `unhandledRejection` é registrado e, se este for o único listener, o erro é relançado no
|
|
11
|
+
* próximo tick para preservar o comportamento padrão do Node (e cai no caso acima).
|
|
9
12
|
*/
|
|
10
13
|
export declare function installGlobalErrorCapture(core: TrackerCore): () => void;
|
|
11
14
|
//# sourceMappingURL=global-errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-errors.d.ts","sourceRoot":"","sources":["../src/global-errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD
|
|
1
|
+
{"version":3,"file":"global-errors.d.ts","sourceRoot":"","sources":["../src/global-errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,OAAO,CAAC;AA0D3C;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,IAAI,CAkCvE"}
|
package/dist/global-errors.js
CHANGED
|
@@ -1,12 +1,47 @@
|
|
|
1
|
+
/** Prazo do envio antes de encerrar por exceção não tratada. */
|
|
2
|
+
export const FATAL_FLUSH_TIMEOUT_MS = 2000;
|
|
3
|
+
const REGISTRY_KEY = Symbol.for('fg-tracker.global-errors.v1');
|
|
4
|
+
function registry() {
|
|
5
|
+
const holder = globalThis;
|
|
6
|
+
const existing = holder[REGISTRY_KEY];
|
|
7
|
+
if (existing)
|
|
8
|
+
return existing;
|
|
9
|
+
const created = {
|
|
10
|
+
cores: new Set(),
|
|
11
|
+
fatal: false,
|
|
12
|
+
rejectionHandlers: new Set(),
|
|
13
|
+
rethrownPromises: new WeakSet(),
|
|
14
|
+
onFatal: (err) => {
|
|
15
|
+
// Outro listener (da aplicação, inclusive `process.once`) decide o destino do processo. O
|
|
16
|
+
// `onFatal` fica na frente da lista (`prependListener`): quando ele roda, um `once` da
|
|
17
|
+
// aplicação ainda não foi removido pelo EventEmitter.
|
|
18
|
+
if (process.listeners('uncaughtException').some((listener) => listener !== created.onFatal))
|
|
19
|
+
return;
|
|
20
|
+
if (created.fatal)
|
|
21
|
+
return;
|
|
22
|
+
created.fatal = true;
|
|
23
|
+
const now = Date.now();
|
|
24
|
+
const flushes = [...created.cores].map((core) => core.flushForExit(now + Math.min(FATAL_FLUSH_TIMEOUT_MS, core.options.shutdownTimeoutMs)));
|
|
25
|
+
void Promise.allSettled(flushes).finally(() => {
|
|
26
|
+
process.stderr.write(`${err instanceof Error && err.stack ? err.stack : String(err)}\n`);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
holder[REGISTRY_KEY] = created;
|
|
32
|
+
return created;
|
|
33
|
+
}
|
|
1
34
|
/**
|
|
2
35
|
* Captura global de erros do processo (opcional, `captureGlobalErrors: true`):
|
|
3
|
-
* - `uncaughtExceptionMonitor`
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
36
|
+
* - `uncaughtExceptionMonitor` registra o erro como span `custom` (`process.uncaughtException`);
|
|
37
|
+
* - sem outro listener de `uncaughtException`, o Node encerraria antes de o envio terminar: o SDK
|
|
38
|
+
* envia a fila com prazo de 2 s (limitado a `shutdownTimeoutMs`), escreve o erro no stderr e sai
|
|
39
|
+
* com código 1, como o Node. Com outro listener, quem decide o destino do processo é ele;
|
|
40
|
+
* - `unhandledRejection` é registrado e, se este for o único listener, o erro é relançado no
|
|
41
|
+
* próximo tick para preservar o comportamento padrão do Node (e cai no caso acima).
|
|
8
42
|
*/
|
|
9
43
|
export function installGlobalErrorCapture(core) {
|
|
44
|
+
const state = registry();
|
|
10
45
|
const record = (name, err) => {
|
|
11
46
|
if (!core.enabled)
|
|
12
47
|
return;
|
|
@@ -17,19 +52,33 @@ export function installGlobalErrorCapture(core) {
|
|
|
17
52
|
void core.flush();
|
|
18
53
|
};
|
|
19
54
|
const onException = (err) => record('process.uncaughtException', err);
|
|
20
|
-
const onRejection = (reason) => {
|
|
55
|
+
const onRejection = (reason, promise) => {
|
|
21
56
|
record('process.unhandledRejection', reason);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
57
|
+
// Só listeners do SDK (um por tracker): relança uma vez por promessa, como o Node faria sem eles.
|
|
58
|
+
if (!process.listeners('unhandledRejection').every((listener) => state.rejectionHandlers.has(listener)))
|
|
59
|
+
return;
|
|
60
|
+
if (promise && typeof promise === 'object') {
|
|
61
|
+
if (state.rethrownPromises.has(promise))
|
|
62
|
+
return;
|
|
63
|
+
state.rethrownPromises.add(promise);
|
|
26
64
|
}
|
|
65
|
+
process.nextTick(() => {
|
|
66
|
+
throw reason;
|
|
67
|
+
});
|
|
27
68
|
};
|
|
69
|
+
state.rejectionHandlers.add(onRejection);
|
|
28
70
|
process.on('uncaughtExceptionMonitor', onException);
|
|
29
71
|
process.on('unhandledRejection', onRejection);
|
|
72
|
+
if (state.cores.size === 0)
|
|
73
|
+
process.prependListener('uncaughtException', state.onFatal);
|
|
74
|
+
state.cores.add(core);
|
|
30
75
|
return () => {
|
|
31
76
|
process.off('uncaughtExceptionMonitor', onException);
|
|
32
77
|
process.off('unhandledRejection', onRejection);
|
|
78
|
+
state.rejectionHandlers.delete(onRejection);
|
|
79
|
+
state.cores.delete(core);
|
|
80
|
+
if (state.cores.size === 0)
|
|
81
|
+
process.off('uncaughtException', state.onFatal);
|
|
33
82
|
};
|
|
34
83
|
}
|
|
35
84
|
//# sourceMappingURL=global-errors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-errors.js","sourceRoot":"","sources":["../src/global-errors.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"global-errors.js","sourceRoot":"","sources":["../src/global-errors.ts"],"names":[],"mappings":"AAEA,gEAAgE;AAChE,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AA4B3C,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;AAE/D,SAAS,QAAQ;IACf,MAAM,MAAM,GAAG,UAAkE,CAAC;IAClF,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;IACtC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,OAAO,GAAkB;QAC7B,KAAK,EAAE,IAAI,GAAG,EAAE;QAChB,KAAK,EAAE,KAAK;QACZ,iBAAiB,EAAE,IAAI,GAAG,EAAE;QAC5B,gBAAgB,EAAE,IAAI,OAAO,EAAE;QAC/B,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACf,0FAA0F;YAC1F,uFAAuF;YACvF,sDAAsD;YACtD,IAAI,OAAO,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,OAAO,CAAC,OAAO,CAAC;gBAAE,OAAO;YACpG,IAAI,OAAO,CAAC,KAAK;gBAAE,OAAO;YAC1B,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;YACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,sBAAsB,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;YAC5I,KAAK,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;gBAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACzF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;IACF,MAAM,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC;IAC/B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAiB;IACzD,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,GAAY,EAAE,EAAE;QAC5C,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,KAAK,2BAA2B,EAAE,EAAE,IAAI,CAAC,CAAC;QACtH,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAAE,IAAI,CAAC,GAAG,EAAE,CAAC;QACjC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC,CAAC;IACF,MAAM,WAAW,GAAG,CAAC,GAAY,EAAE,EAAE,CAAC,MAAM,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAC;IAC/E,MAAM,WAAW,GAAG,CAAC,MAAe,EAAE,OAAyB,EAAE,EAAE;QACjE,MAAM,CAAC,4BAA4B,EAAE,MAAM,CAAC,CAAC;QAC7C,kGAAkG;QAClG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,QAAgE,CAAC,CAAC;YAAE,OAAO;QACxK,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC3C,IAAI,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC;gBAAE,OAAO;YAChD,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE;YACpB,MAAM,MAAM,CAAC;QACf,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IACF,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,CAAC,0BAA0B,EAAE,WAAW,CAAC,CAAC;IACpD,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,WAAW,CAAC,CAAC;IAC9C,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,CAAC,eAAe,CAAC,mBAAmB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACxF,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACtB,OAAO,GAAG,EAAE;QACV,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,WAAW,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,WAAW,CAAC,CAAC;QAC/C,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC5C,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9E,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export type { InfraReporter, InfraReporterOptions } from './infra/ecs.js';
|
|
|
18
18
|
export { hasLambdaExtension, LAMBDA_EXTENSION_PATH } from './infra/lambda.js';
|
|
19
19
|
export type { LambdaContextLike, LambdaHandler, WrapLambdaOptions } from './infra/lambda.js';
|
|
20
20
|
/**
|
|
21
|
-
* Cria um tracker do FG
|
|
21
|
+
* Cria um tracker do FG Tracker.
|
|
22
22
|
*
|
|
23
23
|
* ```ts
|
|
24
24
|
* const tracker = createTracker({ apiKey: process.env.FG_TRACKER_KEY!, endpoint: 'http://localhost:4050', serviceName: 'minha-app' });
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,8BAA8B,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAiBxG,OAAO,KAAK,EAAsE,OAAO,EAAE,cAAc,EAAW,MAAM,YAAY,CAAC;AAEvI,YAAY,EACV,UAAU,EACV,aAAa,EACb,cAAc,EACd,sBAAsB,EACtB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,OAAO,EACP,cAAc,EACd,OAAO,GACR,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,YAAY,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvF,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtF,YAAY,EAAE,cAAc,EAAE,sBAAsB,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACjH,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACvF,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAChF,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE7F;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,8BAA8B,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAiBxG,OAAO,KAAK,EAAsE,OAAO,EAAE,cAAc,EAAW,MAAM,YAAY,CAAC;AAEvI,YAAY,EACV,UAAU,EACV,aAAa,EACb,cAAc,EACd,sBAAsB,EACtB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,OAAO,EACP,cAAc,EACd,OAAO,GACR,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,YAAY,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvF,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtF,YAAY,EAAE,cAAc,EAAE,sBAAsB,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACjH,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACvF,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAChF,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE7F;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAyH9D;AAyBD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACzD,YAAY,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC5I,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC/D,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEtH,YAAY,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ export { InfraAggregator, detectArchitecture, infraKey } from './infra/aggregato
|
|
|
24
24
|
export { parseArn, sqsQueueRef } from './infra/aws.js';
|
|
25
25
|
export { hasLambdaExtension, LAMBDA_EXTENSION_PATH } from './infra/lambda.js';
|
|
26
26
|
/**
|
|
27
|
-
* Cria um tracker do FG
|
|
27
|
+
* Cria um tracker do FG Tracker.
|
|
28
28
|
*
|
|
29
29
|
* ```ts
|
|
30
30
|
* const tracker = createTracker({ apiKey: process.env.FG_TRACKER_KEY!, endpoint: 'http://localhost:4050', serviceName: 'minha-app' });
|
|
@@ -47,8 +47,7 @@ export function createTracker(options) {
|
|
|
47
47
|
// Ligado por default: a saída HTTP que não passa pelo `fetch` (AWS SDK, axios,
|
|
48
48
|
// got, node-fetch 2, gaxios, web-push) é invisível sem isto.
|
|
49
49
|
const uninstrumentNodeHttp = options.instrumentNodeHttp !== false && core.enabled ? instrumentNodeHttp(core) : undefined;
|
|
50
|
-
|
|
51
|
-
installGlobalErrorCapture(core);
|
|
50
|
+
const uninstallGlobalErrors = options.captureGlobalErrors && core.enabled ? installGlobalErrorCapture(core) : undefined;
|
|
52
51
|
const tracker = {
|
|
53
52
|
express: (expressOptions) => createExpressMiddleware(core, expressOptions),
|
|
54
53
|
expressErrorHandler: () => createExpressErrorHandler(core),
|
|
@@ -143,9 +142,10 @@ export function createTracker(options) {
|
|
|
143
142
|
flush: () => core.flush(),
|
|
144
143
|
// As inscrições em `diagnostics_channel` são do processo, não do tracker:
|
|
145
144
|
// sem cancelar, um tracker desligado continuaria instrumentando requisições.
|
|
146
|
-
shutdown: async () => {
|
|
145
|
+
shutdown: async (shutdownOptions) => {
|
|
147
146
|
uninstrumentNodeHttp?.();
|
|
148
|
-
await core.shutdown();
|
|
147
|
+
await core.shutdown(shutdownOptions);
|
|
148
|
+
uninstallGlobalErrors?.();
|
|
149
149
|
},
|
|
150
150
|
};
|
|
151
151
|
return tracker;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAErH,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AA6BtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvF,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEtF,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAIvD,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG9E;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,OAAuB;IACnD,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,aAAa,GAAmC,IAAI,CAAC;IAEzD,MAAM,qBAAqB,GAAG,GAA4B,EAAE;QAC1D,IAAI,aAAa;YAAE,OAAO,aAAa,CAAC;QACxC,aAAa,GAAG,UAAU,CAAC,KAAK,CAAC;QACjC,UAAU,CAAC,KAAK,GAAG,uBAAuB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QAChE,OAAO,aAAa,CAAC;IACvB,CAAC,CAAC;IACF,IAAI,OAAO,CAAC,qBAAqB,IAAI,IAAI,CAAC,OAAO;QAAE,qBAAqB,EAAE,CAAC;IAC3E,+EAA+E;IAC/E,6DAA6D;IAC7D,MAAM,oBAAoB,GACxB,OAAO,CAAC,kBAAkB,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9F,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|