@deeptracer/core 0.6.2 → 0.6.3
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 +28 -7
- package/dist/{chunk-DHFWC5TL.js → chunk-W62R346F.js} +64 -22
- package/dist/index.cjs +65 -23
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/internal.cjs +64 -22
- package/dist/internal.d.cts +2 -70
- package/dist/internal.d.ts +2 -70
- package/dist/internal.js +1 -1
- package/dist/{logger-CzZg2_vM.d.cts → logger-DyJENLNA.d.cts} +97 -4
- package/dist/{logger-CzZg2_vM.d.ts → logger-DyJENLNA.d.ts} +97 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -90,7 +90,7 @@ const logger = createLogger({
|
|
|
90
90
|
|
|
91
91
|
// Optional
|
|
92
92
|
batchSize: 50, // Logs to buffer before sending (default: 50)
|
|
93
|
-
flushIntervalMs: 5000, // Max ms between flushes (default: 5000)
|
|
93
|
+
flushIntervalMs: 5000, // Max ms between flushes (default: 5000 — 200 in serverless environments, auto-detected via VERCEL or AWS_LAMBDA_FUNCTION_NAME)
|
|
94
94
|
debug: false, // Mirror logs to console (default: false)
|
|
95
95
|
})
|
|
96
96
|
```
|
|
@@ -104,7 +104,7 @@ const logger = createLogger({
|
|
|
104
104
|
| `service` | `string` | `"server"` | Service name (e.g., `"api"`, `"worker"`, `"web"`) |
|
|
105
105
|
| `environment` | `string` | `NODE_ENV` / `"production"` | Deployment environment |
|
|
106
106
|
| `batchSize` | `number` | `50` | Number of log entries to buffer before flushing |
|
|
107
|
-
| `flushIntervalMs` | `number` | `5000` | Milliseconds between automatic flushes |
|
|
107
|
+
| `flushIntervalMs` | `number` | `5000 (200 in serverless environments — auto-detected via VERCEL or AWS_LAMBDA_FUNCTION_NAME)` | Milliseconds between automatic flushes |
|
|
108
108
|
| `debug` | `boolean` | `false` | When `true`, all log calls also print to the console |
|
|
109
109
|
|
|
110
110
|
## API Reference
|
|
@@ -364,7 +364,7 @@ logger.llmUsage({
|
|
|
364
364
|
|
|
365
365
|
#### `forRequest(request)`
|
|
366
366
|
|
|
367
|
-
Create a request-scoped logger that extracts distributed trace context from incoming HTTP headers. The returned logger attaches `trace_id`, `span_id`, `request_id`, and `vercel_id` to all subsequent logs, errors, and spans.
|
|
367
|
+
Create a request-scoped logger that extracts distributed trace context from incoming HTTP headers. The returned logger attaches `trace_id`, `span_id`, `request_id`, and `vercel_id` to all subsequent logs, errors, and spans. Child loggers share the same transport as the root logger — logs from children are flushed together with the parent.
|
|
368
368
|
|
|
369
369
|
```ts
|
|
370
370
|
const reqLogger = logger.forRequest(request: Request): Logger
|
|
@@ -396,7 +396,7 @@ app.get("/api/users", async (c) => {
|
|
|
396
396
|
|
|
397
397
|
#### `withContext(name)`
|
|
398
398
|
|
|
399
|
-
Create a new logger that includes a context name in every log entry. Useful for distinguishing logs from different modules or subsystems.
|
|
399
|
+
Create a new logger that includes a context name in every log entry. Useful for distinguishing logs from different modules or subsystems. Child loggers share the same transport as the root logger — logs from children are flushed together with the parent.
|
|
400
400
|
|
|
401
401
|
```ts
|
|
402
402
|
const dbLogger = logger.withContext("database")
|
|
@@ -411,12 +411,12 @@ authLogger.info("Token refreshed") // context: "auth"
|
|
|
411
411
|
|
|
412
412
|
### Lifecycle
|
|
413
413
|
|
|
414
|
-
#### `flush()
|
|
414
|
+
#### `flush(): Promise<void>`
|
|
415
415
|
|
|
416
416
|
Immediately send all buffered log entries. Call this before your process exits or when you want to ensure logs are delivered.
|
|
417
417
|
|
|
418
418
|
```ts
|
|
419
|
-
logger.flush()
|
|
419
|
+
await logger.flush()
|
|
420
420
|
```
|
|
421
421
|
|
|
422
422
|
#### `destroy()`
|
|
@@ -430,6 +430,8 @@ process.on("SIGTERM", () => {
|
|
|
430
430
|
})
|
|
431
431
|
```
|
|
432
432
|
|
|
433
|
+
> **Note on child loggers:** Calling `destroy()` on a child logger (returned by `withContext()` or `forRequest()`) flushes the shared buffer and drains in-flight requests, but does **not** stop the root logger's batch timer. Only calling `destroy()` on the root logger stops the timer.
|
|
434
|
+
|
|
433
435
|
## Type Reference
|
|
434
436
|
|
|
435
437
|
### LoggerConfig
|
|
@@ -441,7 +443,7 @@ interface LoggerConfig {
|
|
|
441
443
|
endpoint: string
|
|
442
444
|
apiKey: string
|
|
443
445
|
batchSize?: number // default: 50
|
|
444
|
-
flushIntervalMs?: number // default: 5000
|
|
446
|
+
flushIntervalMs?: number // default: 5000 (200 in serverless environments — auto-detected via VERCEL or AWS_LAMBDA_FUNCTION_NAME)
|
|
445
447
|
debug?: boolean // default: false
|
|
446
448
|
}
|
|
447
449
|
```
|
|
@@ -571,6 +573,25 @@ Log entries are buffered and sent in batches to reduce network overhead:
|
|
|
571
573
|
|
|
572
574
|
Error reports (`captureError`) and span data (`startSpan`, `startInactiveSpan`) are **not batched** -- they are sent immediately.
|
|
573
575
|
|
|
576
|
+
### Serverless environments (Vercel, AWS Lambda)
|
|
577
|
+
|
|
578
|
+
In serverless functions, the execution context may freeze immediately after the HTTP response is sent, before the automatic flush timer fires. DeepTracer handles this in two ways:
|
|
579
|
+
|
|
580
|
+
- **Auto-detected interval**: When `VERCEL` or `AWS_LAMBDA_FUNCTION_NAME` is set, the default `flushIntervalMs` drops to 200ms.
|
|
581
|
+
- **Explicit flush**: Call `await logger.flush()` before returning a response to guarantee delivery.
|
|
582
|
+
|
|
583
|
+
For third-party route handlers you can't wrap (e.g. Auth.js, Stripe webhooks), use Vercel's `waitUntil` to extend the function lifetime:
|
|
584
|
+
|
|
585
|
+
```ts
|
|
586
|
+
import { waitUntil } from "@vercel/functions"
|
|
587
|
+
|
|
588
|
+
export const POST = async (req: Request) => {
|
|
589
|
+
const response = await thirdPartyHandler(req)
|
|
590
|
+
waitUntil(logger.flush()) // extends function lifetime, non-blocking
|
|
591
|
+
return response
|
|
592
|
+
}
|
|
593
|
+
```
|
|
594
|
+
|
|
574
595
|
## Transport
|
|
575
596
|
|
|
576
597
|
The transport layer sends data to four DeepTracer ingestion endpoints:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/version.ts
|
|
2
|
-
var SDK_VERSION = "0.6.
|
|
2
|
+
var SDK_VERSION = "0.6.3";
|
|
3
3
|
var SDK_NAME = "core";
|
|
4
4
|
|
|
5
5
|
// src/transport.ts
|
|
@@ -172,7 +172,8 @@ var Batcher = class {
|
|
|
172
172
|
constructor(config, onFlush) {
|
|
173
173
|
this.onFlush = onFlush;
|
|
174
174
|
this.batchSize = config.batchSize ?? 50;
|
|
175
|
-
|
|
175
|
+
const isServerless = typeof process !== "undefined" && !!(process.env.VERCEL || process.env.AWS_LAMBDA_FUNCTION_NAME);
|
|
176
|
+
this.flushIntervalMs = config.flushIntervalMs ?? (isServerless ? 200 : 5e3);
|
|
176
177
|
this.startTimer();
|
|
177
178
|
}
|
|
178
179
|
buffer = [];
|
|
@@ -265,30 +266,34 @@ var _originalConsole = {
|
|
|
265
266
|
var Logger = class _Logger {
|
|
266
267
|
batcher;
|
|
267
268
|
transport;
|
|
269
|
+
isRoot;
|
|
268
270
|
effectiveLevel;
|
|
269
271
|
contextName;
|
|
270
272
|
config;
|
|
271
273
|
state;
|
|
272
274
|
requestMeta;
|
|
273
|
-
constructor(config, contextName, requestMeta, state) {
|
|
275
|
+
constructor(config, contextName, requestMeta, state, sharedBatcher, sharedTransport) {
|
|
274
276
|
this.config = config;
|
|
275
277
|
this.contextName = contextName;
|
|
276
278
|
this.requestMeta = requestMeta;
|
|
277
279
|
this.state = state ?? createLoggerState(config.maxBreadcrumbs ?? 20);
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
280
|
+
this.isRoot = !sharedBatcher;
|
|
281
|
+
if (this.isRoot) {
|
|
282
|
+
const hasKey = !!config.apiKey;
|
|
283
|
+
const hasEndpoint = !!config.endpoint;
|
|
284
|
+
if (!hasKey && !hasEndpoint) {
|
|
285
|
+
_originalConsole.warn(
|
|
286
|
+
"[@deeptracer/core] No API key or endpoint configured. Running in local-only mode (logging methods work, but events are not sent). Set DEEPTRACER_KEY and DEEPTRACER_ENDPOINT to enable."
|
|
287
|
+
);
|
|
288
|
+
} else if (!hasKey) {
|
|
289
|
+
_originalConsole.warn("[@deeptracer/core] No `apiKey` provided. Events will not be sent.");
|
|
290
|
+
} else if (!hasEndpoint) {
|
|
291
|
+
_originalConsole.warn("[@deeptracer/core] No `endpoint` provided. Events will not be sent.");
|
|
292
|
+
}
|
|
288
293
|
}
|
|
289
294
|
this.effectiveLevel = LOG_LEVEL_VALUES[config.level ?? (config.environment === "production" ? "info" : "debug")];
|
|
290
|
-
this.transport = new Transport(config);
|
|
291
|
-
this.batcher = new Batcher(
|
|
295
|
+
this.transport = sharedTransport ?? new Transport(config);
|
|
296
|
+
this.batcher = sharedBatcher ?? new Batcher(
|
|
292
297
|
{ batchSize: config.batchSize, flushIntervalMs: config.flushIntervalMs },
|
|
293
298
|
(entries) => {
|
|
294
299
|
this.transport.sendLogs(entries);
|
|
@@ -476,7 +481,14 @@ var Logger = class _Logger {
|
|
|
476
481
|
// ---------------------------------------------------------------------------
|
|
477
482
|
/** Create a context-scoped logger. All logs include the context name. Gets an independent copy of state. */
|
|
478
483
|
withContext(name) {
|
|
479
|
-
return new _Logger(
|
|
484
|
+
return new _Logger(
|
|
485
|
+
this.config,
|
|
486
|
+
name,
|
|
487
|
+
this.requestMeta,
|
|
488
|
+
cloneState(this.state),
|
|
489
|
+
this.batcher,
|
|
490
|
+
this.transport
|
|
491
|
+
);
|
|
480
492
|
}
|
|
481
493
|
/** Create a request-scoped logger that extracts trace context from headers. Gets an independent copy of state. */
|
|
482
494
|
forRequest(request) {
|
|
@@ -503,7 +515,9 @@ var Logger = class _Logger {
|
|
|
503
515
|
request_id: requestId || (vercelId ? vercelId.split("::").pop() : void 0),
|
|
504
516
|
vercel_id: vercelId
|
|
505
517
|
},
|
|
506
|
-
cloneState(this.state)
|
|
518
|
+
cloneState(this.state),
|
|
519
|
+
this.batcher,
|
|
520
|
+
this.transport
|
|
507
521
|
);
|
|
508
522
|
}
|
|
509
523
|
// ---------------------------------------------------------------------------
|
|
@@ -638,11 +652,25 @@ var Logger = class _Logger {
|
|
|
638
652
|
this.transport.sendTrace(hookResult.data);
|
|
639
653
|
},
|
|
640
654
|
startSpan: (childOp, fn) => {
|
|
641
|
-
const childLogger = new _Logger(
|
|
655
|
+
const childLogger = new _Logger(
|
|
656
|
+
this.config,
|
|
657
|
+
this.contextName,
|
|
658
|
+
childMeta,
|
|
659
|
+
this.state,
|
|
660
|
+
this.batcher,
|
|
661
|
+
this.transport
|
|
662
|
+
);
|
|
642
663
|
return childLogger.startSpan(childOp, fn);
|
|
643
664
|
},
|
|
644
665
|
startInactiveSpan: (childOp) => {
|
|
645
|
-
const childLogger = new _Logger(
|
|
666
|
+
const childLogger = new _Logger(
|
|
667
|
+
this.config,
|
|
668
|
+
this.contextName,
|
|
669
|
+
childMeta,
|
|
670
|
+
this.state,
|
|
671
|
+
this.batcher,
|
|
672
|
+
this.transport
|
|
673
|
+
);
|
|
646
674
|
return childLogger.startInactiveSpan(childOp);
|
|
647
675
|
},
|
|
648
676
|
getHeaders: () => {
|
|
@@ -667,9 +695,19 @@ var Logger = class _Logger {
|
|
|
667
695
|
// ---------------------------------------------------------------------------
|
|
668
696
|
// Lifecycle
|
|
669
697
|
// ---------------------------------------------------------------------------
|
|
670
|
-
/**
|
|
671
|
-
|
|
698
|
+
/**
|
|
699
|
+
* Flush all batched log entries and wait for in-flight HTTP requests to complete.
|
|
700
|
+
*
|
|
701
|
+
* @returns Promise that resolves when all pending logs have been sent.
|
|
702
|
+
*
|
|
703
|
+
* @example
|
|
704
|
+
* ```ts
|
|
705
|
+
* await logger.flush() // ensure logs are sent before response is returned
|
|
706
|
+
* ```
|
|
707
|
+
*/
|
|
708
|
+
async flush() {
|
|
672
709
|
this.batcher.flush();
|
|
710
|
+
await this.transport.drain();
|
|
673
711
|
}
|
|
674
712
|
/**
|
|
675
713
|
* Stop the batch timer, flush remaining logs, and wait for in-flight requests.
|
|
@@ -684,7 +722,11 @@ var Logger = class _Logger {
|
|
|
684
722
|
* ```
|
|
685
723
|
*/
|
|
686
724
|
async destroy(timeoutMs) {
|
|
687
|
-
|
|
725
|
+
if (this.isRoot) {
|
|
726
|
+
await this.batcher.destroy();
|
|
727
|
+
} else {
|
|
728
|
+
this.batcher.flush();
|
|
729
|
+
}
|
|
688
730
|
await this.transport.drain(timeoutMs);
|
|
689
731
|
}
|
|
690
732
|
};
|
package/dist/index.cjs
CHANGED
|
@@ -33,7 +33,8 @@ var Batcher = class {
|
|
|
33
33
|
constructor(config, onFlush) {
|
|
34
34
|
this.onFlush = onFlush;
|
|
35
35
|
this.batchSize = config.batchSize ?? 50;
|
|
36
|
-
|
|
36
|
+
const isServerless = typeof process !== "undefined" && !!(process.env.VERCEL || process.env.AWS_LAMBDA_FUNCTION_NAME);
|
|
37
|
+
this.flushIntervalMs = config.flushIntervalMs ?? (isServerless ? 200 : 5e3);
|
|
37
38
|
this.startTimer();
|
|
38
39
|
}
|
|
39
40
|
buffer = [];
|
|
@@ -63,7 +64,7 @@ var Batcher = class {
|
|
|
63
64
|
};
|
|
64
65
|
|
|
65
66
|
// src/version.ts
|
|
66
|
-
var SDK_VERSION = "0.6.
|
|
67
|
+
var SDK_VERSION = "0.6.3";
|
|
67
68
|
var SDK_NAME = "core";
|
|
68
69
|
|
|
69
70
|
// src/transport.ts
|
|
@@ -295,30 +296,34 @@ var _originalConsole = {
|
|
|
295
296
|
var Logger = class _Logger {
|
|
296
297
|
batcher;
|
|
297
298
|
transport;
|
|
299
|
+
isRoot;
|
|
298
300
|
effectiveLevel;
|
|
299
301
|
contextName;
|
|
300
302
|
config;
|
|
301
303
|
state;
|
|
302
304
|
requestMeta;
|
|
303
|
-
constructor(config, contextName, requestMeta, state) {
|
|
305
|
+
constructor(config, contextName, requestMeta, state, sharedBatcher, sharedTransport) {
|
|
304
306
|
this.config = config;
|
|
305
307
|
this.contextName = contextName;
|
|
306
308
|
this.requestMeta = requestMeta;
|
|
307
309
|
this.state = state ?? createLoggerState(config.maxBreadcrumbs ?? 20);
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
310
|
+
this.isRoot = !sharedBatcher;
|
|
311
|
+
if (this.isRoot) {
|
|
312
|
+
const hasKey = !!config.apiKey;
|
|
313
|
+
const hasEndpoint = !!config.endpoint;
|
|
314
|
+
if (!hasKey && !hasEndpoint) {
|
|
315
|
+
_originalConsole.warn(
|
|
316
|
+
"[@deeptracer/core] No API key or endpoint configured. Running in local-only mode (logging methods work, but events are not sent). Set DEEPTRACER_KEY and DEEPTRACER_ENDPOINT to enable."
|
|
317
|
+
);
|
|
318
|
+
} else if (!hasKey) {
|
|
319
|
+
_originalConsole.warn("[@deeptracer/core] No `apiKey` provided. Events will not be sent.");
|
|
320
|
+
} else if (!hasEndpoint) {
|
|
321
|
+
_originalConsole.warn("[@deeptracer/core] No `endpoint` provided. Events will not be sent.");
|
|
322
|
+
}
|
|
318
323
|
}
|
|
319
324
|
this.effectiveLevel = LOG_LEVEL_VALUES[config.level ?? (config.environment === "production" ? "info" : "debug")];
|
|
320
|
-
this.transport = new Transport(config);
|
|
321
|
-
this.batcher = new Batcher(
|
|
325
|
+
this.transport = sharedTransport ?? new Transport(config);
|
|
326
|
+
this.batcher = sharedBatcher ?? new Batcher(
|
|
322
327
|
{ batchSize: config.batchSize, flushIntervalMs: config.flushIntervalMs },
|
|
323
328
|
(entries) => {
|
|
324
329
|
this.transport.sendLogs(entries);
|
|
@@ -506,7 +511,14 @@ var Logger = class _Logger {
|
|
|
506
511
|
// ---------------------------------------------------------------------------
|
|
507
512
|
/** Create a context-scoped logger. All logs include the context name. Gets an independent copy of state. */
|
|
508
513
|
withContext(name) {
|
|
509
|
-
return new _Logger(
|
|
514
|
+
return new _Logger(
|
|
515
|
+
this.config,
|
|
516
|
+
name,
|
|
517
|
+
this.requestMeta,
|
|
518
|
+
cloneState(this.state),
|
|
519
|
+
this.batcher,
|
|
520
|
+
this.transport
|
|
521
|
+
);
|
|
510
522
|
}
|
|
511
523
|
/** Create a request-scoped logger that extracts trace context from headers. Gets an independent copy of state. */
|
|
512
524
|
forRequest(request) {
|
|
@@ -533,7 +545,9 @@ var Logger = class _Logger {
|
|
|
533
545
|
request_id: requestId || (vercelId ? vercelId.split("::").pop() : void 0),
|
|
534
546
|
vercel_id: vercelId
|
|
535
547
|
},
|
|
536
|
-
cloneState(this.state)
|
|
548
|
+
cloneState(this.state),
|
|
549
|
+
this.batcher,
|
|
550
|
+
this.transport
|
|
537
551
|
);
|
|
538
552
|
}
|
|
539
553
|
// ---------------------------------------------------------------------------
|
|
@@ -668,11 +682,25 @@ var Logger = class _Logger {
|
|
|
668
682
|
this.transport.sendTrace(hookResult.data);
|
|
669
683
|
},
|
|
670
684
|
startSpan: (childOp, fn) => {
|
|
671
|
-
const childLogger = new _Logger(
|
|
685
|
+
const childLogger = new _Logger(
|
|
686
|
+
this.config,
|
|
687
|
+
this.contextName,
|
|
688
|
+
childMeta,
|
|
689
|
+
this.state,
|
|
690
|
+
this.batcher,
|
|
691
|
+
this.transport
|
|
692
|
+
);
|
|
672
693
|
return childLogger.startSpan(childOp, fn);
|
|
673
694
|
},
|
|
674
695
|
startInactiveSpan: (childOp) => {
|
|
675
|
-
const childLogger = new _Logger(
|
|
696
|
+
const childLogger = new _Logger(
|
|
697
|
+
this.config,
|
|
698
|
+
this.contextName,
|
|
699
|
+
childMeta,
|
|
700
|
+
this.state,
|
|
701
|
+
this.batcher,
|
|
702
|
+
this.transport
|
|
703
|
+
);
|
|
676
704
|
return childLogger.startInactiveSpan(childOp);
|
|
677
705
|
},
|
|
678
706
|
getHeaders: () => {
|
|
@@ -697,9 +725,19 @@ var Logger = class _Logger {
|
|
|
697
725
|
// ---------------------------------------------------------------------------
|
|
698
726
|
// Lifecycle
|
|
699
727
|
// ---------------------------------------------------------------------------
|
|
700
|
-
/**
|
|
701
|
-
|
|
728
|
+
/**
|
|
729
|
+
* Flush all batched log entries and wait for in-flight HTTP requests to complete.
|
|
730
|
+
*
|
|
731
|
+
* @returns Promise that resolves when all pending logs have been sent.
|
|
732
|
+
*
|
|
733
|
+
* @example
|
|
734
|
+
* ```ts
|
|
735
|
+
* await logger.flush() // ensure logs are sent before response is returned
|
|
736
|
+
* ```
|
|
737
|
+
*/
|
|
738
|
+
async flush() {
|
|
702
739
|
this.batcher.flush();
|
|
740
|
+
await this.transport.drain();
|
|
703
741
|
}
|
|
704
742
|
/**
|
|
705
743
|
* Stop the batch timer, flush remaining logs, and wait for in-flight requests.
|
|
@@ -714,7 +752,11 @@ var Logger = class _Logger {
|
|
|
714
752
|
* ```
|
|
715
753
|
*/
|
|
716
754
|
async destroy(timeoutMs) {
|
|
717
|
-
|
|
755
|
+
if (this.isRoot) {
|
|
756
|
+
await this.batcher.destroy();
|
|
757
|
+
} else {
|
|
758
|
+
this.batcher.flush();
|
|
759
|
+
}
|
|
718
760
|
await this.transport.drain(timeoutMs);
|
|
719
761
|
}
|
|
720
762
|
};
|
|
@@ -771,7 +813,7 @@ var noopLogger = {
|
|
|
771
813
|
startInactiveSpan: () => NOOP_INACTIVE_SPAN,
|
|
772
814
|
wrap: (_operation, fn) => fn,
|
|
773
815
|
// Lifecycle — resolve immediately
|
|
774
|
-
flush:
|
|
816
|
+
flush: () => Promise.resolve(),
|
|
775
817
|
destroy: () => Promise.resolve()
|
|
776
818
|
};
|
|
777
819
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { L as Logger } from './logger-
|
|
2
|
-
export { B as BeforeSendEvent, a as Breadcrumb, E as ErrorReport, I as InactiveSpan, b as LLMUsageReport, c as LogEntry, d as LogLevel, e as LoggerConfig, M as MiddlewareOptions, S as Span, f as SpanData, U as User, g as createLogger } from './logger-
|
|
1
|
+
import { L as Logger } from './logger-DyJENLNA.cjs';
|
|
2
|
+
export { B as BeforeSendEvent, a as Breadcrumb, E as ErrorReport, I as InactiveSpan, b as LLMUsageReport, c as LogEntry, d as LogLevel, e as LoggerConfig, M as MiddlewareOptions, S as Span, f as SpanData, U as User, g as createLogger } from './logger-DyJENLNA.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* A Logger-compatible object where every method is a silent no-op.
|
|
@@ -18,7 +18,7 @@ export { B as BeforeSendEvent, a as Breadcrumb, E as ErrorReport, I as InactiveS
|
|
|
18
18
|
declare const noopLogger: Logger;
|
|
19
19
|
|
|
20
20
|
/** SDK version. Update on each release. */
|
|
21
|
-
declare const SDK_VERSION = "0.6.
|
|
21
|
+
declare const SDK_VERSION = "0.6.3";
|
|
22
22
|
declare const SDK_NAME = "core";
|
|
23
23
|
|
|
24
24
|
export { Logger, SDK_NAME, SDK_VERSION, noopLogger };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { L as Logger } from './logger-
|
|
2
|
-
export { B as BeforeSendEvent, a as Breadcrumb, E as ErrorReport, I as InactiveSpan, b as LLMUsageReport, c as LogEntry, d as LogLevel, e as LoggerConfig, M as MiddlewareOptions, S as Span, f as SpanData, U as User, g as createLogger } from './logger-
|
|
1
|
+
import { L as Logger } from './logger-DyJENLNA.js';
|
|
2
|
+
export { B as BeforeSendEvent, a as Breadcrumb, E as ErrorReport, I as InactiveSpan, b as LLMUsageReport, c as LogEntry, d as LogLevel, e as LoggerConfig, M as MiddlewareOptions, S as Span, f as SpanData, U as User, g as createLogger } from './logger-DyJENLNA.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* A Logger-compatible object where every method is a silent no-op.
|
|
@@ -18,7 +18,7 @@ export { B as BeforeSendEvent, a as Breadcrumb, E as ErrorReport, I as InactiveS
|
|
|
18
18
|
declare const noopLogger: Logger;
|
|
19
19
|
|
|
20
20
|
/** SDK version. Update on each release. */
|
|
21
|
-
declare const SDK_VERSION = "0.6.
|
|
21
|
+
declare const SDK_VERSION = "0.6.3";
|
|
22
22
|
declare const SDK_NAME = "core";
|
|
23
23
|
|
|
24
24
|
export { Logger, SDK_NAME, SDK_VERSION, noopLogger };
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
SDK_NAME,
|
|
4
4
|
SDK_VERSION,
|
|
5
5
|
createLogger
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-W62R346F.js";
|
|
7
7
|
|
|
8
8
|
// src/noop-logger.ts
|
|
9
9
|
var NOOP_INACTIVE_SPAN = {
|
|
@@ -54,7 +54,7 @@ var noopLogger = {
|
|
|
54
54
|
startInactiveSpan: () => NOOP_INACTIVE_SPAN,
|
|
55
55
|
wrap: (_operation, fn) => fn,
|
|
56
56
|
// Lifecycle — resolve immediately
|
|
57
|
-
flush:
|
|
57
|
+
flush: () => Promise.resolve(),
|
|
58
58
|
destroy: () => Promise.resolve()
|
|
59
59
|
};
|
|
60
60
|
export {
|
package/dist/internal.cjs
CHANGED
|
@@ -33,7 +33,8 @@ var Batcher = class {
|
|
|
33
33
|
constructor(config, onFlush) {
|
|
34
34
|
this.onFlush = onFlush;
|
|
35
35
|
this.batchSize = config.batchSize ?? 50;
|
|
36
|
-
|
|
36
|
+
const isServerless = typeof process !== "undefined" && !!(process.env.VERCEL || process.env.AWS_LAMBDA_FUNCTION_NAME);
|
|
37
|
+
this.flushIntervalMs = config.flushIntervalMs ?? (isServerless ? 200 : 5e3);
|
|
37
38
|
this.startTimer();
|
|
38
39
|
}
|
|
39
40
|
buffer = [];
|
|
@@ -63,7 +64,7 @@ var Batcher = class {
|
|
|
63
64
|
};
|
|
64
65
|
|
|
65
66
|
// src/version.ts
|
|
66
|
-
var SDK_VERSION = "0.6.
|
|
67
|
+
var SDK_VERSION = "0.6.3";
|
|
67
68
|
var SDK_NAME = "core";
|
|
68
69
|
|
|
69
70
|
// src/transport.ts
|
|
@@ -295,30 +296,34 @@ var _originalConsole = {
|
|
|
295
296
|
var Logger = class _Logger {
|
|
296
297
|
batcher;
|
|
297
298
|
transport;
|
|
299
|
+
isRoot;
|
|
298
300
|
effectiveLevel;
|
|
299
301
|
contextName;
|
|
300
302
|
config;
|
|
301
303
|
state;
|
|
302
304
|
requestMeta;
|
|
303
|
-
constructor(config, contextName, requestMeta, state) {
|
|
305
|
+
constructor(config, contextName, requestMeta, state, sharedBatcher, sharedTransport) {
|
|
304
306
|
this.config = config;
|
|
305
307
|
this.contextName = contextName;
|
|
306
308
|
this.requestMeta = requestMeta;
|
|
307
309
|
this.state = state ?? createLoggerState(config.maxBreadcrumbs ?? 20);
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
310
|
+
this.isRoot = !sharedBatcher;
|
|
311
|
+
if (this.isRoot) {
|
|
312
|
+
const hasKey = !!config.apiKey;
|
|
313
|
+
const hasEndpoint = !!config.endpoint;
|
|
314
|
+
if (!hasKey && !hasEndpoint) {
|
|
315
|
+
_originalConsole.warn(
|
|
316
|
+
"[@deeptracer/core] No API key or endpoint configured. Running in local-only mode (logging methods work, but events are not sent). Set DEEPTRACER_KEY and DEEPTRACER_ENDPOINT to enable."
|
|
317
|
+
);
|
|
318
|
+
} else if (!hasKey) {
|
|
319
|
+
_originalConsole.warn("[@deeptracer/core] No `apiKey` provided. Events will not be sent.");
|
|
320
|
+
} else if (!hasEndpoint) {
|
|
321
|
+
_originalConsole.warn("[@deeptracer/core] No `endpoint` provided. Events will not be sent.");
|
|
322
|
+
}
|
|
318
323
|
}
|
|
319
324
|
this.effectiveLevel = LOG_LEVEL_VALUES[config.level ?? (config.environment === "production" ? "info" : "debug")];
|
|
320
|
-
this.transport = new Transport(config);
|
|
321
|
-
this.batcher = new Batcher(
|
|
325
|
+
this.transport = sharedTransport ?? new Transport(config);
|
|
326
|
+
this.batcher = sharedBatcher ?? new Batcher(
|
|
322
327
|
{ batchSize: config.batchSize, flushIntervalMs: config.flushIntervalMs },
|
|
323
328
|
(entries) => {
|
|
324
329
|
this.transport.sendLogs(entries);
|
|
@@ -506,7 +511,14 @@ var Logger = class _Logger {
|
|
|
506
511
|
// ---------------------------------------------------------------------------
|
|
507
512
|
/** Create a context-scoped logger. All logs include the context name. Gets an independent copy of state. */
|
|
508
513
|
withContext(name) {
|
|
509
|
-
return new _Logger(
|
|
514
|
+
return new _Logger(
|
|
515
|
+
this.config,
|
|
516
|
+
name,
|
|
517
|
+
this.requestMeta,
|
|
518
|
+
cloneState(this.state),
|
|
519
|
+
this.batcher,
|
|
520
|
+
this.transport
|
|
521
|
+
);
|
|
510
522
|
}
|
|
511
523
|
/** Create a request-scoped logger that extracts trace context from headers. Gets an independent copy of state. */
|
|
512
524
|
forRequest(request) {
|
|
@@ -533,7 +545,9 @@ var Logger = class _Logger {
|
|
|
533
545
|
request_id: requestId || (vercelId ? vercelId.split("::").pop() : void 0),
|
|
534
546
|
vercel_id: vercelId
|
|
535
547
|
},
|
|
536
|
-
cloneState(this.state)
|
|
548
|
+
cloneState(this.state),
|
|
549
|
+
this.batcher,
|
|
550
|
+
this.transport
|
|
537
551
|
);
|
|
538
552
|
}
|
|
539
553
|
// ---------------------------------------------------------------------------
|
|
@@ -668,11 +682,25 @@ var Logger = class _Logger {
|
|
|
668
682
|
this.transport.sendTrace(hookResult.data);
|
|
669
683
|
},
|
|
670
684
|
startSpan: (childOp, fn) => {
|
|
671
|
-
const childLogger = new _Logger(
|
|
685
|
+
const childLogger = new _Logger(
|
|
686
|
+
this.config,
|
|
687
|
+
this.contextName,
|
|
688
|
+
childMeta,
|
|
689
|
+
this.state,
|
|
690
|
+
this.batcher,
|
|
691
|
+
this.transport
|
|
692
|
+
);
|
|
672
693
|
return childLogger.startSpan(childOp, fn);
|
|
673
694
|
},
|
|
674
695
|
startInactiveSpan: (childOp) => {
|
|
675
|
-
const childLogger = new _Logger(
|
|
696
|
+
const childLogger = new _Logger(
|
|
697
|
+
this.config,
|
|
698
|
+
this.contextName,
|
|
699
|
+
childMeta,
|
|
700
|
+
this.state,
|
|
701
|
+
this.batcher,
|
|
702
|
+
this.transport
|
|
703
|
+
);
|
|
676
704
|
return childLogger.startInactiveSpan(childOp);
|
|
677
705
|
},
|
|
678
706
|
getHeaders: () => {
|
|
@@ -697,9 +725,19 @@ var Logger = class _Logger {
|
|
|
697
725
|
// ---------------------------------------------------------------------------
|
|
698
726
|
// Lifecycle
|
|
699
727
|
// ---------------------------------------------------------------------------
|
|
700
|
-
/**
|
|
701
|
-
|
|
728
|
+
/**
|
|
729
|
+
* Flush all batched log entries and wait for in-flight HTTP requests to complete.
|
|
730
|
+
*
|
|
731
|
+
* @returns Promise that resolves when all pending logs have been sent.
|
|
732
|
+
*
|
|
733
|
+
* @example
|
|
734
|
+
* ```ts
|
|
735
|
+
* await logger.flush() // ensure logs are sent before response is returned
|
|
736
|
+
* ```
|
|
737
|
+
*/
|
|
738
|
+
async flush() {
|
|
702
739
|
this.batcher.flush();
|
|
740
|
+
await this.transport.drain();
|
|
703
741
|
}
|
|
704
742
|
/**
|
|
705
743
|
* Stop the batch timer, flush remaining logs, and wait for in-flight requests.
|
|
@@ -714,7 +752,11 @@ var Logger = class _Logger {
|
|
|
714
752
|
* ```
|
|
715
753
|
*/
|
|
716
754
|
async destroy(timeoutMs) {
|
|
717
|
-
|
|
755
|
+
if (this.isRoot) {
|
|
756
|
+
await this.batcher.destroy();
|
|
757
|
+
} else {
|
|
758
|
+
this.batcher.flush();
|
|
759
|
+
}
|
|
718
760
|
await this.transport.drain(timeoutMs);
|
|
719
761
|
}
|
|
720
762
|
};
|
package/dist/internal.d.cts
CHANGED
|
@@ -1,72 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export { L as Logger, h as LoggerState, M as MiddlewareOptions, _ as _originalConsole, p as parseTraceparent } from './logger-CzZg2_vM.cjs';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* HTTP transport for sending data to the DeepTracer ingestion API.
|
|
6
|
-
*
|
|
7
|
-
* Features:
|
|
8
|
-
* - Automatic retry with exponential backoff (3 retries, 1s/2s/4s + jitter)
|
|
9
|
-
* - Only retries on network errors and 5xx (not 4xx client errors)
|
|
10
|
-
* - SDK version header on every request (`x-deeptracer-sdk: core/0.3.0`)
|
|
11
|
-
* - In-flight request tracking for graceful shutdown via `drain()`
|
|
12
|
-
* - Silent no-op when no API key or endpoint is configured (no retries, no console noise)
|
|
13
|
-
* - Warn-once per failure type — first failure for each send type (logs, error, trace)
|
|
14
|
-
* logs a warning, subsequent identical failures are silently dropped
|
|
15
|
-
*/
|
|
16
|
-
declare class Transport {
|
|
17
|
-
private config;
|
|
18
|
-
private inFlightRequests;
|
|
19
|
-
/**
|
|
20
|
-
* When true, all send methods become silent no-ops.
|
|
21
|
-
* Set automatically when no auth key or no endpoint is configured.
|
|
22
|
-
* This prevents pointless network requests and console noise during
|
|
23
|
-
* local development without API keys.
|
|
24
|
-
*/
|
|
25
|
-
private readonly disabled;
|
|
26
|
-
/**
|
|
27
|
-
* Tracks which send types (logs, error, trace, LLM usage) have already
|
|
28
|
-
* logged a failure warning. After the first failure for a given type,
|
|
29
|
-
* subsequent failures are silently dropped to prevent console spam
|
|
30
|
-
* (e.g., when the ingestion endpoint is unreachable during development).
|
|
31
|
-
*/
|
|
32
|
-
private warnedLabels;
|
|
33
|
-
constructor(config: Pick<LoggerConfig, "endpoint" | "apiKey" | "service" | "environment">);
|
|
34
|
-
private get authKey();
|
|
35
|
-
/**
|
|
36
|
-
* Send a request with automatic retry and exponential backoff.
|
|
37
|
-
* Retries up to `maxRetries` times on network errors and 5xx responses.
|
|
38
|
-
* Does NOT retry on 4xx (client errors — bad payload, auth failure, etc.).
|
|
39
|
-
*
|
|
40
|
-
* After the first total failure for a given label, subsequent failures
|
|
41
|
-
* are silently dropped (no more console warnings).
|
|
42
|
-
*/
|
|
43
|
-
private sendWithRetry;
|
|
44
|
-
/** Add +/- 20% jitter to a delay to prevent thundering herd. */
|
|
45
|
-
private jitter;
|
|
46
|
-
private sleep;
|
|
47
|
-
/** Track an in-flight request and remove it when done. */
|
|
48
|
-
private track;
|
|
49
|
-
sendLogs(logs: LogEntry[]): Promise<void>;
|
|
50
|
-
sendError(error: ErrorReport): Promise<void>;
|
|
51
|
-
sendTrace(span: SpanData): Promise<void>;
|
|
52
|
-
sendLLMUsage(report: {
|
|
53
|
-
model: string;
|
|
54
|
-
provider: string;
|
|
55
|
-
operation: string;
|
|
56
|
-
input_tokens: number;
|
|
57
|
-
output_tokens: number;
|
|
58
|
-
cost_usd: number;
|
|
59
|
-
latency_ms: number;
|
|
60
|
-
metadata?: Record<string, unknown>;
|
|
61
|
-
}): Promise<void>;
|
|
62
|
-
/**
|
|
63
|
-
* Wait for all in-flight requests to complete, with a timeout.
|
|
64
|
-
* Used by `logger.destroy()` to ensure data is sent before process exit.
|
|
65
|
-
*
|
|
66
|
-
* @param timeoutMs - Maximum time to wait (default: 2000ms)
|
|
67
|
-
*/
|
|
68
|
-
drain(timeoutMs?: number): Promise<void>;
|
|
69
|
-
}
|
|
1
|
+
export { L as Logger, e as LoggerConfig, h as LoggerState, M as MiddlewareOptions, T as Transport, _ as _originalConsole, p as parseTraceparent } from './logger-DyJENLNA.cjs';
|
|
70
2
|
|
|
71
3
|
/**
|
|
72
4
|
* Parse console.log/info/warn/error arguments into a structured `{ message, metadata }` pair.
|
|
@@ -82,4 +14,4 @@ declare function parseConsoleArgs(args: unknown[]): {
|
|
|
82
14
|
metadata?: Record<string, unknown>;
|
|
83
15
|
};
|
|
84
16
|
|
|
85
|
-
export {
|
|
17
|
+
export { parseConsoleArgs };
|
package/dist/internal.d.ts
CHANGED
|
@@ -1,72 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export { L as Logger, h as LoggerState, M as MiddlewareOptions, _ as _originalConsole, p as parseTraceparent } from './logger-CzZg2_vM.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* HTTP transport for sending data to the DeepTracer ingestion API.
|
|
6
|
-
*
|
|
7
|
-
* Features:
|
|
8
|
-
* - Automatic retry with exponential backoff (3 retries, 1s/2s/4s + jitter)
|
|
9
|
-
* - Only retries on network errors and 5xx (not 4xx client errors)
|
|
10
|
-
* - SDK version header on every request (`x-deeptracer-sdk: core/0.3.0`)
|
|
11
|
-
* - In-flight request tracking for graceful shutdown via `drain()`
|
|
12
|
-
* - Silent no-op when no API key or endpoint is configured (no retries, no console noise)
|
|
13
|
-
* - Warn-once per failure type — first failure for each send type (logs, error, trace)
|
|
14
|
-
* logs a warning, subsequent identical failures are silently dropped
|
|
15
|
-
*/
|
|
16
|
-
declare class Transport {
|
|
17
|
-
private config;
|
|
18
|
-
private inFlightRequests;
|
|
19
|
-
/**
|
|
20
|
-
* When true, all send methods become silent no-ops.
|
|
21
|
-
* Set automatically when no auth key or no endpoint is configured.
|
|
22
|
-
* This prevents pointless network requests and console noise during
|
|
23
|
-
* local development without API keys.
|
|
24
|
-
*/
|
|
25
|
-
private readonly disabled;
|
|
26
|
-
/**
|
|
27
|
-
* Tracks which send types (logs, error, trace, LLM usage) have already
|
|
28
|
-
* logged a failure warning. After the first failure for a given type,
|
|
29
|
-
* subsequent failures are silently dropped to prevent console spam
|
|
30
|
-
* (e.g., when the ingestion endpoint is unreachable during development).
|
|
31
|
-
*/
|
|
32
|
-
private warnedLabels;
|
|
33
|
-
constructor(config: Pick<LoggerConfig, "endpoint" | "apiKey" | "service" | "environment">);
|
|
34
|
-
private get authKey();
|
|
35
|
-
/**
|
|
36
|
-
* Send a request with automatic retry and exponential backoff.
|
|
37
|
-
* Retries up to `maxRetries` times on network errors and 5xx responses.
|
|
38
|
-
* Does NOT retry on 4xx (client errors — bad payload, auth failure, etc.).
|
|
39
|
-
*
|
|
40
|
-
* After the first total failure for a given label, subsequent failures
|
|
41
|
-
* are silently dropped (no more console warnings).
|
|
42
|
-
*/
|
|
43
|
-
private sendWithRetry;
|
|
44
|
-
/** Add +/- 20% jitter to a delay to prevent thundering herd. */
|
|
45
|
-
private jitter;
|
|
46
|
-
private sleep;
|
|
47
|
-
/** Track an in-flight request and remove it when done. */
|
|
48
|
-
private track;
|
|
49
|
-
sendLogs(logs: LogEntry[]): Promise<void>;
|
|
50
|
-
sendError(error: ErrorReport): Promise<void>;
|
|
51
|
-
sendTrace(span: SpanData): Promise<void>;
|
|
52
|
-
sendLLMUsage(report: {
|
|
53
|
-
model: string;
|
|
54
|
-
provider: string;
|
|
55
|
-
operation: string;
|
|
56
|
-
input_tokens: number;
|
|
57
|
-
output_tokens: number;
|
|
58
|
-
cost_usd: number;
|
|
59
|
-
latency_ms: number;
|
|
60
|
-
metadata?: Record<string, unknown>;
|
|
61
|
-
}): Promise<void>;
|
|
62
|
-
/**
|
|
63
|
-
* Wait for all in-flight requests to complete, with a timeout.
|
|
64
|
-
* Used by `logger.destroy()` to ensure data is sent before process exit.
|
|
65
|
-
*
|
|
66
|
-
* @param timeoutMs - Maximum time to wait (default: 2000ms)
|
|
67
|
-
*/
|
|
68
|
-
drain(timeoutMs?: number): Promise<void>;
|
|
69
|
-
}
|
|
1
|
+
export { L as Logger, e as LoggerConfig, h as LoggerState, M as MiddlewareOptions, T as Transport, _ as _originalConsole, p as parseTraceparent } from './logger-DyJENLNA.js';
|
|
70
2
|
|
|
71
3
|
/**
|
|
72
4
|
* Parse console.log/info/warn/error arguments into a structured `{ message, metadata }` pair.
|
|
@@ -82,4 +14,4 @@ declare function parseConsoleArgs(args: unknown[]): {
|
|
|
82
14
|
metadata?: Record<string, unknown>;
|
|
83
15
|
};
|
|
84
16
|
|
|
85
|
-
export {
|
|
17
|
+
export { parseConsoleArgs };
|
package/dist/internal.js
CHANGED
|
@@ -209,6 +209,89 @@ type BeforeSendEvent = {
|
|
|
209
209
|
data: LLMUsageReport;
|
|
210
210
|
};
|
|
211
211
|
|
|
212
|
+
declare class Batcher {
|
|
213
|
+
private onFlush;
|
|
214
|
+
private buffer;
|
|
215
|
+
private timer;
|
|
216
|
+
private batchSize;
|
|
217
|
+
private flushIntervalMs;
|
|
218
|
+
constructor(config: {
|
|
219
|
+
batchSize?: number;
|
|
220
|
+
flushIntervalMs?: number;
|
|
221
|
+
}, onFlush: (entries: LogEntry[]) => void);
|
|
222
|
+
add(entry: LogEntry): void;
|
|
223
|
+
flush(): void;
|
|
224
|
+
private startTimer;
|
|
225
|
+
destroy(): Promise<void>;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* HTTP transport for sending data to the DeepTracer ingestion API.
|
|
230
|
+
*
|
|
231
|
+
* Features:
|
|
232
|
+
* - Automatic retry with exponential backoff (3 retries, 1s/2s/4s + jitter)
|
|
233
|
+
* - Only retries on network errors and 5xx (not 4xx client errors)
|
|
234
|
+
* - SDK version header on every request (`x-deeptracer-sdk: core/0.3.0`)
|
|
235
|
+
* - In-flight request tracking for graceful shutdown via `drain()`
|
|
236
|
+
* - Silent no-op when no API key or endpoint is configured (no retries, no console noise)
|
|
237
|
+
* - Warn-once per failure type — first failure for each send type (logs, error, trace)
|
|
238
|
+
* logs a warning, subsequent identical failures are silently dropped
|
|
239
|
+
*/
|
|
240
|
+
declare class Transport {
|
|
241
|
+
private config;
|
|
242
|
+
private inFlightRequests;
|
|
243
|
+
/**
|
|
244
|
+
* When true, all send methods become silent no-ops.
|
|
245
|
+
* Set automatically when no auth key or no endpoint is configured.
|
|
246
|
+
* This prevents pointless network requests and console noise during
|
|
247
|
+
* local development without API keys.
|
|
248
|
+
*/
|
|
249
|
+
private readonly disabled;
|
|
250
|
+
/**
|
|
251
|
+
* Tracks which send types (logs, error, trace, LLM usage) have already
|
|
252
|
+
* logged a failure warning. After the first failure for a given type,
|
|
253
|
+
* subsequent failures are silently dropped to prevent console spam
|
|
254
|
+
* (e.g., when the ingestion endpoint is unreachable during development).
|
|
255
|
+
*/
|
|
256
|
+
private warnedLabels;
|
|
257
|
+
constructor(config: Pick<LoggerConfig, "endpoint" | "apiKey" | "service" | "environment">);
|
|
258
|
+
private get authKey();
|
|
259
|
+
/**
|
|
260
|
+
* Send a request with automatic retry and exponential backoff.
|
|
261
|
+
* Retries up to `maxRetries` times on network errors and 5xx responses.
|
|
262
|
+
* Does NOT retry on 4xx (client errors — bad payload, auth failure, etc.).
|
|
263
|
+
*
|
|
264
|
+
* After the first total failure for a given label, subsequent failures
|
|
265
|
+
* are silently dropped (no more console warnings).
|
|
266
|
+
*/
|
|
267
|
+
private sendWithRetry;
|
|
268
|
+
/** Add +/- 20% jitter to a delay to prevent thundering herd. */
|
|
269
|
+
private jitter;
|
|
270
|
+
private sleep;
|
|
271
|
+
/** Track an in-flight request and remove it when done. */
|
|
272
|
+
private track;
|
|
273
|
+
sendLogs(logs: LogEntry[]): Promise<void>;
|
|
274
|
+
sendError(error: ErrorReport): Promise<void>;
|
|
275
|
+
sendTrace(span: SpanData): Promise<void>;
|
|
276
|
+
sendLLMUsage(report: {
|
|
277
|
+
model: string;
|
|
278
|
+
provider: string;
|
|
279
|
+
operation: string;
|
|
280
|
+
input_tokens: number;
|
|
281
|
+
output_tokens: number;
|
|
282
|
+
cost_usd: number;
|
|
283
|
+
latency_ms: number;
|
|
284
|
+
metadata?: Record<string, unknown>;
|
|
285
|
+
}): Promise<void>;
|
|
286
|
+
/**
|
|
287
|
+
* Wait for all in-flight requests to complete, with a timeout.
|
|
288
|
+
* Used by `logger.destroy()` to ensure data is sent before process exit.
|
|
289
|
+
*
|
|
290
|
+
* @param timeoutMs - Maximum time to wait (default: 2000ms)
|
|
291
|
+
*/
|
|
292
|
+
drain(timeoutMs?: number): Promise<void>;
|
|
293
|
+
}
|
|
294
|
+
|
|
212
295
|
/**
|
|
213
296
|
* Mutable state for a Logger instance.
|
|
214
297
|
* The root Logger creates this; `withContext()` and `forRequest()` clone it
|
|
@@ -276,6 +359,7 @@ declare const _originalConsole: {
|
|
|
276
359
|
declare class Logger {
|
|
277
360
|
private batcher;
|
|
278
361
|
private transport;
|
|
362
|
+
private readonly isRoot;
|
|
279
363
|
private effectiveLevel;
|
|
280
364
|
protected contextName?: string;
|
|
281
365
|
protected config: LoggerConfig;
|
|
@@ -291,7 +375,7 @@ declare class Logger {
|
|
|
291
375
|
span_id?: string;
|
|
292
376
|
request_id?: string;
|
|
293
377
|
vercel_id?: string;
|
|
294
|
-
}, state?: LoggerState);
|
|
378
|
+
}, state?: LoggerState, sharedBatcher?: Batcher, sharedTransport?: Transport);
|
|
295
379
|
/**
|
|
296
380
|
* Set the current user context. Attached to all subsequent logs, errors, spans, and LLM reports.
|
|
297
381
|
* Only affects this logger instance — child loggers created via `withContext()` or `forRequest()`
|
|
@@ -378,8 +462,17 @@ declare class Logger {
|
|
|
378
462
|
startInactiveSpan(operation: string): InactiveSpan;
|
|
379
463
|
/** Wrap a function with automatic tracing and error capture. */
|
|
380
464
|
wrap<TArgs extends unknown[], TReturn>(operation: string, fn: (...args: TArgs) => TReturn): (...args: TArgs) => TReturn;
|
|
381
|
-
/**
|
|
382
|
-
|
|
465
|
+
/**
|
|
466
|
+
* Flush all batched log entries and wait for in-flight HTTP requests to complete.
|
|
467
|
+
*
|
|
468
|
+
* @returns Promise that resolves when all pending logs have been sent.
|
|
469
|
+
*
|
|
470
|
+
* @example
|
|
471
|
+
* ```ts
|
|
472
|
+
* await logger.flush() // ensure logs are sent before response is returned
|
|
473
|
+
* ```
|
|
474
|
+
*/
|
|
475
|
+
flush(): Promise<void>;
|
|
383
476
|
/**
|
|
384
477
|
* Stop the batch timer, flush remaining logs, and wait for in-flight requests.
|
|
385
478
|
*
|
|
@@ -397,4 +490,4 @@ declare class Logger {
|
|
|
397
490
|
/** Create a new DeepTracer logger instance. */
|
|
398
491
|
declare function createLogger(config: LoggerConfig): Logger;
|
|
399
492
|
|
|
400
|
-
export { type BeforeSendEvent as B, type ErrorReport as E, type InactiveSpan as I, Logger as L, type MiddlewareOptions as M, type Span as S, type User as U, _originalConsole as _, type Breadcrumb as a, type LLMUsageReport as b, type LogEntry as c, type LogLevel as d, type LoggerConfig as e, type SpanData as f, createLogger as g, type LoggerState as h, parseTraceparent as p };
|
|
493
|
+
export { type BeforeSendEvent as B, type ErrorReport as E, type InactiveSpan as I, Logger as L, type MiddlewareOptions as M, type Span as S, Transport as T, type User as U, _originalConsole as _, type Breadcrumb as a, type LLMUsageReport as b, type LogEntry as c, type LogLevel as d, type LoggerConfig as e, type SpanData as f, createLogger as g, type LoggerState as h, parseTraceparent as p };
|
|
@@ -209,6 +209,89 @@ type BeforeSendEvent = {
|
|
|
209
209
|
data: LLMUsageReport;
|
|
210
210
|
};
|
|
211
211
|
|
|
212
|
+
declare class Batcher {
|
|
213
|
+
private onFlush;
|
|
214
|
+
private buffer;
|
|
215
|
+
private timer;
|
|
216
|
+
private batchSize;
|
|
217
|
+
private flushIntervalMs;
|
|
218
|
+
constructor(config: {
|
|
219
|
+
batchSize?: number;
|
|
220
|
+
flushIntervalMs?: number;
|
|
221
|
+
}, onFlush: (entries: LogEntry[]) => void);
|
|
222
|
+
add(entry: LogEntry): void;
|
|
223
|
+
flush(): void;
|
|
224
|
+
private startTimer;
|
|
225
|
+
destroy(): Promise<void>;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* HTTP transport for sending data to the DeepTracer ingestion API.
|
|
230
|
+
*
|
|
231
|
+
* Features:
|
|
232
|
+
* - Automatic retry with exponential backoff (3 retries, 1s/2s/4s + jitter)
|
|
233
|
+
* - Only retries on network errors and 5xx (not 4xx client errors)
|
|
234
|
+
* - SDK version header on every request (`x-deeptracer-sdk: core/0.3.0`)
|
|
235
|
+
* - In-flight request tracking for graceful shutdown via `drain()`
|
|
236
|
+
* - Silent no-op when no API key or endpoint is configured (no retries, no console noise)
|
|
237
|
+
* - Warn-once per failure type — first failure for each send type (logs, error, trace)
|
|
238
|
+
* logs a warning, subsequent identical failures are silently dropped
|
|
239
|
+
*/
|
|
240
|
+
declare class Transport {
|
|
241
|
+
private config;
|
|
242
|
+
private inFlightRequests;
|
|
243
|
+
/**
|
|
244
|
+
* When true, all send methods become silent no-ops.
|
|
245
|
+
* Set automatically when no auth key or no endpoint is configured.
|
|
246
|
+
* This prevents pointless network requests and console noise during
|
|
247
|
+
* local development without API keys.
|
|
248
|
+
*/
|
|
249
|
+
private readonly disabled;
|
|
250
|
+
/**
|
|
251
|
+
* Tracks which send types (logs, error, trace, LLM usage) have already
|
|
252
|
+
* logged a failure warning. After the first failure for a given type,
|
|
253
|
+
* subsequent failures are silently dropped to prevent console spam
|
|
254
|
+
* (e.g., when the ingestion endpoint is unreachable during development).
|
|
255
|
+
*/
|
|
256
|
+
private warnedLabels;
|
|
257
|
+
constructor(config: Pick<LoggerConfig, "endpoint" | "apiKey" | "service" | "environment">);
|
|
258
|
+
private get authKey();
|
|
259
|
+
/**
|
|
260
|
+
* Send a request with automatic retry and exponential backoff.
|
|
261
|
+
* Retries up to `maxRetries` times on network errors and 5xx responses.
|
|
262
|
+
* Does NOT retry on 4xx (client errors — bad payload, auth failure, etc.).
|
|
263
|
+
*
|
|
264
|
+
* After the first total failure for a given label, subsequent failures
|
|
265
|
+
* are silently dropped (no more console warnings).
|
|
266
|
+
*/
|
|
267
|
+
private sendWithRetry;
|
|
268
|
+
/** Add +/- 20% jitter to a delay to prevent thundering herd. */
|
|
269
|
+
private jitter;
|
|
270
|
+
private sleep;
|
|
271
|
+
/** Track an in-flight request and remove it when done. */
|
|
272
|
+
private track;
|
|
273
|
+
sendLogs(logs: LogEntry[]): Promise<void>;
|
|
274
|
+
sendError(error: ErrorReport): Promise<void>;
|
|
275
|
+
sendTrace(span: SpanData): Promise<void>;
|
|
276
|
+
sendLLMUsage(report: {
|
|
277
|
+
model: string;
|
|
278
|
+
provider: string;
|
|
279
|
+
operation: string;
|
|
280
|
+
input_tokens: number;
|
|
281
|
+
output_tokens: number;
|
|
282
|
+
cost_usd: number;
|
|
283
|
+
latency_ms: number;
|
|
284
|
+
metadata?: Record<string, unknown>;
|
|
285
|
+
}): Promise<void>;
|
|
286
|
+
/**
|
|
287
|
+
* Wait for all in-flight requests to complete, with a timeout.
|
|
288
|
+
* Used by `logger.destroy()` to ensure data is sent before process exit.
|
|
289
|
+
*
|
|
290
|
+
* @param timeoutMs - Maximum time to wait (default: 2000ms)
|
|
291
|
+
*/
|
|
292
|
+
drain(timeoutMs?: number): Promise<void>;
|
|
293
|
+
}
|
|
294
|
+
|
|
212
295
|
/**
|
|
213
296
|
* Mutable state for a Logger instance.
|
|
214
297
|
* The root Logger creates this; `withContext()` and `forRequest()` clone it
|
|
@@ -276,6 +359,7 @@ declare const _originalConsole: {
|
|
|
276
359
|
declare class Logger {
|
|
277
360
|
private batcher;
|
|
278
361
|
private transport;
|
|
362
|
+
private readonly isRoot;
|
|
279
363
|
private effectiveLevel;
|
|
280
364
|
protected contextName?: string;
|
|
281
365
|
protected config: LoggerConfig;
|
|
@@ -291,7 +375,7 @@ declare class Logger {
|
|
|
291
375
|
span_id?: string;
|
|
292
376
|
request_id?: string;
|
|
293
377
|
vercel_id?: string;
|
|
294
|
-
}, state?: LoggerState);
|
|
378
|
+
}, state?: LoggerState, sharedBatcher?: Batcher, sharedTransport?: Transport);
|
|
295
379
|
/**
|
|
296
380
|
* Set the current user context. Attached to all subsequent logs, errors, spans, and LLM reports.
|
|
297
381
|
* Only affects this logger instance — child loggers created via `withContext()` or `forRequest()`
|
|
@@ -378,8 +462,17 @@ declare class Logger {
|
|
|
378
462
|
startInactiveSpan(operation: string): InactiveSpan;
|
|
379
463
|
/** Wrap a function with automatic tracing and error capture. */
|
|
380
464
|
wrap<TArgs extends unknown[], TReturn>(operation: string, fn: (...args: TArgs) => TReturn): (...args: TArgs) => TReturn;
|
|
381
|
-
/**
|
|
382
|
-
|
|
465
|
+
/**
|
|
466
|
+
* Flush all batched log entries and wait for in-flight HTTP requests to complete.
|
|
467
|
+
*
|
|
468
|
+
* @returns Promise that resolves when all pending logs have been sent.
|
|
469
|
+
*
|
|
470
|
+
* @example
|
|
471
|
+
* ```ts
|
|
472
|
+
* await logger.flush() // ensure logs are sent before response is returned
|
|
473
|
+
* ```
|
|
474
|
+
*/
|
|
475
|
+
flush(): Promise<void>;
|
|
383
476
|
/**
|
|
384
477
|
* Stop the batch timer, flush remaining logs, and wait for in-flight requests.
|
|
385
478
|
*
|
|
@@ -397,4 +490,4 @@ declare class Logger {
|
|
|
397
490
|
/** Create a new DeepTracer logger instance. */
|
|
398
491
|
declare function createLogger(config: LoggerConfig): Logger;
|
|
399
492
|
|
|
400
|
-
export { type BeforeSendEvent as B, type ErrorReport as E, type InactiveSpan as I, Logger as L, type MiddlewareOptions as M, type Span as S, type User as U, _originalConsole as _, type Breadcrumb as a, type LLMUsageReport as b, type LogEntry as c, type LogLevel as d, type LoggerConfig as e, type SpanData as f, createLogger as g, type LoggerState as h, parseTraceparent as p };
|
|
493
|
+
export { type BeforeSendEvent as B, type ErrorReport as E, type InactiveSpan as I, Logger as L, type MiddlewareOptions as M, type Span as S, Transport as T, type User as U, _originalConsole as _, type Breadcrumb as a, type LLMUsageReport as b, type LogEntry as c, type LogLevel as d, type LoggerConfig as e, type SpanData as f, createLogger as g, type LoggerState as h, parseTraceparent as p };
|