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.
Files changed (91) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +375 -0
  3. package/dist/cli/release.d.ts +3 -0
  4. package/dist/cli/release.d.ts.map +1 -0
  5. package/dist/cli/release.js +134 -0
  6. package/dist/cli/release.js.map +1 -0
  7. package/dist/cli/sourcemaps.d.ts +3 -0
  8. package/dist/cli/sourcemaps.d.ts.map +1 -0
  9. package/dist/cli/sourcemaps.js +98 -0
  10. package/dist/cli/sourcemaps.js.map +1 -0
  11. package/dist/constants.d.ts +28 -0
  12. package/dist/constants.d.ts.map +1 -0
  13. package/dist/constants.js +35 -0
  14. package/dist/constants.js.map +1 -0
  15. package/dist/context.d.ts +22 -0
  16. package/dist/context.d.ts.map +1 -0
  17. package/dist/context.js +42 -0
  18. package/dist/context.js.map +1 -0
  19. package/dist/database.d.ts +29 -0
  20. package/dist/database.d.ts.map +1 -0
  21. package/dist/database.js +157 -0
  22. package/dist/database.js.map +1 -0
  23. package/dist/express.d.ts +17 -0
  24. package/dist/express.d.ts.map +1 -0
  25. package/dist/express.js +125 -0
  26. package/dist/express.js.map +1 -0
  27. package/dist/fetch.d.ts +9 -0
  28. package/dist/fetch.d.ts.map +1 -0
  29. package/dist/fetch.js +78 -0
  30. package/dist/fetch.js.map +1 -0
  31. package/dist/global-errors.d.ts +11 -0
  32. package/dist/global-errors.d.ts.map +1 -0
  33. package/dist/global-errors.js +35 -0
  34. package/dist/global-errors.js.map +1 -0
  35. package/dist/index.d.ts +29 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +154 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/logs/nest-logger.d.ts +40 -0
  40. package/dist/logs/nest-logger.d.ts.map +1 -0
  41. package/dist/logs/nest-logger.js +99 -0
  42. package/dist/logs/nest-logger.js.map +1 -0
  43. package/dist/logs/pino.d.ts +24 -0
  44. package/dist/logs/pino.d.ts.map +1 -0
  45. package/dist/logs/pino.js +62 -0
  46. package/dist/logs/pino.js.map +1 -0
  47. package/dist/logs/shipper.d.ts +18 -0
  48. package/dist/logs/shipper.d.ts.map +1 -0
  49. package/dist/logs/shipper.js +217 -0
  50. package/dist/logs/shipper.js.map +1 -0
  51. package/dist/logs/types.d.ts +84 -0
  52. package/dist/logs/types.d.ts.map +1 -0
  53. package/dist/logs/types.js +47 -0
  54. package/dist/logs/types.js.map +1 -0
  55. package/dist/logs/winston.d.ts +31 -0
  56. package/dist/logs/winston.d.ts.map +1 -0
  57. package/dist/logs/winston.js +57 -0
  58. package/dist/logs/winston.js.map +1 -0
  59. package/dist/monitors.d.ts +8 -0
  60. package/dist/monitors.d.ts.map +1 -0
  61. package/dist/monitors.js +69 -0
  62. package/dist/monitors.js.map +1 -0
  63. package/dist/next.d.ts +9 -0
  64. package/dist/next.d.ts.map +1 -0
  65. package/dist/next.js +55 -0
  66. package/dist/next.js.map +1 -0
  67. package/dist/normalize.d.ts +12 -0
  68. package/dist/normalize.d.ts.map +1 -0
  69. package/dist/normalize.js +113 -0
  70. package/dist/normalize.js.map +1 -0
  71. package/dist/pg.d.ts +9 -0
  72. package/dist/pg.d.ts.map +1 -0
  73. package/dist/pg.js +83 -0
  74. package/dist/pg.js.map +1 -0
  75. package/dist/releases.d.ts +5 -0
  76. package/dist/releases.d.ts.map +1 -0
  77. package/dist/releases.js +30 -0
  78. package/dist/releases.js.map +1 -0
  79. package/dist/scrub.d.ts +11 -0
  80. package/dist/scrub.d.ts.map +1 -0
  81. package/dist/scrub.js +34 -0
  82. package/dist/scrub.js.map +1 -0
  83. package/dist/tracker.d.ts +99 -0
  84. package/dist/tracker.d.ts.map +1 -0
  85. package/dist/tracker.js +400 -0
  86. package/dist/tracker.js.map +1 -0
  87. package/dist/types.d.ts +264 -0
  88. package/dist/types.d.ts.map +1 -0
  89. package/dist/types.js +2 -0
  90. package/dist/types.js.map +1 -0
  91. package/package.json +98 -0
