logquill 0.3.0 → 1.0.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 +392 -6
- package/dist/browser.d.ts +468 -0
- package/dist/browser.mjs +783 -0
- package/dist/browser.mjs.map +1 -0
- package/dist/index.cjs +756 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +561 -126
- package/dist/index.d.ts +561 -126
- package/dist/index.mjs +736 -9
- package/dist/index.mjs.map +1 -1
- package/dist/langchain.cjs +120 -0
- package/dist/langchain.cjs.map +1 -0
- package/dist/langchain.d.cts +128 -0
- package/dist/langchain.d.ts +128 -0
- package/dist/langchain.mjs +116 -0
- package/dist/langchain.mjs.map +1 -0
- package/dist/logger-CRdmCDfC.d.cts +299 -0
- package/dist/logger-CRdmCDfC.d.ts +299 -0
- package/dist/winston.cjs +108 -0
- package/dist/winston.cjs.map +1 -0
- package/dist/winston.d.cts +55 -0
- package/dist/winston.d.ts +55 -0
- package/dist/winston.mjs +101 -0
- package/dist/winston.mjs.map +1 -0
- package/package.json +57 -12
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
/** Log levels, shared by name and numeric weight with the logquill-python contract. */
|
|
2
|
+
declare enum Level {
|
|
3
|
+
/** Finest-grained diagnostic detail. */
|
|
4
|
+
TRACE = 5,
|
|
5
|
+
/** Diagnostic detail useful in development. */
|
|
6
|
+
DEBUG = 10,
|
|
7
|
+
/** Notable events during normal operation. */
|
|
8
|
+
INFO = 20,
|
|
9
|
+
/** Something unexpected, but not (yet) an error. */
|
|
10
|
+
WARN = 30,
|
|
11
|
+
/** An error that didn't necessarily stop the operation. */
|
|
12
|
+
ERROR = 40,
|
|
13
|
+
/** An error that precedes an unrecoverable failure. */
|
|
14
|
+
FATAL = 50
|
|
15
|
+
}
|
|
16
|
+
/** A level given as a `Level`, a level name (any case), or its numeric weight. */
|
|
17
|
+
type LevelInput = Level | number | string;
|
|
18
|
+
/** The level's name, e.g. `levelName(Level.INFO) === "INFO"`. */
|
|
19
|
+
declare function levelName(level: Level): string;
|
|
20
|
+
/** Normalize a level given as a `Level`, level name, or numeric weight. Throws if unknown. */
|
|
21
|
+
declare function parseLevel(level: LevelInput): Level;
|
|
22
|
+
|
|
23
|
+
/** The cross-language record shape shared with logquill-python. */
|
|
24
|
+
interface LogRecord {
|
|
25
|
+
/** ISO8601 UTC timestamp with millisecond precision. */
|
|
26
|
+
timestamp: string;
|
|
27
|
+
/** Level name, e.g. `"INFO"`. */
|
|
28
|
+
level: string;
|
|
29
|
+
/** Name of the `Logger` that created this record. */
|
|
30
|
+
logger: string;
|
|
31
|
+
/** The log message. */
|
|
32
|
+
message: string;
|
|
33
|
+
/** Structured payload — always present, even if empty. */
|
|
34
|
+
meta: Record<string, unknown>;
|
|
35
|
+
}
|
|
36
|
+
/** ISO8601 UTC timestamp with millisecond precision, matching Python's `utc_timestamp()`. */
|
|
37
|
+
declare function utcTimestamp(): string;
|
|
38
|
+
/** Builds a `LogRecord` with the current UTC timestamp. Used internally by `Logger`; exported for transports/plugins that need to construct a record directly. */
|
|
39
|
+
declare function createRecord(params: {
|
|
40
|
+
level: Level;
|
|
41
|
+
logger: string;
|
|
42
|
+
message: string;
|
|
43
|
+
meta: Record<string, unknown>;
|
|
44
|
+
}): LogRecord;
|
|
45
|
+
|
|
46
|
+
/** `format(record) -> string`, per the transport contract shared with logquill-python. */
|
|
47
|
+
interface Formatter {
|
|
48
|
+
/** Turns a `LogRecord` into the string a `Transport` writes. */
|
|
49
|
+
format(record: LogRecord): string;
|
|
50
|
+
}
|
|
51
|
+
/** Serializes a record to the canonical JSON line shape. */
|
|
52
|
+
declare class JSONFormatter implements Formatter {
|
|
53
|
+
/** Returns `JSON.stringify(record)`. */
|
|
54
|
+
format(record: LogRecord): string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The plugin pipeline hooks, matching the Python hook names: `beforeLog`,
|
|
59
|
+
* `afterLog`, `onError`. All hooks are optional — implement only what you need.
|
|
60
|
+
* A hook that throws cannot crash logging: the pipeline catches it, routes it
|
|
61
|
+
* to `onError`, and moves on.
|
|
62
|
+
*/
|
|
63
|
+
interface Plugin {
|
|
64
|
+
/** Return a (possibly modified) record, or `null` to drop it. */
|
|
65
|
+
beforeLog?(record: LogRecord): LogRecord | null;
|
|
66
|
+
/** Called after the record has been dispatched to every transport. */
|
|
67
|
+
afterLog?(record: LogRecord): void;
|
|
68
|
+
/** Called when one of this plugin's own hooks throws. */
|
|
69
|
+
onError?(error: unknown, record: LogRecord): void;
|
|
70
|
+
}
|
|
71
|
+
/** A plain `beforeLog`-style function, as accepted by `Logger.use()` in place of a `Plugin`. */
|
|
72
|
+
type MiddlewareFunc = (record: LogRecord) => LogRecord | null;
|
|
73
|
+
/**
|
|
74
|
+
* Wraps a plain `beforeLog`-style function as a `Plugin`. `Logger.use()`
|
|
75
|
+
* builds one of these automatically when given a function instead of a
|
|
76
|
+
* `Plugin` — Express/Koa-style middleware ergonomics, without needing to
|
|
77
|
+
* read the `Plugin` interface first. There's no `next()` chaining: the
|
|
78
|
+
* pipeline already calls hooks in sequence, so this is sugar for a
|
|
79
|
+
* single-method `Plugin`, not a new execution model.
|
|
80
|
+
*/
|
|
81
|
+
declare class FunctionPlugin implements Plugin {
|
|
82
|
+
private readonly func;
|
|
83
|
+
constructor(func: MiddlewareFunc);
|
|
84
|
+
beforeLog(record: LogRecord): LogRecord | null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Injects fixed key/value pairs into every record's `meta`.
|
|
89
|
+
* A value already present in a record's own `meta` wins over the fixed context.
|
|
90
|
+
*/
|
|
91
|
+
declare class ContextPlugin implements Plugin {
|
|
92
|
+
/** Fixed key/value pairs merged into every record's `meta`. */
|
|
93
|
+
readonly context: Record<string, unknown>;
|
|
94
|
+
constructor(context: Record<string, unknown>);
|
|
95
|
+
beforeLog(record: LogRecord): LogRecord;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** `meta` keys (case-insensitive) `RedactPlugin` replaces by default. */
|
|
99
|
+
declare const DEFAULT_REDACTED_KEYS: readonly string[];
|
|
100
|
+
/** Options for {@link RedactPlugin}. */
|
|
101
|
+
interface RedactPluginOptions {
|
|
102
|
+
/** Keys (case-insensitive) to redact. Default `DEFAULT_REDACTED_KEYS`. */
|
|
103
|
+
keys?: readonly string[];
|
|
104
|
+
/** Placeholder a matched value is replaced with. Default `"***"`. */
|
|
105
|
+
replacement?: string;
|
|
106
|
+
}
|
|
107
|
+
/** Replaces sensitive `meta` values, matched by key (case-insensitive), with a placeholder. */
|
|
108
|
+
declare class RedactPlugin implements Plugin {
|
|
109
|
+
private readonly keys;
|
|
110
|
+
/** Placeholder a matched value is replaced with. */
|
|
111
|
+
readonly replacement: string;
|
|
112
|
+
constructor(options?: RedactPluginOptions);
|
|
113
|
+
beforeLog(record: LogRecord): LogRecord;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Syntactic (not semantic) patterns — matched on shape, so both false
|
|
118
|
+
* positives (a random 9-digit number) and false negatives (anything that
|
|
119
|
+
* doesn't look like these shapes) are expected. Override via `patterns`
|
|
120
|
+
* for anything stricter.
|
|
121
|
+
*/
|
|
122
|
+
declare const DEFAULT_PII_PATTERNS: Readonly<Record<string, RegExp>>;
|
|
123
|
+
/** Options for {@link PIIRedactPlugin}. */
|
|
124
|
+
interface PIIRedactPluginOptions {
|
|
125
|
+
/** Named patterns to scan for. Default `DEFAULT_PII_PATTERNS`. */
|
|
126
|
+
patterns?: Readonly<Record<string, RegExp>>;
|
|
127
|
+
/** Placeholder a matched substring is replaced with. Default `"***"`. */
|
|
128
|
+
replacement?: string;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Regex-based PII redaction over `meta` **values**, not just keys.
|
|
132
|
+
*
|
|
133
|
+
* Complements `RedactPlugin`, which redacts by exact key match —
|
|
134
|
+
* `PIIRedactPlugin` scans string values (recursively through nested
|
|
135
|
+
* objects/arrays) for emails, SSNs, credit-card numbers, and phone
|
|
136
|
+
* numbers, and redacts matches wherever they appear, regardless of which
|
|
137
|
+
* key holds them (a `notes` field containing a stray SSN is still caught).
|
|
138
|
+
*
|
|
139
|
+
* Detection is pattern-based: fast and dependency-free, but it matches on
|
|
140
|
+
* syntactic shape, not meaning — a random 9-digit number can false-positive
|
|
141
|
+
* as an SSN, and anything that doesn't fit these shapes (a name, a street
|
|
142
|
+
* address) is a false negative. Pass your own `patterns` to extend or
|
|
143
|
+
* replace the defaults.
|
|
144
|
+
*
|
|
145
|
+
* Recursion into nested `meta` structures is depth- and cycle-bounded, so a
|
|
146
|
+
* circular reference or a pathologically deep structure can't hang or
|
|
147
|
+
* crash the caller — it's left unredacted past the bound rather than
|
|
148
|
+
* throwing.
|
|
149
|
+
*/
|
|
150
|
+
declare class PIIRedactPlugin implements Plugin {
|
|
151
|
+
/** Named patterns scanned for in every string `meta` value. */
|
|
152
|
+
readonly patterns: Readonly<Record<string, RegExp>>;
|
|
153
|
+
/** Placeholder a matched substring is replaced with. */
|
|
154
|
+
readonly replacement: string;
|
|
155
|
+
constructor(options?: PIIRedactPluginOptions);
|
|
156
|
+
beforeLog(record: LogRecord): LogRecord;
|
|
157
|
+
private redactValue;
|
|
158
|
+
private redactText;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Sink for log records, per the cross-language transport contract:
|
|
163
|
+
* `format(record) -> string`, `write(formatted, record)`, `close()` on shutdown.
|
|
164
|
+
*/
|
|
165
|
+
declare abstract class Transport {
|
|
166
|
+
/** Turns a `LogRecord` into the string this transport actually writes. Defaults to `JSONFormatter`. */
|
|
167
|
+
formatter: Formatter;
|
|
168
|
+
constructor(formatter?: Formatter);
|
|
169
|
+
/** Formats `record` via `this.formatter`. Called once per record before `write()`. */
|
|
170
|
+
format(record: LogRecord): string;
|
|
171
|
+
/** Sends the already-formatted record to this transport's sink. */
|
|
172
|
+
abstract write(formatted: string, record: LogRecord): void;
|
|
173
|
+
/** Flush/release resources on shutdown. No-op unless a transport overrides it. */
|
|
174
|
+
close(): void;
|
|
175
|
+
}
|
|
176
|
+
/** Duck-typed: a transport (typically a `BatchingTransport`) whose `flush()` sends its current buffer now, without closing. */
|
|
177
|
+
interface FlushableTransport {
|
|
178
|
+
/** Sends the current buffer now, even if it hasn't reached its own flush threshold. */
|
|
179
|
+
flush(): void | Promise<void>;
|
|
180
|
+
}
|
|
181
|
+
/** Type guard for {@link FlushableTransport} — true for any transport (e.g. every `BatchingTransport`) that exposes a `flush()` method. */
|
|
182
|
+
declare function hasFlush(transport: Transport): transport is Transport & FlushableTransport;
|
|
183
|
+
/** In-memory transport for tests: collects every (formatted, record) pair written to it. */
|
|
184
|
+
declare class CollectingTransport extends Transport {
|
|
185
|
+
/** Every formatted string passed to `write()`, in call order. */
|
|
186
|
+
readonly formatted: string[];
|
|
187
|
+
/** Every raw `LogRecord` passed to `write()`, in call order. */
|
|
188
|
+
readonly records: LogRecord[];
|
|
189
|
+
/** Set once `close()` has been called. */
|
|
190
|
+
closed: boolean;
|
|
191
|
+
write(formatted: string, record: LogRecord): void;
|
|
192
|
+
close(): void;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** Options for {@link SamplingPlugin}. */
|
|
196
|
+
interface SamplingPluginOptions {
|
|
197
|
+
/** Source of randomness for the rate check. Defaults to `Math.random`; override with a seeded/fake generator for deterministic tests. */
|
|
198
|
+
rng?: () => number;
|
|
199
|
+
/** `meta` key holding the trace/run id used to group buffered records. Default `"traceId"`. */
|
|
200
|
+
traceKey?: string;
|
|
201
|
+
/** A record at or above this level elevates its whole trace. Default `Level.ERROR`. */
|
|
202
|
+
elevateAt?: LevelInput;
|
|
203
|
+
/** Enables tail-based elevation, writing straight to these transports on elevation. Omit to disable and get plain rate-based sampling. */
|
|
204
|
+
transports?: Transport[];
|
|
205
|
+
/** Total buffered records allowed across every trace before the oldest trace is evicted. Default 1000. */
|
|
206
|
+
maxBufferedRecords?: number;
|
|
207
|
+
/** Distinct trace ids held at once before the oldest is evicted. Default 200. */
|
|
208
|
+
maxTraces?: number;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Keeps roughly `rate` of records (0.0-1.0), dropping the rest.
|
|
212
|
+
*
|
|
213
|
+
* With `transports` set, sampling becomes tail-based per trace: a record
|
|
214
|
+
* that would otherwise be dropped is buffered under its `meta[traceKey]`
|
|
215
|
+
* value instead of discarded outright. If any later record sharing that
|
|
216
|
+
* trace id reaches `elevateAt` or above, the whole trace is "elevated" —
|
|
217
|
+
* every buffered record for that trace id is flushed straight to
|
|
218
|
+
* `transports`, and every subsequent record for that trace id ships
|
|
219
|
+
* unconditionally. This is what lets a sampled-out request still produce a
|
|
220
|
+
* complete trace once it turns out to matter (it errored).
|
|
221
|
+
*
|
|
222
|
+
* Flushing writes buffered records directly to `transports` — pass the
|
|
223
|
+
* same array given to the `Logger`. This bypasses `beforeLog`/`afterLog`/
|
|
224
|
+
* `onError` for any plugin *after* `SamplingPlugin` in the pipeline (the
|
|
225
|
+
* plugins before it already ran, since that's how the buffered record was
|
|
226
|
+
* built); put `SamplingPlugin` last if that matters for your pipeline.
|
|
227
|
+
*
|
|
228
|
+
* Without `transports`, tail-based elevation is inactive and this behaves
|
|
229
|
+
* exactly like plain rate-based sampling (the original behavior) — a
|
|
230
|
+
* record without `meta[traceKey]` is also just rate-sampled, since there's
|
|
231
|
+
* no trace to buffer it under.
|
|
232
|
+
*
|
|
233
|
+
* Buffering is bounded: at most `maxBufferedRecords` records total and
|
|
234
|
+
* `maxTraces` distinct trace ids are held at once. Once either limit is
|
|
235
|
+
* hit, the oldest buffered trace is evicted (and its records are lost, not
|
|
236
|
+
* flushed) — a deliberate bounded-memory trade-off, not a bug: an
|
|
237
|
+
* unbounded per-trace buffer would let a single pathologically long-lived
|
|
238
|
+
* or high-cardinality trace grow memory without limit.
|
|
239
|
+
*/
|
|
240
|
+
declare class SamplingPlugin implements Plugin {
|
|
241
|
+
/** Fraction of non-elevated records kept, in `[0, 1]`. */
|
|
242
|
+
readonly rate: number;
|
|
243
|
+
/** `meta` key holding the trace/run id used to group buffered records. */
|
|
244
|
+
readonly traceKey: string;
|
|
245
|
+
/** A record at or above this level elevates its whole trace. */
|
|
246
|
+
readonly elevateAt: Level;
|
|
247
|
+
/** Transports buffered records are flushed straight to on elevation; `undefined` disables tail-based elevation. */
|
|
248
|
+
readonly transports: Transport[] | undefined;
|
|
249
|
+
/** Total buffered records allowed across every trace before the oldest trace is evicted. */
|
|
250
|
+
readonly maxBufferedRecords: number;
|
|
251
|
+
/** Distinct trace ids held at once before the oldest is evicted. */
|
|
252
|
+
readonly maxTraces: number;
|
|
253
|
+
private readonly rng;
|
|
254
|
+
private readonly buffer;
|
|
255
|
+
private bufferedCount;
|
|
256
|
+
private readonly elevated;
|
|
257
|
+
constructor(rate: number, options?: SamplingPluginOptions);
|
|
258
|
+
beforeLog(record: LogRecord): LogRecord | null;
|
|
259
|
+
private elevate;
|
|
260
|
+
private bufferRecord;
|
|
261
|
+
private evictOldestTrace;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/** The subset of `console` this transport needs — swap in a fake for tests. */
|
|
265
|
+
interface ConsoleLike {
|
|
266
|
+
/** Writes one already-formatted line, e.g. for a TRACE–WARN record. */
|
|
267
|
+
log(message: string): void;
|
|
268
|
+
/** Writes one already-formatted line, e.g. for an ERROR/FATAL record. */
|
|
269
|
+
error(message: string): void;
|
|
270
|
+
}
|
|
271
|
+
/** Options for {@link ConsoleTransport}. */
|
|
272
|
+
interface ConsoleTransportOptions {
|
|
273
|
+
/** Turns a `LogRecord` into the string this transport writes. Defaults to `JSONFormatter`. */
|
|
274
|
+
formatter?: Formatter;
|
|
275
|
+
/** Wrap each line in an ANSI color escape for its level. Defaults to `true` unless the `NO_COLOR` env var is set. */
|
|
276
|
+
colorize?: boolean;
|
|
277
|
+
/** Sink to write through instead of the global `console` — swap in a fake for tests. */
|
|
278
|
+
console?: ConsoleLike;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Writes to `console.log`, routing ERROR/FATAL to `console.error`, colorized by
|
|
282
|
+
* level. Uses the global `console` rather than Node's `process.stdout`/`stderr`
|
|
283
|
+
* so this transport works unmodified in a browser bundle.
|
|
284
|
+
*/
|
|
285
|
+
declare class ConsoleTransport extends Transport {
|
|
286
|
+
/** Whether each line is wrapped in an ANSI color escape for its level. */
|
|
287
|
+
colorize: boolean;
|
|
288
|
+
private readonly out;
|
|
289
|
+
constructor(options?: ConsoleTransportOptions);
|
|
290
|
+
/** Writes `formatted` via `console.log`, or `console.error` for ERROR/FATAL records. */
|
|
291
|
+
write(formatted: string, record: LogRecord): void;
|
|
292
|
+
private applyColor;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/** Sends one batch of formatted lines to `url`. Swap in a fake for tests. */
|
|
296
|
+
type BeaconSender = (url: string, batch: readonly string[]) => void;
|
|
297
|
+
/** Options for {@link BeaconTransport}. */
|
|
298
|
+
interface BeaconTransportOptions {
|
|
299
|
+
/** Turns a `LogRecord` into the string this transport writes. Defaults to `JSONFormatter`. */
|
|
300
|
+
formatter?: Formatter;
|
|
301
|
+
/** Flush once the buffer holds this many lines. Default 20 — kept low since `sendBeacon` payloads are capped. */
|
|
302
|
+
batchSize?: number;
|
|
303
|
+
/** Delivers one batch. Defaults to `sendBeacon` with a `fetch(..., { keepalive: true })` fallback; override for a fake or a different backend. */
|
|
304
|
+
sender?: BeaconSender;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Batches formatted records and sends them via `navigator.sendBeacon`,
|
|
308
|
+
* falling back to a `keepalive` `fetch` where `sendBeacon` isn't available.
|
|
309
|
+
* Meant for the browser: unlike `HTTPTransport`, a beacon send can complete
|
|
310
|
+
* even after the page that queued it starts unloading. Keep `batchSize`
|
|
311
|
+
* small — `sendBeacon` payloads are capped (64KB in most browsers).
|
|
312
|
+
*/
|
|
313
|
+
declare class BeaconTransport extends Transport {
|
|
314
|
+
/** Endpoint each batch is sent to. */
|
|
315
|
+
readonly url: string;
|
|
316
|
+
/** Buffer is flushed once it holds this many lines. */
|
|
317
|
+
readonly batchSize: number;
|
|
318
|
+
private readonly sender;
|
|
319
|
+
private batch;
|
|
320
|
+
constructor(url: string, options?: BeaconTransportOptions);
|
|
321
|
+
/** Buffers the formatted line, flushing the batch once `batchSize` is reached. */
|
|
322
|
+
write(formatted: string): void;
|
|
323
|
+
/** Send the current batch now, even if it hasn't reached `batchSize`. */
|
|
324
|
+
flush(): void;
|
|
325
|
+
close(): void;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/** How a full queue behaves when another task arrives. */
|
|
329
|
+
type BackpressurePolicy = "dropOldest" | "dropNewest" | "block";
|
|
330
|
+
/** Options for the {@link DispatchQueue} constructor. */
|
|
331
|
+
interface DispatchQueueOptions {
|
|
332
|
+
/** Maximum number of pending tasks the queue holds at once. Default 10_000. */
|
|
333
|
+
maxSize?: number;
|
|
334
|
+
/**
|
|
335
|
+
* What happens when `enqueue()` is called while the queue is already at
|
|
336
|
+
* `maxSize`:
|
|
337
|
+
* - `"dropOldest"` (default) — evict the longest-waiting task (it never
|
|
338
|
+
* runs) and enqueue the new one. Favors recent records.
|
|
339
|
+
* - `"dropNewest"` — discard the incoming task; everything already queued
|
|
340
|
+
* is left alone. Favors records already in flight.
|
|
341
|
+
* - `"block"` — run the task synchronously, right now, on the caller's
|
|
342
|
+
* stack instead of queueing it. Nothing is ever dropped, at the cost of
|
|
343
|
+
* the caller (e.g. `logger.info()`) taking as long as the write itself —
|
|
344
|
+
* real backpressure rather than a silent drop.
|
|
345
|
+
*/
|
|
346
|
+
policy?: BackpressurePolicy;
|
|
347
|
+
/**
|
|
348
|
+
* Called at most once per `warnIntervalMs` (default 5000) when the queue
|
|
349
|
+
* drops tasks, with the number dropped since the last call — a
|
|
350
|
+
* rate-limited way to surface sustained overload without flooding the
|
|
351
|
+
* caller's own logs with one warning per drop. Defaults to `console.warn`.
|
|
352
|
+
*/
|
|
353
|
+
onDrop?: (droppedSinceLastWarning: number, policy: BackpressurePolicy) => void;
|
|
354
|
+
/** Minimum gap between `onDrop` calls. Default 5000ms. */
|
|
355
|
+
warnIntervalMs?: number;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/** Options for `Logger.span()`. Any extra keys become the span's own `meta`. */
|
|
359
|
+
interface SpanOptions extends Record<string, unknown> {
|
|
360
|
+
/** Adopt an id handed in from elsewhere (e.g. a framework's own run id) instead of generating one. */
|
|
361
|
+
spanId?: string;
|
|
362
|
+
/** Adopt a parent id explicitly, overriding auto-nesting from an enclosing `span()` block. */
|
|
363
|
+
parentSpanId?: string;
|
|
364
|
+
}
|
|
365
|
+
/** Options for the {@link Logger} constructor. */
|
|
366
|
+
interface LoggerOptions {
|
|
367
|
+
/** Minimum level that reaches a transport; records below it are dropped before any plugin runs. Default `INFO`. */
|
|
368
|
+
level?: LevelInput;
|
|
369
|
+
/** Sinks every record that passes the level filter and plugin pipeline is written to. */
|
|
370
|
+
transports?: Transport[];
|
|
371
|
+
/** Registered via `.use()` in order — a plain function is wrapped as an anonymous `Plugin`. */
|
|
372
|
+
plugins?: (Plugin | MiddlewareFunc)[];
|
|
373
|
+
/** Merged into every record's `meta`, before a call-site `meta` value (which always wins on collision). */
|
|
374
|
+
meta?: Record<string, unknown>;
|
|
375
|
+
/** Bounds and backpressure policy for the internal async dispatch queue. See `DispatchQueueOptions`. */
|
|
376
|
+
queue?: DispatchQueueOptions;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* The core logger: leveled, structured logging over a pluggable transport
|
|
380
|
+
* and plugin pipeline. Every log call returns the finished `LogRecord` (or
|
|
381
|
+
* `null` if it was filtered by level or dropped by a plugin) synchronously —
|
|
382
|
+
* the actual transport writes are dispatched onto an internal queue so the
|
|
383
|
+
* call returns before any I/O runs; see `flush()`/`close()`.
|
|
384
|
+
*/
|
|
385
|
+
declare class Logger {
|
|
386
|
+
/** This logger's name, as passed to the constructor (or derived via `.child()`). Appears on every record as `logger`. */
|
|
387
|
+
readonly name: string;
|
|
388
|
+
/** Every transport a written record is sent to. */
|
|
389
|
+
readonly transports: Transport[];
|
|
390
|
+
/** Every plugin registered via `.use()`, in registration order. */
|
|
391
|
+
readonly plugins: Plugin[];
|
|
392
|
+
private currentLevel;
|
|
393
|
+
private readonly baseMeta;
|
|
394
|
+
private dispatchQueue;
|
|
395
|
+
constructor(name: string, options?: LoggerOptions);
|
|
396
|
+
/** This logger's current minimum level — records below it are filtered before any plugin runs. */
|
|
397
|
+
get level(): Level;
|
|
398
|
+
/** Changes the minimum level records must meet to reach a transport. Accepts a `Level`, its numeric weight, or its name. */
|
|
399
|
+
setLevel(level: LevelInput): void;
|
|
400
|
+
/**
|
|
401
|
+
* Register a plugin, or a plain `beforeLog`-style function. A function is
|
|
402
|
+
* wrapped internally as an anonymous `Plugin` (`FunctionPlugin`) — the
|
|
403
|
+
* same middleware ergonomics as Express/Koa, without needing to read the
|
|
404
|
+
* `Plugin` interface first. Returns `this` so calls can be chained.
|
|
405
|
+
*/
|
|
406
|
+
use(plugin: Plugin | MiddlewareFunc): this;
|
|
407
|
+
/** Number of dispatched records not yet written to their transports. Bounded by the `queue` option. */
|
|
408
|
+
get queueSize(): number;
|
|
409
|
+
/**
|
|
410
|
+
* Waits for every record dispatched so far to reach its transports'
|
|
411
|
+
* `write()` (and any plugin `afterLog` hooks). Note this does *not* force
|
|
412
|
+
* a batching transport (SQL, a queue, `HTTPTransport`, ...) to send a
|
|
413
|
+
* batch still under its own `maxRecords`/`maxBytes` threshold early — it
|
|
414
|
+
* only guarantees the record has been handed to that transport, the same
|
|
415
|
+
* contract `write()` always had. Before a process may pause or exit
|
|
416
|
+
* (a serverless freeze, a shutdown signal), prefer `withLambda`/
|
|
417
|
+
* `installShutdownHandlers`, which additionally force every batching
|
|
418
|
+
* transport to send its current buffer regardless of threshold.
|
|
419
|
+
*/
|
|
420
|
+
flush(): Promise<void>;
|
|
421
|
+
/** Flush every pending record, then close every attached transport. Call once, on shutdown. */
|
|
422
|
+
close(): Promise<void>;
|
|
423
|
+
/** A logger scoped under this one, inheriting its level, transports, plugins, and dispatch queue. */
|
|
424
|
+
child(name: string, meta?: Record<string, unknown>): Logger;
|
|
425
|
+
private notifyError;
|
|
426
|
+
private dispatch;
|
|
427
|
+
private writeAndNotify;
|
|
428
|
+
/** Logs at `TRACE` — the lowest level, for fine-grained diagnostic detail. Returns the record, or `null` if filtered/dropped. */
|
|
429
|
+
trace(message: string, meta?: Record<string, unknown>): LogRecord | null;
|
|
430
|
+
/** Logs at `DEBUG`. Returns the record, or `null` if filtered/dropped. */
|
|
431
|
+
debug(message: string, meta?: Record<string, unknown>): LogRecord | null;
|
|
432
|
+
/** Logs at `INFO`. Returns the record, or `null` if filtered/dropped. */
|
|
433
|
+
info(message: string, meta?: Record<string, unknown>): LogRecord | null;
|
|
434
|
+
/** Logs at `WARN`. Returns the record, or `null` if filtered/dropped. */
|
|
435
|
+
warn(message: string, meta?: Record<string, unknown>): LogRecord | null;
|
|
436
|
+
/** Logs at `ERROR`. Returns the record, or `null` if filtered/dropped. */
|
|
437
|
+
error(message: string, meta?: Record<string, unknown>): LogRecord | null;
|
|
438
|
+
/** Logs at `FATAL` — the highest level, for errors that precede an unrecoverable failure. Returns the record, or `null` if filtered/dropped. */
|
|
439
|
+
fatal(message: string, meta?: Record<string, unknown>): LogRecord | null;
|
|
440
|
+
/** `.info()` tagged `meta.kind = "thought"` — an agent's internal reasoning step, for harness/agentic tracing. */
|
|
441
|
+
thought(message: string, meta?: Record<string, unknown>): LogRecord | null;
|
|
442
|
+
/** `.info()` tagged `meta.kind = "action"` — an agent taking an action (a tool call, an LLM request), for harness/agentic tracing. */
|
|
443
|
+
action(message: string, meta?: Record<string, unknown>): LogRecord | null;
|
|
444
|
+
/** `.info()` tagged `meta.kind = "observation"` — the result an agent observed from an action, for harness/agentic tracing. */
|
|
445
|
+
observation(message: string, meta?: Record<string, unknown>): LogRecord | null;
|
|
446
|
+
/** `.info()` tagged `meta.kind = "decision"` — an agent's concluding decision for a step or run, for harness/agentic tracing. */
|
|
447
|
+
decision(message: string, meta?: Record<string, unknown>): LogRecord | null;
|
|
448
|
+
/**
|
|
449
|
+
* `await logger.span("callLlm", async () => {...})` — runs `fn`, and on
|
|
450
|
+
* settling (success or throw) emits one record for the span itself
|
|
451
|
+
* carrying `meta.spanId` and `meta.durationMs`. Every record logged
|
|
452
|
+
* inside `fn` — through any method, and through any further `await` —
|
|
453
|
+
* is automatically stamped with `meta.parentSpanId` pointing at this
|
|
454
|
+
* span, so nested/sub-agent calls reconstruct their exact nesting when
|
|
455
|
+
* sorted by `spanId`/`parentSpanId`.
|
|
456
|
+
*
|
|
457
|
+
* Still emits its record — at `ERROR`, with `meta.error` set — if `fn`
|
|
458
|
+
* throws; the error itself propagates unchanged to the caller.
|
|
459
|
+
*
|
|
460
|
+
* `spanId`/`parentSpanId` normally auto-generate/auto-nest; pass them in
|
|
461
|
+
* `options` to adopt an id handed in from elsewhere (e.g. a framework
|
|
462
|
+
* adapter translating an id it already received).
|
|
463
|
+
*/
|
|
464
|
+
span<T>(name: string, fn: () => T | Promise<T>, options?: SpanOptions): Promise<T>;
|
|
465
|
+
private finishSpan;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
export { type BeaconSender, BeaconTransport, type BeaconTransportOptions, CollectingTransport, type ConsoleLike, ConsoleTransport, type ConsoleTransportOptions, ContextPlugin, DEFAULT_PII_PATTERNS, DEFAULT_REDACTED_KEYS, type FlushableTransport, type Formatter, FunctionPlugin, JSONFormatter, Level, type LevelInput, type LogRecord, Logger, type LoggerOptions, type MiddlewareFunc, PIIRedactPlugin, type PIIRedactPluginOptions, type Plugin, RedactPlugin, type RedactPluginOptions, SamplingPlugin, type SamplingPluginOptions, type SpanOptions, Transport, createRecord, hasFlush, levelName, parseLevel, utcTimestamp };
|