vedatrace 0.1.8 → 0.2.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/README.md +25 -5
- package/dist/index.cjs +310 -61
- package/dist/index.d.cts +126 -49
- package/dist/index.d.mts +126 -49
- package/dist/index.mjs +305 -63
- package/dist/integrations/express.d.cts +1 -1
- package/dist/integrations/express.d.mts +1 -1
- package/dist/integrations/nextjs.d.cts +1 -1
- package/dist/integrations/nextjs.d.mts +1 -1
- package/dist/integrations/react.cjs +1 -2
- package/dist/integrations/react.d.cts +1 -1
- package/dist/integrations/react.d.mts +1 -1
- package/dist/integrations/react.mjs +1 -2
- package/dist/transports/index.cjs +26 -1
- package/dist/transports/index.d.cts +23 -6
- package/dist/transports/index.d.mts +23 -6
- package/dist/transports/index.mjs +26 -2
- package/dist/{types-CcdFb-vY.d.cts → types-BU0UESs9.d.cts} +25 -41
- package/dist/{types-CcdFb-vY.d.mts → types-BU0UESs9.d.mts} +25 -41
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,26 +1,60 @@
|
|
|
1
|
-
import { VedaTraceHttpTransport, VedaTraceConsoleTransport } from './transports/index.mjs';
|
|
1
|
+
import { VedaTraceHttpTransportBrowser, VedaTraceHttpTransport, VedaTraceConsoleTransport } from './transports/index.mjs';
|
|
2
2
|
|
|
3
3
|
class VedaTraceBatcher {
|
|
4
|
-
constructor(transports, config,
|
|
4
|
+
constructor(transports, config, immediateFlush = false) {
|
|
5
5
|
this.transports = transports;
|
|
6
6
|
this.config = config;
|
|
7
|
-
this.onError = onError;
|
|
8
|
-
this.onSuccess = onSuccess;
|
|
9
7
|
this.immediateFlush = immediateFlush;
|
|
10
|
-
this.
|
|
8
|
+
this.context = config.executionContext;
|
|
11
9
|
}
|
|
12
10
|
queue = [];
|
|
13
11
|
flushTimer = null;
|
|
12
|
+
flushDebounceTimer = null;
|
|
14
13
|
isFlushing = false;
|
|
15
14
|
pendingFlush = null;
|
|
16
|
-
|
|
15
|
+
context;
|
|
16
|
+
/** Attach execution context after initialization */
|
|
17
|
+
setContext(ctx) {
|
|
18
|
+
this.context = ctx;
|
|
19
|
+
}
|
|
20
|
+
/** Get current context */
|
|
21
|
+
getContext() {
|
|
22
|
+
return this.context;
|
|
23
|
+
}
|
|
24
|
+
/** Add log to queue with context-aware flush */
|
|
17
25
|
add(log) {
|
|
18
26
|
this.queue.push(log);
|
|
19
|
-
if (this.
|
|
27
|
+
if (!this.flushTimer && !this.immediateFlush) {
|
|
28
|
+
this.startFlushTimer();
|
|
29
|
+
}
|
|
30
|
+
if (this.immediateFlush || this.context) {
|
|
31
|
+
this.debouncedFlush();
|
|
32
|
+
} else if (this.queue.length >= this.config.batchSize) {
|
|
20
33
|
this.flush();
|
|
21
34
|
}
|
|
22
35
|
}
|
|
23
|
-
/**
|
|
36
|
+
/** Debounced flush - prevents rapid-fire flushes */
|
|
37
|
+
debouncedFlush() {
|
|
38
|
+
if (this.flushDebounceTimer) {
|
|
39
|
+
clearTimeout(this.flushDebounceTimer);
|
|
40
|
+
}
|
|
41
|
+
this.flushDebounceTimer = setTimeout(() => {
|
|
42
|
+
this.flushDebounceTimer = null;
|
|
43
|
+
this.flush().catch((error) => {
|
|
44
|
+
if (this.config.onError) {
|
|
45
|
+
this.config.onError(
|
|
46
|
+
error instanceof Error ? error : new Error(String(error))
|
|
47
|
+
);
|
|
48
|
+
} else {
|
|
49
|
+
console.error(
|
|
50
|
+
"[VedaTrace] Debounced flush error:",
|
|
51
|
+
error instanceof Error ? error.message : String(error)
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}, 100);
|
|
56
|
+
}
|
|
57
|
+
/** Flush logs to all transports with waitUntil protection */
|
|
24
58
|
async flush() {
|
|
25
59
|
if (this.isFlushing) {
|
|
26
60
|
return this.pendingFlush ?? Promise.resolve();
|
|
@@ -31,13 +65,16 @@ class VedaTraceBatcher {
|
|
|
31
65
|
this.isFlushing = true;
|
|
32
66
|
const logsToSend = [...this.queue];
|
|
33
67
|
this.queue = [];
|
|
34
|
-
|
|
68
|
+
const flushPromise = this.sendWithRetry(logsToSend).finally(() => {
|
|
35
69
|
this.isFlushing = false;
|
|
36
70
|
this.pendingFlush = null;
|
|
37
71
|
});
|
|
38
|
-
|
|
72
|
+
this.pendingFlush = flushPromise;
|
|
73
|
+
if (this.context) {
|
|
74
|
+
this.context.waitUntil(flushPromise);
|
|
75
|
+
}
|
|
76
|
+
return flushPromise;
|
|
39
77
|
}
|
|
40
|
-
/** Send logs with retry logic */
|
|
41
78
|
async sendWithRetry(logs, attempt = 0) {
|
|
42
79
|
const errors = [];
|
|
43
80
|
for (const transport of this.transports) {
|
|
@@ -55,16 +92,17 @@ class VedaTraceBatcher {
|
|
|
55
92
|
const combinedError = new Error(
|
|
56
93
|
`Failed to send logs after ${this.config.maxRetries} retries: ${errors.map((e) => e.message).join(", ")}`
|
|
57
94
|
);
|
|
58
|
-
if (this.onError) {
|
|
59
|
-
this.onError(combinedError);
|
|
95
|
+
if (this.config.onError) {
|
|
96
|
+
this.config.onError(combinedError);
|
|
60
97
|
} else {
|
|
61
98
|
console.error("[VedaTrace]", combinedError.message);
|
|
62
99
|
}
|
|
63
100
|
return;
|
|
64
101
|
}
|
|
65
|
-
this.onSuccess
|
|
102
|
+
if (this.config.onSuccess) {
|
|
103
|
+
this.config.onSuccess();
|
|
104
|
+
}
|
|
66
105
|
}
|
|
67
|
-
/** Start the flush interval timer */
|
|
68
106
|
startFlushTimer() {
|
|
69
107
|
if (this.flushTimer) {
|
|
70
108
|
clearInterval(this.flushTimer);
|
|
@@ -72,8 +110,8 @@ class VedaTraceBatcher {
|
|
|
72
110
|
this.flushTimer = setInterval(() => {
|
|
73
111
|
if (this.queue.length > 0) {
|
|
74
112
|
this.flush().catch((error) => {
|
|
75
|
-
if (this.onError) {
|
|
76
|
-
this.onError(
|
|
113
|
+
if (this.config.onError) {
|
|
114
|
+
this.config.onError(
|
|
77
115
|
error instanceof Error ? error : new Error(String(error))
|
|
78
116
|
);
|
|
79
117
|
} else {
|
|
@@ -89,30 +127,84 @@ class VedaTraceBatcher {
|
|
|
89
127
|
this.flushTimer.unref();
|
|
90
128
|
}
|
|
91
129
|
}
|
|
92
|
-
/** Stop the flush timer */
|
|
93
130
|
stop() {
|
|
94
131
|
if (this.flushTimer) {
|
|
95
132
|
clearInterval(this.flushTimer);
|
|
96
133
|
this.flushTimer = null;
|
|
97
134
|
}
|
|
135
|
+
if (this.flushDebounceTimer) {
|
|
136
|
+
clearTimeout(this.flushDebounceTimer);
|
|
137
|
+
this.flushDebounceTimer = null;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
start() {
|
|
141
|
+
if (!this.flushTimer && !this.immediateFlush) {
|
|
142
|
+
this.startFlushTimer();
|
|
143
|
+
}
|
|
98
144
|
}
|
|
99
|
-
/** Delay helper */
|
|
100
145
|
delay(ms) {
|
|
101
146
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
102
147
|
}
|
|
103
|
-
/** Get current queue size */
|
|
104
148
|
getQueueSize() {
|
|
105
149
|
return this.queue.length;
|
|
106
150
|
}
|
|
151
|
+
setExecutionContext(ctx) {
|
|
152
|
+
this.context = ctx;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function detectRuntime() {
|
|
157
|
+
if (typeof navigator !== "undefined" && navigator.userAgent === "Cloudflare-Workers") {
|
|
158
|
+
return "cloudflare";
|
|
159
|
+
}
|
|
160
|
+
const g = globalThis;
|
|
161
|
+
if (g?.Deno && g.Deno.version?.deno) {
|
|
162
|
+
return "deno";
|
|
163
|
+
}
|
|
164
|
+
if (g?.Bun) {
|
|
165
|
+
return "bun";
|
|
166
|
+
}
|
|
167
|
+
if (typeof g?.WebSocketPair !== "undefined") {
|
|
168
|
+
return "cloudflare";
|
|
169
|
+
}
|
|
170
|
+
if (typeof process !== "undefined" && process.versions?.node) {
|
|
171
|
+
return "node";
|
|
172
|
+
}
|
|
173
|
+
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
174
|
+
return "browser";
|
|
175
|
+
}
|
|
176
|
+
if (typeof fetch !== "undefined" && typeof window === "undefined" && typeof process === "undefined") {
|
|
177
|
+
return "edge";
|
|
178
|
+
}
|
|
179
|
+
return "edge";
|
|
180
|
+
}
|
|
181
|
+
function isEdgeRuntime() {
|
|
182
|
+
const runtime = detectRuntime();
|
|
183
|
+
return runtime === "cloudflare" || runtime === "deno" || runtime === "bun" || runtime === "edge";
|
|
184
|
+
}
|
|
185
|
+
function isServerless() {
|
|
186
|
+
const runtime = detectRuntime();
|
|
187
|
+
return runtime === "cloudflare" || runtime === "edge";
|
|
188
|
+
}
|
|
189
|
+
function isLongRunning() {
|
|
190
|
+
const runtime = detectRuntime();
|
|
191
|
+
return runtime === "node" || runtime === "bun" || runtime === "deno";
|
|
192
|
+
}
|
|
193
|
+
function isBrowser() {
|
|
194
|
+
return detectRuntime() === "browser";
|
|
107
195
|
}
|
|
108
196
|
|
|
109
|
-
const SDK_VERSION = "
|
|
197
|
+
const SDK_VERSION = process.env.npm_package_version ?? "0.0.0";
|
|
110
198
|
class VedaTraceLogger {
|
|
111
199
|
batcher = null;
|
|
200
|
+
runtime;
|
|
112
201
|
config;
|
|
113
202
|
childDefaults;
|
|
203
|
+
_context;
|
|
114
204
|
constructor(config = {}, childDefaults = {}) {
|
|
205
|
+
this.runtime = config.runtime ?? detectRuntime();
|
|
115
206
|
this.childDefaults = childDefaults;
|
|
207
|
+
this._context = config.executionContext;
|
|
116
208
|
this.config = {
|
|
117
209
|
service: config.service,
|
|
118
210
|
apiKey: config.apiKey,
|
|
@@ -122,61 +214,68 @@ class VedaTraceLogger {
|
|
|
122
214
|
flushInterval: config.flushInterval ?? 5e3,
|
|
123
215
|
maxRetries: config.maxRetries ?? 3,
|
|
124
216
|
retryDelay: config.retryDelay ?? 1e3,
|
|
125
|
-
onError: config.onError,
|
|
126
|
-
onSuccess: config.onSuccess,
|
|
127
217
|
debug: config.debug ?? false,
|
|
128
218
|
immediateFlush: config.immediateFlush ?? false,
|
|
129
|
-
unrefTimer: config.unrefTimer
|
|
219
|
+
unrefTimer: config.unrefTimer ?? false
|
|
130
220
|
};
|
|
131
221
|
if (!config.disabled) {
|
|
132
222
|
this.initializeBatcher(config);
|
|
133
223
|
}
|
|
134
224
|
}
|
|
135
|
-
/** Initialize the batcher with transports */
|
|
136
225
|
initializeBatcher(config) {
|
|
137
226
|
const transports = config.transports ?? [];
|
|
138
|
-
if (config.apiKey && transports.length === 0) ;
|
|
139
227
|
if (transports.length > 0) {
|
|
228
|
+
const batcherConfig = {
|
|
229
|
+
batchSize: this.config.batchSize,
|
|
230
|
+
flushInterval: this.config.flushInterval,
|
|
231
|
+
maxRetries: this.config.maxRetries,
|
|
232
|
+
retryDelay: this.config.retryDelay,
|
|
233
|
+
unrefTimer: this.config.unrefTimer,
|
|
234
|
+
executionContext: this._context,
|
|
235
|
+
onError: config.onError,
|
|
236
|
+
onSuccess: config.onSuccess
|
|
237
|
+
};
|
|
140
238
|
this.batcher = new VedaTraceBatcher(
|
|
141
239
|
transports,
|
|
142
|
-
|
|
143
|
-
batchSize: this.config.batchSize,
|
|
144
|
-
flushInterval: this.config.flushInterval,
|
|
145
|
-
maxRetries: this.config.maxRetries,
|
|
146
|
-
retryDelay: this.config.retryDelay,
|
|
147
|
-
unrefTimer: this.config.unrefTimer
|
|
148
|
-
},
|
|
149
|
-
this.config.onError,
|
|
150
|
-
this.config.onSuccess,
|
|
240
|
+
batcherConfig,
|
|
151
241
|
this.config.immediateFlush
|
|
152
242
|
);
|
|
153
243
|
}
|
|
154
244
|
}
|
|
155
|
-
/** Set batcher (called from factory function) */
|
|
156
245
|
setBatcher(batcher) {
|
|
157
246
|
this.batcher = batcher;
|
|
158
247
|
}
|
|
159
|
-
/**
|
|
248
|
+
/** Attach execution context for waitUntil support (Cloudflare Workers / Pages) */
|
|
249
|
+
withContext(ctx) {
|
|
250
|
+
this._context = ctx;
|
|
251
|
+
if (this.batcher) {
|
|
252
|
+
this.batcher.setContext(ctx);
|
|
253
|
+
}
|
|
254
|
+
return this;
|
|
255
|
+
}
|
|
256
|
+
/** Check if context is attached */
|
|
257
|
+
hasContext() {
|
|
258
|
+
return this._context !== void 0;
|
|
259
|
+
}
|
|
260
|
+
/** Get current execution context */
|
|
261
|
+
getContext() {
|
|
262
|
+
return this._context;
|
|
263
|
+
}
|
|
160
264
|
debug(message, metadata) {
|
|
161
265
|
this.log("debug", message, metadata);
|
|
162
266
|
}
|
|
163
|
-
/** Log at info level */
|
|
164
267
|
info(message, metadata) {
|
|
165
268
|
this.log("info", message, metadata);
|
|
166
269
|
}
|
|
167
|
-
/** Log at warn level */
|
|
168
270
|
warn(message, metadata) {
|
|
169
271
|
this.log("warn", message, metadata);
|
|
170
272
|
}
|
|
171
|
-
/** Log at error level */
|
|
172
273
|
error(message, metadata) {
|
|
173
274
|
this.log("error", message, metadata);
|
|
174
275
|
}
|
|
175
|
-
/** Log at fatal level */
|
|
176
276
|
fatal(message, metadata) {
|
|
177
277
|
this.log("fatal", message, metadata);
|
|
178
278
|
}
|
|
179
|
-
/** Internal log method */
|
|
180
279
|
log(level, message, metadata) {
|
|
181
280
|
if (!this.batcher) {
|
|
182
281
|
return;
|
|
@@ -191,7 +290,7 @@ class VedaTraceLogger {
|
|
|
191
290
|
timestamp: Date.now(),
|
|
192
291
|
metadata: cleanMetadata,
|
|
193
292
|
_sdk: {
|
|
194
|
-
source:
|
|
293
|
+
source: detectRuntime(),
|
|
195
294
|
version: SDK_VERSION
|
|
196
295
|
}
|
|
197
296
|
};
|
|
@@ -204,7 +303,6 @@ class VedaTraceLogger {
|
|
|
204
303
|
}
|
|
205
304
|
this.batcher.add(logEntry);
|
|
206
305
|
}
|
|
207
|
-
/** Create a child logger with default metadata */
|
|
208
306
|
child(defaults) {
|
|
209
307
|
const mergedDefaults = { ...this.childDefaults, ...defaults };
|
|
210
308
|
const childLogger = new VedaTraceLogger(
|
|
@@ -213,7 +311,8 @@ class VedaTraceLogger {
|
|
|
213
311
|
apiKey: this.config.apiKey,
|
|
214
312
|
endpoint: this.config.endpoint,
|
|
215
313
|
environment: this.config.environment,
|
|
216
|
-
disabled: !this.batcher
|
|
314
|
+
disabled: !this.batcher,
|
|
315
|
+
executionContext: this._context
|
|
217
316
|
},
|
|
218
317
|
mergedDefaults
|
|
219
318
|
);
|
|
@@ -222,27 +321,132 @@ class VedaTraceLogger {
|
|
|
222
321
|
}
|
|
223
322
|
return childLogger;
|
|
224
323
|
}
|
|
225
|
-
/** Flush pending logs */
|
|
226
324
|
async flush() {
|
|
227
325
|
if (this.batcher) {
|
|
228
|
-
|
|
326
|
+
const flushPromise = this.batcher.flush();
|
|
327
|
+
if (this._context) {
|
|
328
|
+
this._context.waitUntil(flushPromise);
|
|
329
|
+
}
|
|
330
|
+
return flushPromise;
|
|
229
331
|
}
|
|
230
332
|
}
|
|
231
|
-
/** Stop the batcher and flush timer */
|
|
232
333
|
stop() {
|
|
233
334
|
if (this.batcher) {
|
|
234
335
|
this.batcher.stop();
|
|
235
336
|
}
|
|
236
337
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
return "browser";
|
|
338
|
+
start() {
|
|
339
|
+
if (this.batcher) {
|
|
340
|
+
this.batcher.start();
|
|
241
341
|
}
|
|
242
|
-
|
|
243
|
-
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
class BrowserLifecycle {
|
|
346
|
+
constructor(config) {
|
|
347
|
+
this.config = config;
|
|
348
|
+
this.boundVisibilityHandler = this.handleVisibilityChange.bind(this);
|
|
349
|
+
this.boundPageHideHandler = this.handlePageHide.bind(this);
|
|
350
|
+
this.boundBeforeUnloadHandler = this.handleBeforeUnload.bind(this);
|
|
351
|
+
this.boundUnloadHandler = this.handleUnload.bind(this);
|
|
352
|
+
}
|
|
353
|
+
boundVisibilityHandler;
|
|
354
|
+
boundPageHideHandler;
|
|
355
|
+
boundBeforeUnloadHandler;
|
|
356
|
+
boundUnloadHandler;
|
|
357
|
+
isAttached = false;
|
|
358
|
+
pendingFlush = null;
|
|
359
|
+
/** Start listening for browser lifecycle events */
|
|
360
|
+
attach() {
|
|
361
|
+
if (this.isAttached) return;
|
|
362
|
+
if (typeof document !== "undefined") {
|
|
363
|
+
document.addEventListener("visibilitychange", this.boundVisibilityHandler);
|
|
364
|
+
window.addEventListener("pagehide", this.boundPageHideHandler);
|
|
365
|
+
window.addEventListener("beforeunload", this.boundBeforeUnloadHandler);
|
|
366
|
+
window.addEventListener("unload", this.boundUnloadHandler);
|
|
367
|
+
}
|
|
368
|
+
this.isAttached = true;
|
|
369
|
+
if (this.config.debug) {
|
|
370
|
+
console.log("[VedaTrace] Browser lifecycle handlers attached");
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
/** Stop listening for browser lifecycle events */
|
|
374
|
+
detach() {
|
|
375
|
+
if (!this.isAttached) return;
|
|
376
|
+
if (typeof document !== "undefined") {
|
|
377
|
+
document.removeEventListener(
|
|
378
|
+
"visibilitychange",
|
|
379
|
+
this.boundVisibilityHandler
|
|
380
|
+
);
|
|
381
|
+
window.removeEventListener("pagehide", this.boundPageHideHandler);
|
|
382
|
+
window.removeEventListener("beforeunload", this.boundBeforeUnloadHandler);
|
|
383
|
+
window.removeEventListener("unload", this.boundUnloadHandler);
|
|
384
|
+
}
|
|
385
|
+
this.isAttached = false;
|
|
386
|
+
if (this.config.debug) {
|
|
387
|
+
console.log("[VedaTrace] Browser lifecycle handlers detached");
|
|
244
388
|
}
|
|
245
|
-
|
|
389
|
+
}
|
|
390
|
+
/** Handle visibility change - flush when page becomes hidden */
|
|
391
|
+
handleVisibilityChange() {
|
|
392
|
+
if (document.visibilityState === "hidden") {
|
|
393
|
+
if (this.config.debug) {
|
|
394
|
+
console.log("[VedaTrace] Page became hidden, flushing logs");
|
|
395
|
+
}
|
|
396
|
+
this.scheduleFlush();
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
/** Handle pagehide event - primary flush handler for Safari */
|
|
400
|
+
handlePageHide(event) {
|
|
401
|
+
if (this.config.debug) {
|
|
402
|
+
console.log(
|
|
403
|
+
"[VedaTrace] Page hide event",
|
|
404
|
+
event.persisted ? "(cached)" : "(navigation)"
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
if (event.persisted) {
|
|
408
|
+
this.scheduleFlush();
|
|
409
|
+
} else {
|
|
410
|
+
this.finalFlush();
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
/** Handle beforeunload - backup flush mechanism */
|
|
414
|
+
handleBeforeUnload(event) {
|
|
415
|
+
if (this.config.debug) {
|
|
416
|
+
console.log("[VedaTrace] Before unload event");
|
|
417
|
+
}
|
|
418
|
+
this.finalFlush();
|
|
419
|
+
}
|
|
420
|
+
/** Handle unload - fallback for older browsers */
|
|
421
|
+
handleUnload() {
|
|
422
|
+
if (this.config.debug) {
|
|
423
|
+
console.log("[VedaTrace] Unload event");
|
|
424
|
+
}
|
|
425
|
+
this.finalFlush();
|
|
426
|
+
}
|
|
427
|
+
/** Schedule a debounced flush (for visibility change) */
|
|
428
|
+
scheduleFlush() {
|
|
429
|
+
if (this.pendingFlush) return;
|
|
430
|
+
this.pendingFlush = this.config.flush().finally(() => {
|
|
431
|
+
this.pendingFlush = null;
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Final flush using keepalive fetch
|
|
436
|
+
* For sending logs after the page context is destroyed
|
|
437
|
+
*/
|
|
438
|
+
finalFlush() {
|
|
439
|
+
for (const transport of this.config.transports) {
|
|
440
|
+
if (transport.name === "http" && "flush" in transport) {
|
|
441
|
+
transport.flush?.();
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
this.config.flush().catch(() => {
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
/** Check if handlers are attached */
|
|
448
|
+
isActive() {
|
|
449
|
+
return this.isAttached;
|
|
246
450
|
}
|
|
247
451
|
}
|
|
248
452
|
|
|
@@ -320,26 +524,55 @@ function redactPii(value, mask) {
|
|
|
320
524
|
return result;
|
|
321
525
|
}
|
|
322
526
|
|
|
527
|
+
const RUNTIME_FLUSH_INTERVALS = {
|
|
528
|
+
node: 3e3,
|
|
529
|
+
bun: 3e3,
|
|
530
|
+
deno: 3e3,
|
|
531
|
+
browser: 3e3,
|
|
532
|
+
cloudflare: 1e3,
|
|
533
|
+
edge: 1e3
|
|
534
|
+
};
|
|
323
535
|
function vedatrace(config = {}) {
|
|
536
|
+
const runtime = detectRuntime();
|
|
324
537
|
const logger = new VedaTraceLogger(config);
|
|
325
538
|
if (config.apiKey && (!config.transports || config.transports.length === 0)) {
|
|
326
|
-
const
|
|
539
|
+
const isBrowserEnv = isBrowser();
|
|
540
|
+
const isServerlessEnv = isServerless();
|
|
541
|
+
const isLongRunningEnv = isLongRunning();
|
|
542
|
+
const HttpTransport = isBrowserEnv ? VedaTraceHttpTransportBrowser : VedaTraceHttpTransport;
|
|
543
|
+
const httpConfig = {
|
|
544
|
+
apiKey: config.apiKey,
|
|
545
|
+
keepalive: isBrowserEnv
|
|
546
|
+
};
|
|
327
547
|
if (config.endpoint) httpConfig.endpoint = config.endpoint;
|
|
328
|
-
const httpTransport = new
|
|
548
|
+
const httpTransport = new HttpTransport(httpConfig);
|
|
549
|
+
let immediateFlush = config.immediateFlush ?? false;
|
|
550
|
+
let shouldUnrefTimer = false;
|
|
551
|
+
if (isServerlessEnv) {
|
|
552
|
+
immediateFlush = config.immediateFlush ?? !config.executionContext;
|
|
553
|
+
} else if (isLongRunningEnv) {
|
|
554
|
+
immediateFlush = config.immediateFlush ?? false;
|
|
555
|
+
shouldUnrefTimer = true;
|
|
556
|
+
} else if (isBrowserEnv) {
|
|
557
|
+
immediateFlush = config.immediateFlush ?? false;
|
|
558
|
+
}
|
|
559
|
+
const flushInterval = config.flushInterval ?? RUNTIME_FLUSH_INTERVALS[runtime] ?? 3e3;
|
|
329
560
|
const batcher = new VedaTraceBatcher(
|
|
330
561
|
[httpTransport],
|
|
331
562
|
{
|
|
332
563
|
batchSize: config.batchSize ?? 100,
|
|
333
|
-
flushInterval
|
|
564
|
+
flushInterval,
|
|
334
565
|
maxRetries: config.maxRetries ?? 3,
|
|
335
566
|
retryDelay: config.retryDelay ?? 1e3,
|
|
336
|
-
unrefTimer: config.unrefTimer
|
|
567
|
+
unrefTimer: config.unrefTimer ?? shouldUnrefTimer,
|
|
568
|
+
executionContext: config.executionContext,
|
|
569
|
+
onError: config.onError,
|
|
570
|
+
onSuccess: config.onSuccess
|
|
337
571
|
},
|
|
338
|
-
|
|
339
|
-
config.onSuccess
|
|
572
|
+
immediateFlush
|
|
340
573
|
);
|
|
341
574
|
logger.setBatcher(batcher);
|
|
342
|
-
if (typeof process !== "undefined") {
|
|
575
|
+
if (typeof process !== "undefined" && isLongRunningEnv) {
|
|
343
576
|
const flushLogs = async () => {
|
|
344
577
|
await batcher.flush();
|
|
345
578
|
};
|
|
@@ -347,6 +580,15 @@ function vedatrace(config = {}) {
|
|
|
347
580
|
process.on("SIGTERM", flushLogs);
|
|
348
581
|
process.on("SIGINT", flushLogs);
|
|
349
582
|
}
|
|
583
|
+
if (isBrowserEnv) {
|
|
584
|
+
const lifecycle = new BrowserLifecycle({
|
|
585
|
+
transports: [httpTransport],
|
|
586
|
+
flush: () => batcher.flush(),
|
|
587
|
+
debug: config.debug
|
|
588
|
+
});
|
|
589
|
+
lifecycle.attach();
|
|
590
|
+
logger._lifecycle = lifecycle;
|
|
591
|
+
}
|
|
350
592
|
}
|
|
351
593
|
return logger;
|
|
352
594
|
}
|
|
@@ -363,4 +605,4 @@ function devVedatrace(config = {}) {
|
|
|
363
605
|
});
|
|
364
606
|
}
|
|
365
607
|
|
|
366
|
-
export { VedaTraceBatcher, VedaTraceConsoleTransport, VedaTraceHttpTransport, VedaTraceLogger, vedatrace as default, devVedatrace, redact, vedatrace };
|
|
608
|
+
export { BrowserLifecycle, VedaTraceBatcher, VedaTraceConsoleTransport, VedaTraceHttpTransport, VedaTraceHttpTransportBrowser, VedaTraceLogger, vedatrace as default, detectRuntime, devVedatrace, isBrowser, isEdgeRuntime, isLongRunning, isServerless, redact, vedatrace };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Request, Response, NextFunction } from 'express';
|
|
2
|
-
import { V as VedaTraceLoggerInterface, a as VedaTraceConfig, L as LogMetadata } from '../types-
|
|
2
|
+
import { V as VedaTraceLoggerInterface, a as VedaTraceConfig, L as LogMetadata } from '../types-BU0UESs9.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Express.js middleware integration for VedaTrace
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Request, Response, NextFunction } from 'express';
|
|
2
|
-
import { V as VedaTraceLoggerInterface, a as VedaTraceConfig, L as LogMetadata } from '../types-
|
|
2
|
+
import { V as VedaTraceLoggerInterface, a as VedaTraceConfig, L as LogMetadata } from '../types-BU0UESs9.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Express.js middleware integration for VedaTrace
|
|
@@ -39,10 +39,9 @@ function useVedaTrace() {
|
|
|
39
39
|
function useVedaTraceChild(metadata) {
|
|
40
40
|
const parentLogger = useVedaTrace();
|
|
41
41
|
const metadataRef = react.useRef(metadata);
|
|
42
|
-
|
|
42
|
+
return react.useMemo(() => {
|
|
43
43
|
return parentLogger.child(metadataRef.current);
|
|
44
44
|
}, [parentLogger]);
|
|
45
|
-
return childLogger;
|
|
46
45
|
}
|
|
47
46
|
function useVedaTraceLifecycle(componentName, metadata) {
|
|
48
47
|
const logger = useVedaTrace();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode, ReactElement } from 'react';
|
|
2
|
-
import { a as VedaTraceConfig, V as VedaTraceLoggerInterface, L as LogMetadata } from '../types-
|
|
2
|
+
import { a as VedaTraceConfig, V as VedaTraceLoggerInterface, L as LogMetadata } from '../types-BU0UESs9.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* React integration for VedaTrace
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode, ReactElement } from 'react';
|
|
2
|
-
import { a as VedaTraceConfig, V as VedaTraceLoggerInterface, L as LogMetadata } from '../types-
|
|
2
|
+
import { a as VedaTraceConfig, V as VedaTraceLoggerInterface, L as LogMetadata } from '../types-BU0UESs9.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* React integration for VedaTrace
|
|
@@ -37,10 +37,9 @@ function useVedaTrace() {
|
|
|
37
37
|
function useVedaTraceChild(metadata) {
|
|
38
38
|
const parentLogger = useVedaTrace();
|
|
39
39
|
const metadataRef = useRef(metadata);
|
|
40
|
-
|
|
40
|
+
return useMemo(() => {
|
|
41
41
|
return parentLogger.child(metadataRef.current);
|
|
42
42
|
}, [parentLogger]);
|
|
43
|
-
return childLogger;
|
|
44
43
|
}
|
|
45
44
|
function useVedaTraceLifecycle(componentName, metadata) {
|
|
46
45
|
const logger = useVedaTrace();
|
|
@@ -82,11 +82,13 @@ class VedaTraceHttpTransport {
|
|
|
82
82
|
apiKey;
|
|
83
83
|
timeout;
|
|
84
84
|
headers;
|
|
85
|
+
keepalive;
|
|
85
86
|
constructor(config) {
|
|
86
87
|
this.apiKey = config.apiKey;
|
|
87
88
|
this.endpoint = config.endpoint ?? "https://ingest.vedatrace.dev/v1/logs";
|
|
88
89
|
this.timeout = config.timeout ?? 3e4;
|
|
89
90
|
this.headers = config.headers ?? {};
|
|
91
|
+
this.keepalive = config.keepalive ?? false;
|
|
90
92
|
}
|
|
91
93
|
/** Send logs via HTTP POST */
|
|
92
94
|
async send(logs) {
|
|
@@ -108,7 +110,8 @@ class VedaTraceHttpTransport {
|
|
|
108
110
|
...this.headers
|
|
109
111
|
},
|
|
110
112
|
body: JSON.stringify(payload),
|
|
111
|
-
signal: controller.signal
|
|
113
|
+
signal: controller.signal,
|
|
114
|
+
keepalive: this.keepalive
|
|
112
115
|
});
|
|
113
116
|
clearTimeout(timeoutId);
|
|
114
117
|
if (!response.ok) {
|
|
@@ -126,7 +129,29 @@ class VedaTraceHttpTransport {
|
|
|
126
129
|
throw new Error(String(error));
|
|
127
130
|
}
|
|
128
131
|
}
|
|
132
|
+
/** Flush pending logs - called on page unload */
|
|
133
|
+
async flush() {
|
|
134
|
+
return Promise.resolve();
|
|
135
|
+
}
|
|
136
|
+
/** Check if keepalive is enabled */
|
|
137
|
+
isKeepaliveEnabled() {
|
|
138
|
+
return this.keepalive;
|
|
139
|
+
}
|
|
140
|
+
/** Enable/disable keepalive */
|
|
141
|
+
setKeepalive(enabled) {
|
|
142
|
+
this.keepalive = enabled;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
class VedaTraceHttpTransportBrowser extends VedaTraceHttpTransport {
|
|
146
|
+
constructor(config) {
|
|
147
|
+
super({ ...config, keepalive: true });
|
|
148
|
+
}
|
|
149
|
+
async flush() {
|
|
150
|
+
this.setKeepalive(true);
|
|
151
|
+
return super.flush();
|
|
152
|
+
}
|
|
129
153
|
}
|
|
130
154
|
|
|
131
155
|
exports.VedaTraceConsoleTransport = VedaTraceConsoleTransport;
|
|
132
156
|
exports.VedaTraceHttpTransport = VedaTraceHttpTransport;
|
|
157
|
+
exports.VedaTraceHttpTransportBrowser = VedaTraceHttpTransportBrowser;
|