@@ -0,0 +1,217 @@
1
+ import { hostname } from 'node:os';
2
+ import { API_KEY_HEADER, DEFAULT_ENDPOINT } from '../constants.js';
3
+ import { currentSpanContext } from '../context.js';
4
+ import { LOG_LEVEL_NUMBER, toLogLevel } from './types.js';
5
+ const DEFAULT_FLUSH_INTERVAL_MS = 2000;
6
+ const DEFAULT_MAX_BATCH = 200;
7
+ const DEFAULT_MAX_QUEUE = 5000;
8
+ /** Limite da API por requisição (CONTRATO.md §11). */
9
+ const API_MAX_BATCH = 500;
10
+ const RETRY_DELAY_MS = 400;
11
+ /**
12
+ * Fila + envio em lote para `POST /v1/logs`. Mesma política do tracker:
13
+ * timer com `unref()`, fila limitada (descarta as mais antigas), aviso único
14
+ * em falha, 4xx descarta o lote, 5xx/rede tenta de novo uma vez e depois
15
+ * devolve o lote para o próximo flush.
16
+ */
17
+ export function createLogShipper(options) {
18
+ return new LogShipperImpl(options);
19
+ }
20
+ class LogShipperImpl {
21
+ options;
22
+ apiKey;
23
+ env;
24
+ host;
25
+ minLevel;
26
+ tracker;
27
+ fetchImpl;
28
+ debug;
29
+ active;
30
+ queue = [];
31
+ timer = null;
32
+ flushing = null;
33
+ warnedFailure = false;
34
+ stopped = false;
35
+ constructor(raw) {
36
+ this.options = {
37
+ endpoint: (raw.endpoint ?? DEFAULT_ENDPOINT).replace(/\/+$/, ''),
38
+ service: raw.service || 'default',
39
+ flushIntervalMs: Math.max(100, raw.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS),
40
+ maxBatch: Math.min(API_MAX_BATCH, Math.max(1, raw.maxBatch ?? DEFAULT_MAX_BATCH)),
41
+ maxQueueSize: Math.max(10, raw.maxQueueSize ?? DEFAULT_MAX_QUEUE),
42
+ };
43
+ this.apiKey = raw.apiKey ?? '';
44
+ this.env = raw.env;
45
+ this.host = raw.host === false ? undefined : (raw.host ?? safeHostname());
46
+ this.minLevel = LOG_LEVEL_NUMBER[raw.minLevel ?? 'trace'];
47
+ this.tracker = raw.tracker;
48
+ this.fetchImpl = raw.fetch ?? globalThis.fetch;
49
+ this.debug = raw.debug ?? false;
50
+ this.active = (raw.enabled ?? true) && Boolean(this.apiKey);
51
+ if (!this.active) {
52
+ if (!this.apiKey && (raw.enabled ?? true))
53
+ console.warn('[fg-tracker] apiKey ausente: envio de logs desabilitado.');
54
+ return;
55
+ }
56
+ this.timer = setInterval(() => {
57
+ void this.flush();
58
+ }, this.options.flushIntervalMs);
59
+ if (typeof this.timer === 'object' && this.timer && 'unref' in this.timer)
60
+ this.timer.unref();
61
+ }
62
+ get enabled() {
63
+ return this.active && !this.stopped;
64
+ }
65
+ get size() {
66
+ return this.queue.length;
67
+ }
68
+ log(level, message, context) {
69
+ this.push({ level, message, context });
70
+ }
71
+ push(entry) {
72
+ if (!this.enabled)
73
+ return;
74
+ const level = toLogLevel(entry.level ?? 'info');
75
+ if (LOG_LEVEL_NUMBER[level] < this.minLevel)
76
+ return;
77
+ const correlation = entry.traceId ? null : (this.tracker?.currentSpan() ?? currentSpanContext());
78
+ const line = {
79
+ ts: toIso(entry.ts),
80
+ level,
81
+ service: entry.service || this.options.service,
82
+ message: typeof entry.message === 'string' ? entry.message : String(entry.message),
83
+ };
84
+ if (entry.context && Object.keys(entry.context).length > 0)
85
+ line.context = entry.context;
86
+ const traceId = entry.traceId ?? correlation?.traceId;
87
+ const spanId = entry.spanId ?? correlation?.spanId;
88
+ if (traceId)
89
+ line.traceId = traceId;
90
+ if (spanId)
91
+ line.spanId = spanId;
92
+ if (entry.requestId)
93
+ line.requestId = entry.requestId;
94
+ const env = entry.env ?? this.env;
95
+ if (env)
96
+ line.env = env;
97
+ const host = entry.host ?? this.host;
98
+ if (host)
99
+ line.host = host;
100
+ this.queue.push(line);
101
+ if (this.queue.length > this.options.maxQueueSize) {
102
+ this.queue.splice(0, this.queue.length - this.options.maxQueueSize);
103
+ }
104
+ if (this.queue.length >= this.options.maxBatch)
105
+ void this.flush();
106
+ }
107
+ async flush() {
108
+ if (!this.active)
109
+ return;
110
+ if (this.flushing)
111
+ return this.flushing;
112
+ if (this.queue.length === 0)
113
+ return;
114
+ this.flushing = this.doFlush().finally(() => {
115
+ this.flushing = null;
116
+ });
117
+ return this.flushing;
118
+ }
119
+ async shutdown() {
120
+ if (this.timer) {
121
+ clearInterval(this.timer);
122
+ this.timer = null;
123
+ }
124
+ await this.flush();
125
+ this.stopped = true;
126
+ }
127
+ async doFlush() {
128
+ while (this.queue.length > 0) {
129
+ const batch = this.queue.splice(0, this.options.maxBatch);
130
+ let outcome = await this.send(batch);
131
+ if (outcome === 'retry') {
132
+ await sleep(RETRY_DELAY_MS);
133
+ outcome = await this.send(batch);
134
+ }
135
+ if (outcome === 'retry') {
136
+ // Devolve para a frente da fila e tenta no próximo flush.
137
+ this.queue.unshift(...batch);
138
+ if (this.queue.length > this.options.maxQueueSize) {
139
+ this.queue.splice(0, this.queue.length - this.options.maxQueueSize);
140
+ }
141
+ return;
142
+ }
143
+ }
144
+ }
145
+ async send(logs) {
146
+ try {
147
+ const res = await this.fetchImpl(`${this.options.endpoint}/v1/logs`, {
148
+ method: 'POST',
149
+ headers: { 'content-type': 'application/json', [API_KEY_HEADER]: this.apiKey },
150
+ body: JSON.stringify({ logs }),
151
+ });
152
+ if (!res.ok) {
153
+ const retry = res.status >= 500 || res.status === 429;
154
+ this.warnOnce(`logs respondeu ${res.status}${retry ? ' (vai tentar de novo)' : ' (lote descartado)'}`);
155
+ return retry ? 'retry' : 'drop';
156
+ }
157
+ if (this.warnedFailure) {
158
+ this.warnedFailure = false;
159
+ if (this.debug)
160
+ console.info('[fg-tracker] envio de logs restabelecido.');
161
+ }
162
+ if (this.debug)
163
+ console.info(`[fg-tracker] enviadas ${logs.length} linhas de log.`);
164
+ return 'ok';
165
+ }
166
+ catch (err) {
167
+ this.warnOnce(`falha ao enviar logs para ${this.options.endpoint}/v1/logs: ${err?.message ?? err}`);
168
+ return 'retry';
169
+ }
170
+ }
171
+ warnOnce(message) {
172
+ if (this.warnedFailure)
173
+ return;
174
+ this.warnedFailure = true;
175
+ console.warn(`[fg-tracker] ${message}`);
176
+ }
177
+ }
178
+ function toIso(value) {
179
+ if (value instanceof Date)
180
+ return Number.isNaN(value.getTime()) ? new Date().toISOString() : value.toISOString();
181
+ if (typeof value === 'number')
182
+ return new Date(value).toISOString();
183
+ if (typeof value === 'string' && value) {
184
+ const parsed = new Date(value);
185
+ if (!Number.isNaN(parsed.getTime()))
186
+ return parsed.toISOString();
187
+ }
188
+ return new Date().toISOString();
189
+ }
190
+ function safeHostname() {
191
+ try {
192
+ return hostname();
193
+ }
194
+ catch {
195
+ return undefined;
196
+ }
197
+ }
198
+ function sleep(ms) {
199
+ return new Promise((resolve) => setTimeout(resolve, ms));
200
+ }
201
+ /**
202
+ * `mixin` para o pino: injeta `traceId`/`spanId` do span corrente em cada linha.
203
+ * Necessário porque o transport roda em worker thread, sem acesso ao AsyncLocalStorage da app.
204
+ *
205
+ * ```ts
206
+ * const logger = pino({ mixin: traceMixin(tracker), transport: pinoTransport({ ... }) });
207
+ * ```
208
+ */
209
+ export function traceMixin(tracker) {
210
+ return () => {
211
+ const ctx = tracker?.currentSpan() ?? currentSpanContext();
212
+ if (!ctx)
213
+ return {};
214
+ return { traceId: ctx.traceId, spanId: ctx.spanId };
215
+ };
216
+ }
217
+ //# sourceMappingURL=shipper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shipper.js","sourceRoot":"","sources":["../../src/logs/shipper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAwF,MAAM,YAAY,CAAC;AAEhJ,MAAM,yBAAyB,GAAG,IAAI,CAAC;AACvC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAC9B,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC/B,sDAAsD;AACtD,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAA0B;IACzD,OAAO,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,cAAc;IACT,OAAO,CAAwB;IACvB,MAAM,CAAS;IACf,GAAG,CAAqB;IACxB,IAAI,CAAqB;IACzB,QAAQ,CAAS;IACjB,OAAO,CAA+B;IACtC,SAAS,CAA0B;IACnC,KAAK,CAAU;IACf,MAAM,CAAU;IACzB,KAAK,GAAe,EAAE,CAAC;IACvB,KAAK,GAA0C,IAAI,CAAC;IACpD,QAAQ,GAAyB,IAAI,CAAC;IACtC,aAAa,GAAG,KAAK,CAAC;IACtB,OAAO,GAAG,KAAK,CAAC;IAExB,YAAY,GAAsB;QAChC,IAAI,CAAC,OAAO,GAAG;YACb,QAAQ,EAAE,CAAC,GAAG,CAAC,QAAQ,IAAI,gBAAgB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAChE,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,SAAS;YACjC,eAAe,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,eAAe,IAAI,yBAAyB,CAAC;YAChF,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,IAAI,iBAAiB,CAAC,CAAC;YACjF,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,YAAY,IAAI,iBAAiB,CAAC;SAClE,CAAC;QACF,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC;QAC/B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,YAAY,EAAE,CAAC,CAAC;QAC1E,IAAI,CAAC,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC;QAC1D,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC;QAC/C,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC;QAChC,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5D,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC;YACpH,OAAO;QACT,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC5B,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACjC,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,IAAI,OAAO,IAAI,IAAI,CAAC,KAAK;YAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IAChG,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;IACtC,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED,GAAG,CAAC,KAAe,EAAE,OAAe,EAAE,OAAiC;QACrE,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,CAAC,KAAe;QAClB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAC1B,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC;QAChD,IAAI,gBAAgB,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEpD,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,kBAAkB,EAAE,CAAC,CAAC;QACjG,MAAM,IAAI,GAAa;YACrB,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACnB,KAAK;YACL,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO;YAC9C,OAAO,EAAE,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;SACnF,CAAC;QACF,IAAI,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QACzF,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,WAAW,EAAE,OAAO,CAAC;QACtD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,WAAW,EAAE,MAAM,CAAC;QACnD,IAAI,OAAO;YAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACpC,IAAI,MAAM;YAAE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACjC,IAAI,KAAK,CAAC,SAAS;YAAE,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QACtD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;QAClC,IAAI,GAAG;YAAE,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACxB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC;QACrC,IAAI,IAAI;YAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QAE3B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YAClD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ;YAAE,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QACzB,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACxC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACpC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;YAC1C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACvB,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;IAEO,KAAK,CAAC,OAAO;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC1D,IAAI,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrC,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;gBACxB,MAAM,KAAK,CAAC,cAAc,CAAC,CAAC;gBAC5B,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnC,CAAC;YACD,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;gBACxB,0DAA0D;gBAC1D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;gBAC7B,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;oBAClD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;gBACtE,CAAC;gBACD,OAAO;YACT,CAAC;QACH,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,IAAI,CAAC,IAAgB;QACjC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,UAAU,EAAE;gBACnE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE;gBAC9E,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;aAC/B,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC;gBACtD,IAAI,CAAC,QAAQ,CAAC,kBAAkB,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,oBAAoB,EAAE,CAAC,CAAC;gBACvG,OAAO,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;YAClC,CAAC;YACD,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACvB,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;gBAC3B,IAAI,IAAI,CAAC,KAAK;oBAAE,OAAO,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;YAC5E,CAAC;YACD,IAAI,IAAI,CAAC,KAAK;gBAAE,OAAO,CAAC,IAAI,CAAC,yBAAyB,IAAI,CAAC,MAAM,iBAAiB,CAAC,CAAC;YACpF,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,QAAQ,CAAC,6BAA6B,IAAI,CAAC,OAAO,CAAC,QAAQ,aAAc,GAAa,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC;YAC/G,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IAEO,QAAQ,CAAC,OAAe;QAC9B,IAAI,IAAI,CAAC,aAAa;YAAE,OAAO;QAC/B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,OAAO,CAAC,IAAI,CAAC,gBAAgB,OAAO,EAAE,CAAC,CAAC;IAC1C,CAAC;CACF;AAED,SAAS,KAAK,CAAC,KAAqB;IAClC,IAAI,KAAK,YAAY,IAAI;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;IACjH,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;IACpE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAAE,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC;IACnE,CAAC;IACD,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAClC,CAAC;AAED,SAAS,YAAY;IACnB,IAAI,CAAC;QACH,OAAO,QAAQ,EAAE,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,OAAsC;IAC/D,OAAO,GAA2B,EAAE;QAClC,MAAM,GAAG,GAAG,OAAO,EAAE,WAAW,EAAE,IAAI,kBAAkB,EAAE,CAAC;QAC3D,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;IACtD,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Tipos do envio de logs (CONTRATO.md §11). Espelham o body de `POST /v1/logs`.
3
+ */
4
+ export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
5
+ /** Números do pino: trace 10, debug 20, info 30, warn 40, error 50, fatal 60. */
6
+ export declare const LOG_LEVEL_NUMBER: Record<LogLevel, number>;
7
+ /** Converte número (pino) ou nome (winston/npm) em nível do contrato. */
8
+ export declare function toLogLevel(value: unknown): LogLevel;
9
+ /** Linha como o SDK envia. */
10
+ export interface LogEntry {
11
+ ts: string;
12
+ level: LogLevel;
13
+ service: string;
14
+ message: string;
15
+ context?: Record<string, unknown>;
16
+ traceId?: string;
17
+ spanId?: string;
18
+ requestId?: string;
19
+ env?: string;
20
+ host?: string;
21
+ }
22
+ /** Linha como o chamador entrega ao shipper (tudo opcional exceto a mensagem). */
23
+ export interface LogInput {
24
+ ts?: string | number | Date;
25
+ level?: LogLevel | number | string;
26
+ service?: string;
27
+ message: string;
28
+ context?: Record<string, unknown>;
29
+ traceId?: string | null;
30
+ spanId?: string | null;
31
+ requestId?: string | null;
32
+ env?: string | null;
33
+ host?: string | null;
34
+ }
35
+ /** Subconjunto do `Tracker` usado para correlação (evita dependência circular de tipos). */
36
+ export interface SpanContextSource {
37
+ currentSpan(): {
38
+ traceId: string;
39
+ spanId: string;
40
+ } | undefined;
41
+ }
42
+ export interface LogShipperOptions {
43
+ /** Chave do projeto (`stk_...`). Sem chave o shipper vira no-op (com aviso). */
44
+ apiKey: string;
45
+ /** URL base da API. Default `http://localhost:4050`. */
46
+ endpoint?: string;
47
+ /** Nome do serviço; vai em toda linha que não trouxer o próprio. */
48
+ service: string;
49
+ /** Ambiente (`production`, `staging`...). */
50
+ env?: string;
51
+ /** Host; default `os.hostname()`. `false` desliga. */
52
+ host?: string | false;
53
+ /** Intervalo de envio em ms. Default 2000. */
54
+ flushIntervalMs?: number;
55
+ /** Linhas por lote (máximo 500, limite da API). Default 200. */
56
+ maxBatch?: number;
57
+ /** Tamanho máximo da fila antes de descartar as mais antigas. Default 5000. */
58
+ maxQueueSize?: number;
59
+ /** Tracker do FG Tracker para correlação de traceId/spanId (senão usa o contexto global do SDK). */
60
+ tracker?: SpanContextSource;
61
+ /** Nível mínimo enviado. Default `trace` (tudo). */
62
+ minLevel?: LogLevel;
63
+ /** Desliga sem remover o código. Default `true`. */
64
+ enabled?: boolean;
65
+ /** Loga cada envio no console. Default `false`. */
66
+ debug?: boolean;
67
+ /** Implementação de fetch. Default `globalThis.fetch`. */
68
+ fetch?: typeof globalThis.fetch;
69
+ }
70
+ export interface LogShipper {
71
+ /** Enfileira uma linha (normaliza nível, timestamp e correlação). */
72
+ push(entry: LogInput): void;
73
+ /** Atalhos por nível. */
74
+ log(level: LogLevel, message: string, context?: Record<string, unknown>): void;
75
+ /** Envia imediatamente tudo o que está na fila. */
76
+ flush(): Promise<void>;
77
+ /** Para o timer e envia o que restou. */
78
+ shutdown(): Promise<void>;
79
+ /** Linhas aguardando envio. */
80
+ readonly size: number;
81
+ readonly enabled: boolean;
82
+ readonly options: Readonly<Required<Pick<LogShipperOptions, 'endpoint' | 'service' | 'flushIntervalMs' | 'maxBatch' | 'maxQueueSize'>>>;
83
+ }
84
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/logs/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAE/E,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAOrD,CAAC;AAEF,yEAAyE;AACzE,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAqBnD;AAED,8BAA8B;AAC9B,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,kFAAkF;AAClF,MAAM,WAAW,QAAQ;IACvB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,4FAA4F;AAC5F,MAAM,WAAW,iBAAiB;IAChC,WAAW,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CAChE;AAED,MAAM,WAAW,iBAAiB;IAChC,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACtB,8CAA8C;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oGAAoG;IACpG,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,oDAAoD;IACpD,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,oDAAoD;IACpD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mDAAmD;IACnD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAED,MAAM,WAAW,UAAU;IACzB,qEAAqE;IACrE,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC5B,yBAAyB;IACzB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/E,mDAAmD;IACnD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,yCAAyC;IACzC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,UAAU,GAAG,SAAS,GAAG,iBAAiB,GAAG,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;CACzI"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Tipos do envio de logs (CONTRATO.md §11). Espelham o body de `POST /v1/logs`.
3
+ */
4
+ /** Números do pino: trace 10, debug 20, info 30, warn 40, error 50, fatal 60. */
5
+ export const LOG_LEVEL_NUMBER = {
6
+ trace: 10,
7
+ debug: 20,
8
+ info: 30,
9
+ warn: 40,
10
+ error: 50,
11
+ fatal: 60,
12
+ };
13
+ /** Converte número (pino) ou nome (winston/npm) em nível do contrato. */
14
+ export function toLogLevel(value) {
15
+ if (typeof value === 'number') {
16
+ if (value >= 60)
17
+ return 'fatal';
18
+ if (value >= 50)
19
+ return 'error';
20
+ if (value >= 40)
21
+ return 'warn';
22
+ if (value >= 30)
23
+ return 'info';
24
+ if (value >= 20)
25
+ return 'debug';
26
+ return 'trace';
27
+ }
28
+ if (typeof value === 'string') {
29
+ const name = value.toLowerCase();
30
+ if (name in LOG_LEVEL_NUMBER)
31
+ return name;
32
+ // Níveis npm/syslog do winston fora do contrato.
33
+ if (name === 'crit' || name === 'alert' || name === 'emerg')
34
+ return 'fatal';
35
+ if (name === 'warning')
36
+ return 'warn';
37
+ if (name === 'notice' || name === 'http')
38
+ return 'info';
39
+ if (name === 'verbose' || name === 'silly')
40
+ return 'debug';
41
+ const asNumber = Number(name);
42
+ if (Number.isFinite(asNumber))
43
+ return toLogLevel(asNumber);
44
+ }
45
+ return 'info';
46
+ }
47
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/logs/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,iFAAiF;AACjF,MAAM,CAAC,MAAM,gBAAgB,GAA6B;IACxD,KAAK,EAAE,EAAE;IACT,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,EAAE;IACR,KAAK,EAAE,EAAE;IACT,KAAK,EAAE,EAAE;CACV,CAAC;AAEF,yEAAyE;AACzE,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,KAAK,IAAI,EAAE;YAAE,OAAO,OAAO,CAAC;QAChC,IAAI,KAAK,IAAI,EAAE;YAAE,OAAO,OAAO,CAAC;QAChC,IAAI,KAAK,IAAI,EAAE;YAAE,OAAO,MAAM,CAAC;QAC/B,IAAI,KAAK,IAAI,EAAE;YAAE,OAAO,MAAM,CAAC;QAC/B,IAAI,KAAK,IAAI,EAAE;YAAE,OAAO,OAAO,CAAC;QAChC,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QACjC,IAAI,IAAI,IAAI,gBAAgB;YAAE,OAAO,IAAgB,CAAC;QACtD,iDAAiD;QACjD,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO;YAAE,OAAO,OAAO,CAAC;QAC5E,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC;QACtC,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,MAAM;YAAE,OAAO,MAAM,CAAC;QACxD,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,OAAO;YAAE,OAAO,OAAO,CAAC;QAC3D,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,31 @@
1
+ import Transport from 'winston-transport';
2
+ import type { LogShipper, LogShipperOptions } from './types.js';
3
+ export type WinstonTransportOptions = LogShipperOptions & {
4
+ /** Nível mínimo do winston para este transport (`level` do `winston-transport`). */
5
+ level?: string;
6
+ silent?: boolean;
7
+ handleExceptions?: boolean;
8
+ handleRejections?: boolean;
9
+ };
10
+ /**
11
+ * Transport do winston:
12
+ *
13
+ * ```ts
14
+ * import winston from 'winston';
15
+ * import { FgTrackerTransport } from 'fg-tracker-sdk/winston';
16
+ * const logger = winston.createLogger({ transports: [new FgTrackerTransport({ apiKey, service: 'minha-api', tracker })] });
17
+ * ```
18
+ */
19
+ export declare class FgTrackerTransport extends Transport {
20
+ readonly shipper: LogShipper;
21
+ constructor(options: WinstonTransportOptions);
22
+ log(info: Record<string, unknown>, next: () => void): void;
23
+ close(): void;
24
+ }
25
+ /** @deprecated use `FgTrackerTransport` (nome antigo do `stread-track-sdk`; removido na 1.0). */
26
+ export declare const StreadTrackTransport: typeof FgTrackerTransport;
27
+ /** @deprecated use `FgTrackerTransport` (nome antigo do `stread-track-sdk`; removido na 1.0). */
28
+ export type StreadTrackTransport = FgTrackerTransport;
29
+ /** Fábrica no estilo dos outros helpers do SDK. */
30
+ export declare function winstonTransport(options: WinstonTransportOptions): FgTrackerTransport;
31
+ //# sourceMappingURL=winston.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"winston.d.ts","sourceRoot":"","sources":["../../src/logs/winston.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAE1C,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,GAAG;IACxD,oFAAoF;IACpF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAIF;;;;;;;;GAQG;AACH,qBAAa,kBAAmB,SAAQ,SAAS;IAC/C,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;gBAEjB,OAAO,EAAE,uBAAuB;IAMnC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,IAAI,GAAG,IAAI;IAwB1D,KAAK,IAAI,IAAI;CAGvB;AAED,iGAAiG;AACjG,eAAO,MAAM,oBAAoB,2BAAqB,CAAC;AACvD,iGAAiG;AACjG,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,CAAC;AAEtD,mDAAmD;AACnD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,kBAAkB,CAErF"}
@@ -0,0 +1,57 @@
1
+ import Transport from 'winston-transport';
2
+ import { createLogShipper } from './shipper.js';
3
+ const WINSTON_RESERVED = new Set(['level', 'message', 'timestamp', 'traceId', 'spanId', 'requestId', 'service', 'env', 'host']);
4
+ /**
5
+ * Transport do winston:
6
+ *
7
+ * ```ts
8
+ * import winston from 'winston';
9
+ * import { FgTrackerTransport } from 'fg-tracker-sdk/winston';
10
+ * const logger = winston.createLogger({ transports: [new FgTrackerTransport({ apiKey, service: 'minha-api', tracker })] });
11
+ * ```
12
+ */
13
+ export class FgTrackerTransport extends Transport {
14
+ shipper;
15
+ constructor(options) {
16
+ const { level, silent, handleExceptions, handleRejections, ...shipperOptions } = options;
17
+ super({ level, silent, handleExceptions, handleRejections });
18
+ this.shipper = createLogShipper(shipperOptions);
19
+ }
20
+ log(info, next) {
21
+ setImmediate(() => this.emit('logged', info));
22
+ const context = {};
23
+ // Chaves-símbolo do logform (`Symbol.for('level')`, `Symbol.for('message')`) ficam de fora sozinhas.
24
+ for (const [key, value] of Object.entries(info)) {
25
+ if (WINSTON_RESERVED.has(key) || value === undefined)
26
+ continue;
27
+ context[key] = value;
28
+ }
29
+ const message = info.message;
30
+ this.shipper.push({
31
+ ts: typeof info.timestamp === 'string' || typeof info.timestamp === 'number' ? info.timestamp : undefined,
32
+ level: typeof info.level === 'string' ? info.level : undefined,
33
+ service: typeof info.service === 'string' ? info.service : undefined,
34
+ message: typeof message === 'string' ? message : JSON.stringify(message),
35
+ context,
36
+ traceId: asString(info.traceId),
37
+ spanId: asString(info.spanId),
38
+ requestId: asString(info.requestId),
39
+ env: asString(info.env),
40
+ host: asString(info.host),
41
+ });
42
+ next();
43
+ }
44
+ close() {
45
+ void this.shipper.shutdown();
46
+ }
47
+ }
48
+ /** @deprecated use `FgTrackerTransport` (nome antigo do `stread-track-sdk`; removido na 1.0). */
49
+ export const StreadTrackTransport = FgTrackerTransport;
50
+ /** Fábrica no estilo dos outros helpers do SDK. */
51
+ export function winstonTransport(options) {
52
+ return new FgTrackerTransport(options);
53
+ }
54
+ function asString(value) {
55
+ return typeof value === 'string' && value ? value : undefined;
56
+ }
57
+ //# sourceMappingURL=winston.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"winston.js","sourceRoot":"","sources":["../../src/logs/winston.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { TrackerCore } from './tracker.js';
2
+ import type { CheckInHandle, CheckInOptions } from './types.js';
3
+ export declare function sendCheckIn(core: TrackerCore, slug: string, body: Record<string, unknown>): Promise<boolean>;
4
+ export declare function createMonitor(core: TrackerCore, slug: string, options?: CheckInOptions): {
5
+ start(): Promise<CheckInHandle>;
6
+ };
7
+ export declare function runCheckIn<T>(core: TrackerCore, slug: string, fn: () => T | Promise<T>, options?: CheckInOptions): Promise<T>;
8
+ //# sourceMappingURL=monitors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitors.d.ts","sourceRoot":"","sources":["../src/monitors.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAqBhE,wBAAsB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CASlH;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG;IAAE,KAAK,IAAI,OAAO,CAAC,aAAa,CAAC,CAAA;CAAE,CAsBhI;AAED,wBAAsB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC,CAUvI"}
@@ -0,0 +1,69 @@
1
+ import { performance } from 'node:perf_hooks';
2
+ import { toSpanError } from './normalize.js';
3
+ /**
4
+ * Check-ins de jobs agendados (CONTRATO.md §18): `in_progress` ao começar,
5
+ * `ok`/`fail` ao terminar, com a duração. Sem apiKey vira no-op.
6
+ */
7
+ function payload(status, options, extra = {}) {
8
+ return {
9
+ status,
10
+ ...(options.name ? { name: options.name } : {}),
11
+ ...(options.intervalSeconds ? { intervalSeconds: options.intervalSeconds } : {}),
12
+ ...(options.graceSeconds !== undefined ? { graceSeconds: options.graceSeconds } : {}),
13
+ ...(options.schedule ? { schedule: options.schedule } : {}),
14
+ ...(options.cron ? { cron: options.cron } : {}),
15
+ ...(options.timezone ? { timezone: options.timezone } : {}),
16
+ ...(options.maxRuntimeSeconds !== undefined ? { maxRuntimeSeconds: options.maxRuntimeSeconds } : {}),
17
+ ...extra,
18
+ };
19
+ }
20
+ export async function sendCheckIn(core, slug, body) {
21
+ if (!core.enabled)
22
+ return false;
23
+ const res = await core.post(`/v1/monitors/${encodeURIComponent(slug)}/checkin`, body, 8000);
24
+ if (!res)
25
+ return false;
26
+ if (!res.ok) {
27
+ core.warnOnce(`check-in do monitor "${slug}" respondeu ${res.status}`);
28
+ return false;
29
+ }
30
+ return true;
31
+ }
32
+ export function createMonitor(core, slug, options = {}) {
33
+ return {
34
+ async start() {
35
+ const startedAt = performance.now();
36
+ await sendCheckIn(core, slug, payload('in_progress', options));
37
+ let closed = false;
38
+ const durationMs = () => Math.round((performance.now() - startedAt) * 10) / 10;
39
+ return {
40
+ async ok() {
41
+ if (closed)
42
+ return;
43
+ closed = true;
44
+ await sendCheckIn(core, slug, payload('ok', options, { durationMs: durationMs() }));
45
+ },
46
+ async fail(error) {
47
+ if (closed)
48
+ return;
49
+ closed = true;
50
+ const message = error === undefined ? 'Job reportou falha' : toSpanError(error).message;
51
+ await sendCheckIn(core, slug, payload('fail', options, { durationMs: durationMs(), error: message.slice(0, 2000) }));
52
+ },
53
+ };
54
+ },
55
+ };
56
+ }
57
+ export async function runCheckIn(core, slug, fn, options = {}) {
58
+ const handle = await createMonitor(core, slug, options).start();
59
+ try {
60
+ const result = await fn();
61
+ await handle.ok();
62
+ return result;
63
+ }
64
+ catch (error) {
65
+ await handle.fail(error);
66
+ throw error;
67
+ }
68
+ }
69
+ //# sourceMappingURL=monitors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitors.js","sourceRoot":"","sources":["../src/monitors.ts"],"names":[],"mappings":"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"}
package/dist/next.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import type { TrackerCore } from './tracker.js';
2
+ import type { NextRouteHandler } from './types.js';
3
+ /**
4
+ * Envolve um route handler do App Router (`export const GET = tracker.wrapNextRoute(...)`)
5
+ * num span raiz `http.server`. Status vem da `Response`; exceções viram `error`.
6
+ * Continua o trace de um `traceparent` recebido (CONTRATO.md §16).
7
+ */
8
+ export declare function wrapNextRouteHandler<TCtx>(core: TrackerCore, handler: NextRouteHandler<TCtx>): NextRouteHandler<TCtx>;
9
+ //# sourceMappingURL=next.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next.d.ts","sourceRoot":"","sources":["../src/next.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAwCrH"}
package/dist/next.js ADDED
@@ -0,0 +1,55 @@
1
+ import { parseTraceparent } from './context.js';
2
+ import { normalizePath } from './normalize.js';
3
+ /**
4
+ * Envolve um route handler do App Router (`export const GET = tracker.wrapNextRoute(...)`)
5
+ * num span raiz `http.server`. Status vem da `Response`; exceções viram `error`.
6
+ * Continua o trace de um `traceparent` recebido (CONTRATO.md §16).
7
+ */
8
+ export function wrapNextRouteHandler(core, handler) {
9
+ return async function fgTrackerRoute(req, ctx) {
10
+ if (!core.enabled)
11
+ return handler(req, ctx);
12
+ const method = (req.method ?? 'GET').toUpperCase();
13
+ let pathname = '/';
14
+ let rawUrl = req.url;
15
+ try {
16
+ const u = new URL(req.url);
17
+ pathname = u.pathname;
18
+ rawUrl = u.pathname + u.search;
19
+ }
20
+ catch {
21
+ /* URL relativa ou inválida: usa como está */
22
+ }
23
+ const route = normalizePath(pathname);
24
+ const requestId = req.headers.get('x-request-id');
25
+ const attributes = {
26
+ url: rawUrl,
27
+ userAgent: req.headers.get('user-agent'),
28
+ ip: req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ?? null,
29
+ ...(requestId ? { requestId } : {}),
30
+ };
31
+ const remote = parseTraceparent(req.headers.get('traceparent'));
32
+ const span = remote
33
+ ? core.startRemoteRoot('http.server', `${method} ${route}`, attributes, remote)
34
+ : core.startSpan('http.server', `${method} ${route}`, attributes, null);
35
+ span.method = method;
36
+ span.route = route;
37
+ try {
38
+ const res = await core.runInSpan(span, () => handler(req, ctx));
39
+ span.statusCode = res.status;
40
+ if (res.status >= 500)
41
+ span.error = { name: 'HttpError', message: `HTTP ${res.status}` };
42
+ return res;
43
+ }
44
+ catch (err) {
45
+ span.setError(err);
46
+ if (span.statusCode === null)
47
+ span.statusCode = 500;
48
+ throw err;
49
+ }
50
+ finally {
51
+ span.end();
52
+ }
53
+ };
54
+ }
55
+ //# sourceMappingURL=next.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next.js","sourceRoot":"","sources":["../src/next.ts"],"names":[],"mappings":"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"}