@unhingged/logit 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +132 -2
- package/dist/chunk-3FU7DTQE.cjs +2117 -0
- package/dist/chunk-3FU7DTQE.cjs.map +1 -0
- package/dist/chunk-7J27DQIR.js +72 -0
- package/dist/chunk-7J27DQIR.js.map +1 -0
- package/dist/chunk-GW7WQELF.js +2117 -0
- package/dist/chunk-GW7WQELF.js.map +1 -0
- package/dist/chunk-SKS54NHB.cjs +72 -0
- package/dist/chunk-SKS54NHB.cjs.map +1 -0
- package/dist/express.cjs +195 -0
- package/dist/express.cjs.map +1 -0
- package/dist/express.d.cts +39 -0
- package/dist/express.d.ts +39 -0
- package/dist/express.js +195 -0
- package/dist/express.js.map +1 -0
- package/dist/index.cjs +143 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +877 -0
- package/dist/index.d.ts +877 -0
- package/dist/index.js +143 -0
- package/dist/index.js.map +1 -0
- package/dist/next.cjs +212 -0
- package/dist/next.cjs.map +1 -0
- package/dist/next.d.cts +55 -0
- package/dist/next.d.ts +55 -0
- package/dist/next.js +212 -0
- package/dist/next.js.map +1 -0
- package/dist/node.cjs +341 -0
- package/dist/node.cjs.map +1 -0
- package/dist/node.d.cts +58 -0
- package/dist/node.d.ts +58 -0
- package/dist/node.js +341 -0
- package/dist/node.js.map +1 -0
- package/dist/otel.cjs +304 -0
- package/dist/otel.cjs.map +1 -0
- package/dist/otel.d.cts +103 -0
- package/dist/otel.d.ts +103 -0
- package/dist/otel.js +304 -0
- package/dist/otel.js.map +1 -0
- package/dist/request-7cW3twuF.d.ts +34 -0
- package/dist/request-DrVrbDze.d.cts +34 -0
- package/package.json +89 -4
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,877 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capturing — turning the arguments of a logging call into the values stored
|
|
3
|
+
* on the event. This is Serilog's destructuring step, with JS defaults:
|
|
4
|
+
*
|
|
5
|
+
* scalars kept as they are (Date stays a Date; bigint, symbol and
|
|
6
|
+
* functions become strings)
|
|
7
|
+
* plain objects, captured structurally — they are data
|
|
8
|
+
* arrays, Map, Set
|
|
9
|
+
* class instances rendered with their own `toString()` / `toJSON()`, or
|
|
10
|
+
* the class name — they are behaviour — unless `@` is used
|
|
11
|
+
* `@` destructures anything, class instances included (`$type`
|
|
12
|
+
* carries the class name)
|
|
13
|
+
* `$` stringifies anything
|
|
14
|
+
* Error always captured as a structure (name, message, stack,
|
|
15
|
+
* own properties, `cause` chain)
|
|
16
|
+
*
|
|
17
|
+
* Depth, string and collection limits, redaction by key and transforming
|
|
18
|
+
* policies all apply here, once, at capture time — so every sink sees the
|
|
19
|
+
* same, already-safe value.
|
|
20
|
+
*/
|
|
21
|
+
interface CapturedError {
|
|
22
|
+
$type: 'Error';
|
|
23
|
+
name: string;
|
|
24
|
+
message: string;
|
|
25
|
+
stack?: string;
|
|
26
|
+
cause?: unknown;
|
|
27
|
+
errors?: unknown[];
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A policy sees every non-scalar value before the default rules and may
|
|
32
|
+
* replace it. Return `undefined` to decline; return `{ value }` to substitute
|
|
33
|
+
* (the substitute is captured again, so return something simpler than you
|
|
34
|
+
* were given or the policy recurses — Serilog's rule).
|
|
35
|
+
*/
|
|
36
|
+
type DestructuringPolicy = (value: object) => {
|
|
37
|
+
value: unknown;
|
|
38
|
+
} | undefined;
|
|
39
|
+
interface DestructuringOptions {
|
|
40
|
+
/** Nesting depth beyond which values are replaced by `'[Object]'` / `'[Array]'`. */
|
|
41
|
+
maxDepth: number;
|
|
42
|
+
/** Strings longer than this are cut and end with `…`. `Infinity` = no limit. */
|
|
43
|
+
maxStringLength: number;
|
|
44
|
+
/** Arrays, Sets and Maps are cut to this many elements. `Infinity` = no limit. */
|
|
45
|
+
maxCollectionCount: number;
|
|
46
|
+
/**
|
|
47
|
+
* Keys whose values are replaced by `redactedValue`, at any depth.
|
|
48
|
+
* A bare name (`'password'`) matches that key anywhere, case-insensitively.
|
|
49
|
+
* A dotted path (`'headers.authorization'`, `'*.token'`, `'user.*.ssn'`) is
|
|
50
|
+
* matched from the root of the captured value; `*` is one segment.
|
|
51
|
+
*/
|
|
52
|
+
redact: readonly string[];
|
|
53
|
+
redactedValue: unknown;
|
|
54
|
+
/** Policies run in order; the first that answers wins. */
|
|
55
|
+
policies: readonly DestructuringPolicy[];
|
|
56
|
+
/** Add `$type` (the class name) when a class instance is destructured with `@`. */
|
|
57
|
+
typeTag: boolean;
|
|
58
|
+
}
|
|
59
|
+
declare const DEFAULT_DESTRUCTURING: DestructuringOptions;
|
|
60
|
+
/** Serilog's `Destructure.ByTransforming<T>()`: when a value is an instance of `type`, log `transform(value)` instead. */
|
|
61
|
+
declare function byTransforming<T extends object>(type: abstract new (...args: never[]) => T, transform: (value: T) => unknown): DestructuringPolicy;
|
|
62
|
+
type CaptureOperator = '@' | '$' | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Captures one value. `operator` is the hole's `@` / `$`; `path` is the key
|
|
65
|
+
* path from the root (for redaction) and `seen` guards against cycles.
|
|
66
|
+
*/
|
|
67
|
+
declare function captureValue(value: unknown, operator: CaptureOperator, options: DestructuringOptions, path?: string[], seen?: Set<object>, depth?: number): unknown;
|
|
68
|
+
/**
|
|
69
|
+
* Captures a value that is about to become the property `name` — the root
|
|
70
|
+
* of its redaction path, so `redact: ['password']` also covers
|
|
71
|
+
* `log.info('Login {Password}', pw)` and `forContext('password', …)`.
|
|
72
|
+
*/
|
|
73
|
+
declare function captureProperty(name: string, value: unknown, operator: CaptureOperator, options: DestructuringOptions): unknown;
|
|
74
|
+
/**
|
|
75
|
+
* Errors are always structured: name, message, stack, every own enumerable
|
|
76
|
+
* property (the `code` on a Node error, the `status` on an HTTP one), the
|
|
77
|
+
* `cause` chain and an `AggregateError`'s `errors`.
|
|
78
|
+
*/
|
|
79
|
+
declare function captureError(error: Error, options?: DestructuringOptions, path?: string[], seen?: Set<object>, depth?: number): CapturedError;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Serilog's six levels. The names are the JS-idiomatic short forms
|
|
83
|
+
* (`info`, `warn`), with Serilog's own (`information`, `warning`) and
|
|
84
|
+
* pino's (`trace`) accepted wherever a level is parsed from text.
|
|
85
|
+
*/
|
|
86
|
+
type LogLevel = 'verbose' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
|
|
87
|
+
declare const LEVELS: readonly LogLevel[];
|
|
88
|
+
declare const LEVEL_ORDER: Readonly<Record<LogLevel, number>>;
|
|
89
|
+
/** Serilog's level names — what CLEF (`@l`) and `{Level}` in an output template print. */
|
|
90
|
+
declare const SERILOG_LEVEL_NAMES: Readonly<Record<LogLevel, string>>;
|
|
91
|
+
/** Serilog's three-letter codes (`{Level:u3}`). */
|
|
92
|
+
declare const LEVEL_CODES: Readonly<Record<LogLevel, string>>;
|
|
93
|
+
/** pino / bunyan numeric levels, for the JSON formatter's `levelFormat: 'number'`. */
|
|
94
|
+
declare const LEVEL_NUMBERS: Readonly<Record<LogLevel, number>>;
|
|
95
|
+
/**
|
|
96
|
+
* Parses a level from any of its spellings (`'Information'`, `'warning'`,
|
|
97
|
+
* `'trace'`, `'ERR'`, pino's `30`). Throws on anything it cannot read, so a
|
|
98
|
+
* typo in configuration fails at startup rather than silencing a logger.
|
|
99
|
+
*/
|
|
100
|
+
declare function parseLevel(input: LogLevel | string | number): LogLevel;
|
|
101
|
+
declare function isLevel(input: unknown): input is LogLevel;
|
|
102
|
+
/** `true` when `level` is at or above `minimum`. */
|
|
103
|
+
declare function levelAtLeast(level: LogLevel, minimum: LogLevel): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* A level that can be changed while the application runs — Serilog's
|
|
106
|
+
* `LoggingLevelSwitch`. Hand the same instance to a logger's `minimumLevel`,
|
|
107
|
+
* an override, or a sink's `restrictedToMinimumLevel`, and flip it from an
|
|
108
|
+
* admin endpoint or a signal handler without recreating anything.
|
|
109
|
+
*/
|
|
110
|
+
declare class LevelSwitch {
|
|
111
|
+
#private;
|
|
112
|
+
constructor(initial?: LogLevel | string);
|
|
113
|
+
get level(): LogLevel;
|
|
114
|
+
set level(next: LogLevel | string);
|
|
115
|
+
/** Called with the new level on every change; returns an unsubscribe function. */
|
|
116
|
+
onChange(listener: (level: LogLevel) => void): () => void;
|
|
117
|
+
}
|
|
118
|
+
type LevelOrSwitch = LogLevel | string | LevelSwitch;
|
|
119
|
+
/** Resolves a configured level — static or a switch — to its current value. */
|
|
120
|
+
declare function resolveLevel(value: LevelOrSwitch): LogLevel;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Message templates (https://messagetemplates.org): `"User {UserId} bought {@Order}"`.
|
|
124
|
+
*
|
|
125
|
+
* A template is parsed once (cached by its text) into text and hole tokens.
|
|
126
|
+
* Holes carry the `@` / `$` capturing operator, an optional `,alignment` and
|
|
127
|
+
* `:format`. Malformed holes are kept as literal text, as Serilog does, so a
|
|
128
|
+
* stray brace never throws from a logging call.
|
|
129
|
+
*/
|
|
130
|
+
interface TextToken {
|
|
131
|
+
readonly kind: 'text';
|
|
132
|
+
readonly text: string;
|
|
133
|
+
}
|
|
134
|
+
interface HoleToken {
|
|
135
|
+
readonly kind: 'hole';
|
|
136
|
+
/** The hole exactly as written, braces included — used when no value binds to it. */
|
|
137
|
+
readonly raw: string;
|
|
138
|
+
/** Property name, or the digits of a positional hole. */
|
|
139
|
+
readonly name: string;
|
|
140
|
+
/** Set for positional holes (`{0}`). */
|
|
141
|
+
readonly index?: number;
|
|
142
|
+
/** `@` destructures, `$` stringifies, undefined leaves it to the capture rules. */
|
|
143
|
+
readonly operator?: '@' | '$';
|
|
144
|
+
/** Positive pads on the left, negative on the right (`{Name,-10}`). */
|
|
145
|
+
readonly alignment?: number;
|
|
146
|
+
/** `{Elapsed:0.00}` — passed through to the renderer. */
|
|
147
|
+
readonly format?: string;
|
|
148
|
+
}
|
|
149
|
+
type TemplateToken = TextToken | HoleToken;
|
|
150
|
+
interface MessageTemplate {
|
|
151
|
+
readonly raw: string;
|
|
152
|
+
readonly tokens: readonly TemplateToken[];
|
|
153
|
+
/** The holes in order of appearance — what positional arguments bind to. */
|
|
154
|
+
readonly holes: readonly HoleToken[];
|
|
155
|
+
/** All holes are numeric (`{0} {1}`), so arguments bind by index. */
|
|
156
|
+
readonly positional: boolean;
|
|
157
|
+
}
|
|
158
|
+
/** Parses a template, memoised by text. The cache is bounded; a flood of unique templates just costs a reparse. */
|
|
159
|
+
declare function parseTemplate(raw: string): MessageTemplate;
|
|
160
|
+
/**
|
|
161
|
+
* Serilog's event-type id: Jenkins one-at-a-time over the template's UTF-16
|
|
162
|
+
* code units, as eight hex digits — the same value Seq shows as `@i`, so
|
|
163
|
+
* "all events of this kind" queries match across both ecosystems.
|
|
164
|
+
*/
|
|
165
|
+
declare function templateHash(raw: string): string;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Rendering captured values and templates to text — shared by
|
|
169
|
+
* `renderMessage()`, the text / pretty formatters and CLEF's `@r`.
|
|
170
|
+
*
|
|
171
|
+
* Rules follow Serilog's: strings are quoted unless the hole says `:l`,
|
|
172
|
+
* structures print as `Type { Key: value }` (or JSON with `:j`), sequences
|
|
173
|
+
* as `[a, b]`, dates as ISO 8601. Numbers accept `.NET`-style `0.00` / `F2`
|
|
174
|
+
* / `N0` patterns, dates the `yyyy-MM-dd HH:mm:ss.fff zzz` family.
|
|
175
|
+
*/
|
|
176
|
+
|
|
177
|
+
/** Hooks for colouring (the pretty formatter); each receives text and returns styled text. */
|
|
178
|
+
interface ValueStyles {
|
|
179
|
+
string?: (text: string) => string;
|
|
180
|
+
number?: (text: string) => string;
|
|
181
|
+
boolean?: (text: string) => string;
|
|
182
|
+
null?: (text: string) => string;
|
|
183
|
+
name?: (text: string) => string;
|
|
184
|
+
punctuation?: (text: string) => string;
|
|
185
|
+
/** Raw hole text when nothing bound to it. */
|
|
186
|
+
missing?: (text: string) => string;
|
|
187
|
+
}
|
|
188
|
+
interface RenderOptions {
|
|
189
|
+
/** Strings print bare instead of quoted (`:l`). */
|
|
190
|
+
literal?: boolean;
|
|
191
|
+
/** Structures and sequences print as JSON (`:j`). */
|
|
192
|
+
json?: boolean;
|
|
193
|
+
/** Dates in text output print in UTC (default: local time). */
|
|
194
|
+
utc?: boolean;
|
|
195
|
+
styles?: ValueStyles;
|
|
196
|
+
}
|
|
197
|
+
/** Fills in identity functions so the renderer never has to branch on a missing style. */
|
|
198
|
+
declare function resolveStyles(styles: ValueStyles | undefined): Required<ValueStyles>;
|
|
199
|
+
declare function renderValue(value: unknown, format?: string, options?: RenderOptions): string;
|
|
200
|
+
/**
|
|
201
|
+
* JSON that never throws. Captured values are already JSON-safe (capture
|
|
202
|
+
* turns bigint, NaN and Infinity into numbers or strings; Dates have
|
|
203
|
+
* `toJSON`), so the fast path is a plain `JSON.stringify` — a replacer
|
|
204
|
+
* function would cost a call per key on every event. The replacer only
|
|
205
|
+
* runs if something un-captured (a raw bigint) slipped through.
|
|
206
|
+
*/
|
|
207
|
+
declare function toJson(value: unknown): string;
|
|
208
|
+
declare function jsonReplacer(this: unknown, _key: string, value: unknown): unknown;
|
|
209
|
+
/** `0.00`, `0.####`, `F2`, `N0`, `P1`, `D3`, `X` — the common .NET numeric formats; anything else prints the number as is. */
|
|
210
|
+
declare function formatNumber(value: number, format?: string): string;
|
|
211
|
+
declare function isoTimestamp(date: Date): string;
|
|
212
|
+
/**
|
|
213
|
+
* .NET-style date patterns: `yyyy MM dd HH hh mm ss fff tt zzz K`, quoted
|
|
214
|
+
* literals, plus `o` / `O` for ISO 8601. Local time unless `utc`.
|
|
215
|
+
*/
|
|
216
|
+
declare function formatDate(date: Date, pattern: string, utc?: boolean): string;
|
|
217
|
+
/**
|
|
218
|
+
* Renders a template against captured properties. Holes with no bound value
|
|
219
|
+
* print as written (`{Missing}`), Serilog's behaviour, so a typo is visible.
|
|
220
|
+
* `renderings`, when given, collects the text of every formatted hole — the
|
|
221
|
+
* CLEF `@r` array.
|
|
222
|
+
*/
|
|
223
|
+
declare function renderTemplate(template: MessageTemplate, properties: Record<string, unknown>, options?: RenderOptions, renderings?: string[]): string;
|
|
224
|
+
|
|
225
|
+
interface LogEventInit {
|
|
226
|
+
timestamp?: Date;
|
|
227
|
+
level: LogLevel;
|
|
228
|
+
template: MessageTemplate;
|
|
229
|
+
properties?: Record<string, unknown>;
|
|
230
|
+
error?: Error;
|
|
231
|
+
traceId?: string;
|
|
232
|
+
spanId?: string;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* One logged event: when, how severe, the template it was written with, the
|
|
236
|
+
* captured properties, and — separately from the properties, as in Serilog —
|
|
237
|
+
* the error and the trace/span ids.
|
|
238
|
+
*
|
|
239
|
+
* Sinks receive the same instance; enrichers mutate it through the
|
|
240
|
+
* `add*` methods so that every value goes through the logger's capture rules.
|
|
241
|
+
*/
|
|
242
|
+
declare class LogEvent {
|
|
243
|
+
#private;
|
|
244
|
+
readonly timestamp: Date;
|
|
245
|
+
readonly level: LogLevel;
|
|
246
|
+
readonly template: MessageTemplate;
|
|
247
|
+
readonly properties: Record<string, unknown>;
|
|
248
|
+
error: Error | undefined;
|
|
249
|
+
traceId: string | undefined;
|
|
250
|
+
spanId: string | undefined;
|
|
251
|
+
constructor(init: LogEventInit, destructuring: DestructuringOptions);
|
|
252
|
+
/** The template text, e.g. `"User {UserId} logged in"`. */
|
|
253
|
+
get messageTemplate(): string;
|
|
254
|
+
/** Serilog's `SourceContext` — set by `logger.forSource()`. */
|
|
255
|
+
get sourceContext(): string | undefined;
|
|
256
|
+
/** Eight hex digits identifying the template (Seq's `@i`). */
|
|
257
|
+
get eventId(): string;
|
|
258
|
+
/** The error as a structure (name, message, stack, own properties, cause chain), captured once. */
|
|
259
|
+
get errorProperties(): CapturedError | undefined;
|
|
260
|
+
/** Captures and adds `value` under `name` unless the event already has it — the rule enrichers follow. */
|
|
261
|
+
addPropertyIfAbsent(name: string, value: unknown, destructure?: boolean): void;
|
|
262
|
+
/** Captures and adds `value` under `name`, replacing any existing value. */
|
|
263
|
+
addOrUpdateProperty(name: string, value: unknown, destructure?: boolean): void;
|
|
264
|
+
removeProperty(name: string): void;
|
|
265
|
+
hasProperty(name: string): boolean;
|
|
266
|
+
/** The template rendered with this event's properties. */
|
|
267
|
+
renderMessage(options?: RenderOptions): string;
|
|
268
|
+
/** Properties that are not holes in the template — the "extra" context, in Serilog's `{Properties}` sense. */
|
|
269
|
+
extraProperties(): Record<string, unknown>;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* An enricher adds properties to every event that passes through a logger
|
|
274
|
+
* (Serilog's `ILogEventEnricher`). Use `addPropertyIfAbsent` so that a
|
|
275
|
+
* value written in the message, or bound closer to the call, wins.
|
|
276
|
+
*/
|
|
277
|
+
type Enricher = (event: LogEvent) => void;
|
|
278
|
+
/** A fixed property on every event: `withProperty('Application', 'shop')`. */
|
|
279
|
+
declare function withProperty(name: string, value: unknown, destructure?: boolean): Enricher;
|
|
280
|
+
/** Several fixed properties at once. */
|
|
281
|
+
declare function withProperties(properties: Record<string, unknown>, destructure?: boolean): Enricher;
|
|
282
|
+
/** A property computed per event — `withComputed('Memory', () => process.memoryUsage().rss)`. */
|
|
283
|
+
declare function withComputed(name: string, compute: (event: LogEvent) => unknown, destructure?: boolean): Enricher;
|
|
284
|
+
/**
|
|
285
|
+
* Copies the ambient `LogContext` onto the event — Serilog's
|
|
286
|
+
* `Enrich.FromLogContext()`. `createLogger` includes it unless told not to.
|
|
287
|
+
* `traceId` / `spanId` in the context become the event's trace fields.
|
|
288
|
+
*/
|
|
289
|
+
declare function fromLogContext(): Enricher;
|
|
290
|
+
/** `Environment` from `NODE_ENV` (or the value given). No-op where there is no `process.env`. */
|
|
291
|
+
declare function withEnvironment(name?: string): Enricher;
|
|
292
|
+
interface TraceContext {
|
|
293
|
+
traceId?: string;
|
|
294
|
+
spanId?: string;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Sets the event's trace and span ids from a getter — wire it to
|
|
298
|
+
* `trace.getActiveSpan()?.spanContext()` from `@opentelemetry/api`, or to
|
|
299
|
+
* whatever carries your correlation ids.
|
|
300
|
+
*/
|
|
301
|
+
declare function withTraceContext(get: () => TraceContext | undefined | null): Enricher;
|
|
302
|
+
|
|
303
|
+
/** `true` keeps the event. Filters run after enrichment, before the sinks. */
|
|
304
|
+
type Filter = (event: LogEvent) => boolean;
|
|
305
|
+
/** Serilog's `Filter.ByExcluding`: drop events the predicate matches. */
|
|
306
|
+
declare function byExcluding(predicate: (event: LogEvent) => boolean): Filter;
|
|
307
|
+
/** Serilog's `Filter.ByIncludingOnly`: keep only events the predicate matches. */
|
|
308
|
+
declare function byIncludingOnly(predicate: (event: LogEvent) => boolean): Filter;
|
|
309
|
+
/** Serilog's `Matching` helpers — predicates for the two filters above and for `conditional()` sinks. */
|
|
310
|
+
declare const Matching: {
|
|
311
|
+
/** Events whose `SourceContext` is `source` or starts with `source.`. */
|
|
312
|
+
fromSource(source: string): (event: LogEvent) => boolean;
|
|
313
|
+
/** Events that carry `name` — optionally with a value the predicate accepts. */
|
|
314
|
+
withProperty<T = unknown>(name: string, predicate?: (value: T) => boolean): (event: LogEvent) => boolean;
|
|
315
|
+
/** Events written with exactly this template text. */
|
|
316
|
+
withTemplate(template: string): (event: LogEvent) => boolean;
|
|
317
|
+
/** Events whose rendered message matches the pattern. */
|
|
318
|
+
messageMatches(pattern: RegExp): (event: LogEvent) => boolean;
|
|
319
|
+
};
|
|
320
|
+
/** Keeps a fraction of matching events — `sampled(0.1, Matching.fromSource('http'))` keeps one in ten request logs. */
|
|
321
|
+
declare function sampled(rate: number, predicate?: (event: LogEvent) => boolean, random?: () => number): Filter;
|
|
322
|
+
/**
|
|
323
|
+
* Lets at most `max` matching events through per `windowMs`; the rest are
|
|
324
|
+
* dropped. For the error that fires ten thousand times a second.
|
|
325
|
+
*/
|
|
326
|
+
declare function rateLimited(max: number, windowMs: number, predicate?: (event: LogEvent) => boolean, now?: () => number): Filter;
|
|
327
|
+
|
|
328
|
+
/** Turns an event into one line (or block) of text. Sinks add the newline. */
|
|
329
|
+
type Formatter = (event: LogEvent) => string;
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Serilog's output templates: `"{Timestamp:HH:mm:ss} [{Level:u3}] {SourceContext} {Message:lj}{NewLine}{Exception}"`.
|
|
333
|
+
*
|
|
334
|
+
* The template is parsed with the message-template parser — it IS one —
|
|
335
|
+
* and the well-known holes are filled from the event's own fields; any other
|
|
336
|
+
* name reads a property. `{Properties}` prints every property not already
|
|
337
|
+
* used by the message or the output template.
|
|
338
|
+
*/
|
|
339
|
+
|
|
340
|
+
declare const DEFAULT_OUTPUT_TEMPLATE = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}";
|
|
341
|
+
interface TextFormatterOptions {
|
|
342
|
+
outputTemplate?: string;
|
|
343
|
+
/** Timestamps in UTC instead of local time. */
|
|
344
|
+
utc?: boolean;
|
|
345
|
+
/** Colour hooks for the message's values (used by the pretty formatter). */
|
|
346
|
+
styles?: ValueStyles;
|
|
347
|
+
/** Hooks for the structural holes. */
|
|
348
|
+
tokenStyles?: Partial<Record<'Timestamp' | 'Level' | 'SourceContext' | 'Exception' | 'Properties' | 'Message', (text: string, event: LogEvent) => string>>;
|
|
349
|
+
}
|
|
350
|
+
declare function formatLevel(level: LogEvent['level'], format?: string): string;
|
|
351
|
+
/** The error as text: stack (or name + message), then each cause indented — Node's own "caused by" shape. */
|
|
352
|
+
declare function formatError(error: Error | undefined, indent?: string): string;
|
|
353
|
+
declare function textFormatter(options?: TextFormatterOptions): Formatter;
|
|
354
|
+
|
|
355
|
+
declare const ansi: {
|
|
356
|
+
bold: (text: string) => string;
|
|
357
|
+
dim: (text: string) => string;
|
|
358
|
+
italic: (text: string) => string;
|
|
359
|
+
underline: (text: string) => string;
|
|
360
|
+
red: (text: string) => string;
|
|
361
|
+
green: (text: string) => string;
|
|
362
|
+
yellow: (text: string) => string;
|
|
363
|
+
blue: (text: string) => string;
|
|
364
|
+
magenta: (text: string) => string;
|
|
365
|
+
cyan: (text: string) => string;
|
|
366
|
+
white: (text: string) => string;
|
|
367
|
+
gray: (text: string) => string;
|
|
368
|
+
bgRed: (text: string) => string;
|
|
369
|
+
};
|
|
370
|
+
interface PrettyFormatterOptions {
|
|
371
|
+
colors?: boolean;
|
|
372
|
+
/** Timestamp pattern; default `HH:mm:ss.fff`. `false` hides it. */
|
|
373
|
+
timestamp?: string | false;
|
|
374
|
+
utc?: boolean;
|
|
375
|
+
/** Show properties that are not part of the message, as `key=value`. Default true. */
|
|
376
|
+
extras?: boolean;
|
|
377
|
+
/** Show the source context. Default true. */
|
|
378
|
+
source?: boolean;
|
|
379
|
+
}
|
|
380
|
+
/** Detects colour support the way most CLIs do. Exported so sinks can share the decision. */
|
|
381
|
+
declare function detectColors(stream?: {
|
|
382
|
+
isTTY?: boolean;
|
|
383
|
+
}): boolean;
|
|
384
|
+
declare function prettyFormatter(options?: PrettyFormatterOptions): Formatter;
|
|
385
|
+
|
|
386
|
+
interface JsonFormatterOptions {
|
|
387
|
+
/** Rename the reified keys, e.g. `{ timestamp: 'time', message: 'msg' }` for pino-shaped output. */
|
|
388
|
+
keys?: Partial<Record<'timestamp' | 'level' | 'message' | 'template' | 'source' | 'error' | 'traceId' | 'spanId' | 'eventId', string>>;
|
|
389
|
+
/** `'name'` → `"info"`, `'serilog'` → `"Information"`, `'upper'` → `"INFO"`, `'number'` → pino's 30. */
|
|
390
|
+
levelFormat?: 'name' | 'serilog' | 'upper' | 'number';
|
|
391
|
+
/** Include the rendered message (default true) and / or the template (default true). */
|
|
392
|
+
message?: boolean;
|
|
393
|
+
template?: boolean;
|
|
394
|
+
/** Include the template hash as `eventId` (default false). */
|
|
395
|
+
eventId?: boolean;
|
|
396
|
+
/** Timestamp as ISO 8601 (default) or epoch milliseconds. */
|
|
397
|
+
timestampFormat?: 'iso' | 'epoch';
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* The line is assembled from fragments rather than built as an object and
|
|
401
|
+
* stringified whole: the reified keys are constant strings, the level's
|
|
402
|
+
* fragment is precomputed, the template's JSON is cached per template, and
|
|
403
|
+
* only the message and the properties are escaped per event.
|
|
404
|
+
*/
|
|
405
|
+
declare function jsonFormatter(options?: JsonFormatterOptions): Formatter;
|
|
406
|
+
|
|
407
|
+
declare const CLEF_MEDIA_TYPE = "application/vnd.serilog.clef";
|
|
408
|
+
interface ClefFormatterOptions {
|
|
409
|
+
/** Also write the rendered message as `@m` (Serilog's "rendered compact" variant). Default false. */
|
|
410
|
+
renderMessage?: boolean;
|
|
411
|
+
}
|
|
412
|
+
declare function clefFormatter(options?: ClefFormatterOptions): Formatter;
|
|
413
|
+
|
|
414
|
+
type FormatName = 'pretty' | 'json' | 'clef' | 'text';
|
|
415
|
+
/** `'json'` / `'clef'` / `'text'` / `'pretty'` by name, or a formatter function as given. */
|
|
416
|
+
declare function resolveFormatter(format: FormatName | Formatter | undefined, defaults?: {
|
|
417
|
+
outputTemplate?: string;
|
|
418
|
+
colors?: boolean;
|
|
419
|
+
utc?: boolean;
|
|
420
|
+
}, fallback?: FormatName): Formatter;
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Where events go. `emit` is synchronous and must not throw for ordinary
|
|
424
|
+
* failures (write to `selfLog` instead); a sink that buffers implements
|
|
425
|
+
* `flush` and `close` so `logger.close()` can drain it before the process
|
|
426
|
+
* ends. A `Logger` is itself a sink — that is how sub-loggers work.
|
|
427
|
+
*/
|
|
428
|
+
interface Sink {
|
|
429
|
+
emit(event: LogEvent): void;
|
|
430
|
+
flush?(): Promise<void> | void;
|
|
431
|
+
close?(): Promise<void> | void;
|
|
432
|
+
/** Events below this level are not handed to the sink (Serilog's `restrictedToMinimumLevel`). */
|
|
433
|
+
restrictedToMinimumLevel?: LevelOrSwitch;
|
|
434
|
+
/** An audit sink's failure propagates to the caller instead of going to selfLog (Serilog's `AuditTo`). */
|
|
435
|
+
audit?: boolean;
|
|
436
|
+
/** For selfLog messages. */
|
|
437
|
+
name?: string;
|
|
438
|
+
}
|
|
439
|
+
interface SinkOptions {
|
|
440
|
+
restrictedToMinimumLevel?: LevelOrSwitch;
|
|
441
|
+
audit?: boolean;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
interface ConsoleSinkOptions extends SinkOptions {
|
|
445
|
+
/**
|
|
446
|
+
* `'pretty'` for people, `'json'` for machines, `'clef'` for Seq, `'text'` for
|
|
447
|
+
* a Serilog output template — or a formatter function. Default: `'pretty'` on
|
|
448
|
+
* a terminal and in browsers, `'json'` otherwise (a pipe, a container, Vercel).
|
|
449
|
+
*/
|
|
450
|
+
format?: FormatName | Formatter;
|
|
451
|
+
outputTemplate?: string;
|
|
452
|
+
colors?: boolean;
|
|
453
|
+
utc?: boolean;
|
|
454
|
+
/** Events at or above this level go to stderr (Serilog's `standardErrorFromLevel`). Default: everything to stdout. */
|
|
455
|
+
stderrFrom?: LogLevel | string;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* stdout / stderr in Node, Bun and Deno. Elsewhere the console: in a real
|
|
459
|
+
* browser the pretty format hands it objects so they stay expandable; on an
|
|
460
|
+
* edge runtime or in a worker (no `document`) the default is JSON lines,
|
|
461
|
+
* which is what the platform's log collector expects to parse.
|
|
462
|
+
*/
|
|
463
|
+
declare function consoleSink(options?: ConsoleSinkOptions): Sink;
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* The batching core behind every network sink: events queue up, go out in
|
|
467
|
+
* batches on a timer or when the batch fills, retry with backoff on failure,
|
|
468
|
+
* and are dropped — with a selfLog note — rather than grow without bound.
|
|
469
|
+
* `flush()` sends what is queued and waits; `close()` flushes and stops.
|
|
470
|
+
*/
|
|
471
|
+
|
|
472
|
+
interface BatchingOptions extends SinkOptions {
|
|
473
|
+
/** Send when this many events are queued. Default 100. */
|
|
474
|
+
batchSize?: number;
|
|
475
|
+
/** Send at least this often (ms) while events are queued. Default 2000. */
|
|
476
|
+
flushInterval?: number;
|
|
477
|
+
/** Events kept while the network is down; beyond it the oldest are dropped. Default 10 000. */
|
|
478
|
+
maxQueue?: number;
|
|
479
|
+
/** Attempts per batch (first try included). Default 3. */
|
|
480
|
+
retries?: number;
|
|
481
|
+
/** Base delay between attempts (ms), doubled each time. Default 500. */
|
|
482
|
+
retryDelay?: number;
|
|
483
|
+
/** Called when a batch is given up on. */
|
|
484
|
+
onError?: (error: unknown, events: LogEvent[]) => void;
|
|
485
|
+
name?: string;
|
|
486
|
+
}
|
|
487
|
+
interface BatchingSink extends Sink {
|
|
488
|
+
/** Events waiting to be sent. */
|
|
489
|
+
readonly queued: number;
|
|
490
|
+
flush(): Promise<void>;
|
|
491
|
+
close(): Promise<void>;
|
|
492
|
+
}
|
|
493
|
+
declare function batchingSink(send: (events: LogEvent[]) => Promise<void>, options?: BatchingOptions): BatchingSink;
|
|
494
|
+
|
|
495
|
+
type FetchLike = (url: string, init: {
|
|
496
|
+
method: string;
|
|
497
|
+
headers: Record<string, string>;
|
|
498
|
+
body: string;
|
|
499
|
+
signal?: AbortSignal;
|
|
500
|
+
keepalive?: boolean;
|
|
501
|
+
}) => Promise<{
|
|
502
|
+
ok: boolean;
|
|
503
|
+
status: number;
|
|
504
|
+
text(): Promise<string>;
|
|
505
|
+
}>;
|
|
506
|
+
interface HttpSinkOptions extends BatchingOptions {
|
|
507
|
+
url: string;
|
|
508
|
+
headers?: Record<string, string> | (() => Record<string, string>);
|
|
509
|
+
/**
|
|
510
|
+
* How a batch becomes a body: `'ndjson'` (one JSON event per line — Loki,
|
|
511
|
+
* Splunk HEC, Datadog, most collectors), `'array'` (a JSON array), `'clef'`
|
|
512
|
+
* (newline-delimited CLEF, Seq), or your own function.
|
|
513
|
+
*/
|
|
514
|
+
body?: 'ndjson' | 'array' | 'clef' | ((events: LogEvent[]) => string);
|
|
515
|
+
/** Formatter for each event in `ndjson` / `array` mode. Default: the JSON formatter. */
|
|
516
|
+
formatter?: Formatter;
|
|
517
|
+
contentType?: string;
|
|
518
|
+
/** Request timeout in ms. Default 10 000. */
|
|
519
|
+
timeout?: number;
|
|
520
|
+
/** Supplied for tests and exotic runtimes; defaults to `globalThis.fetch`. */
|
|
521
|
+
fetch?: FetchLike;
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* POSTs batches of events to any HTTP endpoint. In a browser the request is
|
|
525
|
+
* sent with `keepalive`, and the queue is flushed on `pagehide`, so the last
|
|
526
|
+
* events of a session still leave.
|
|
527
|
+
*/
|
|
528
|
+
declare function httpSink(options: HttpSinkOptions): BatchingSink;
|
|
529
|
+
interface SeqSinkOptions extends Omit<HttpSinkOptions, 'url' | 'body' | 'formatter' | 'contentType'> {
|
|
530
|
+
/** e.g. `http://localhost:5341` */
|
|
531
|
+
serverUrl: string;
|
|
532
|
+
apiKey?: string;
|
|
533
|
+
}
|
|
534
|
+
/** Seq (https://datalust.co/seq): CLEF over HTTP to `/ingest/clef`, with the API key header. */
|
|
535
|
+
declare function seqSink(options: SeqSinkOptions): BatchingSink;
|
|
536
|
+
|
|
537
|
+
/** The simplest sink: a function per event. */
|
|
538
|
+
declare function callbackSink(fn: (event: LogEvent) => void, options?: SinkOptions): Sink;
|
|
539
|
+
interface MemorySink extends Sink {
|
|
540
|
+
readonly events: LogEvent[];
|
|
541
|
+
clear(): void;
|
|
542
|
+
/** The rendered messages, for assertions. */
|
|
543
|
+
messages(): string[];
|
|
544
|
+
}
|
|
545
|
+
/** Keeps events in an array — for tests, and for the "last N events" page every ops team ends up wanting. */
|
|
546
|
+
declare function memorySink(options?: SinkOptions & {
|
|
547
|
+
capacity?: number;
|
|
548
|
+
}): MemorySink;
|
|
549
|
+
interface StreamLike {
|
|
550
|
+
write(chunk: string): boolean | void;
|
|
551
|
+
isTTY?: boolean;
|
|
552
|
+
once?(event: 'drain', listener: () => void): unknown;
|
|
553
|
+
}
|
|
554
|
+
interface StreamSinkOptions extends SinkOptions {
|
|
555
|
+
format?: FormatName | Formatter;
|
|
556
|
+
outputTemplate?: string;
|
|
557
|
+
colors?: boolean;
|
|
558
|
+
utc?: boolean;
|
|
559
|
+
}
|
|
560
|
+
/** Writes formatted lines to anything with `write(string)` — a Node stream, a socket, a custom transport. */
|
|
561
|
+
declare function streamSink(stream: StreamLike, options?: StreamSinkOptions): Sink;
|
|
562
|
+
|
|
563
|
+
interface LoggerOptions {
|
|
564
|
+
/** Default `'info'`, or `LOGIT_LEVEL` from the environment when set. A `LevelSwitch` makes it changeable at runtime. */
|
|
565
|
+
minimumLevel?: LevelOrSwitch;
|
|
566
|
+
/**
|
|
567
|
+
* Per-source levels — Serilog's `MinimumLevel.Override`. Keys are
|
|
568
|
+
* `SourceContext` prefixes on dot boundaries (`'app.db'` covers
|
|
569
|
+
* `app.db.query`); the longest match wins.
|
|
570
|
+
*/
|
|
571
|
+
overrides?: Record<string, LevelOrSwitch>;
|
|
572
|
+
/** Where events go (`writeTo`). A `Logger` is a valid sink. */
|
|
573
|
+
sinks?: Sink[];
|
|
574
|
+
/** Serilog's `AuditTo`: sinks whose failures propagate to the caller. */
|
|
575
|
+
auditSinks?: Sink[];
|
|
576
|
+
enrichers?: Enricher[];
|
|
577
|
+
filters?: Filter[];
|
|
578
|
+
destructuring?: Partial<DestructuringOptions>;
|
|
579
|
+
/** Fixed properties on every event — shorthand for `withProperties()`. */
|
|
580
|
+
properties?: Record<string, unknown>;
|
|
581
|
+
/** Read the ambient `LogContext` onto every event. Default true. */
|
|
582
|
+
logContext?: boolean;
|
|
583
|
+
/** Where a non-audit sink's failure is reported. Default: `selfLog`. */
|
|
584
|
+
onSinkError?: (error: unknown, sink: Sink, event: LogEvent) => void;
|
|
585
|
+
}
|
|
586
|
+
interface Override {
|
|
587
|
+
prefix: string;
|
|
588
|
+
level: LevelOrSwitch;
|
|
589
|
+
}
|
|
590
|
+
interface Pipeline {
|
|
591
|
+
minimumLevel: LevelOrSwitch;
|
|
592
|
+
overrides: Override[];
|
|
593
|
+
sinks: Sink[];
|
|
594
|
+
enrichers: Enricher[];
|
|
595
|
+
filters: Filter[];
|
|
596
|
+
destructuring: DestructuringOptions;
|
|
597
|
+
onSinkError?: LoggerOptions['onSinkError'];
|
|
598
|
+
}
|
|
599
|
+
/** Loggers read their pipeline through a ref, so `configure()` can swap the global one under every child. */
|
|
600
|
+
interface PipelineRef {
|
|
601
|
+
current: Pipeline;
|
|
602
|
+
}
|
|
603
|
+
type LogArgs = unknown[];
|
|
604
|
+
interface LogMethod {
|
|
605
|
+
(template: string, ...args: unknown[]): void;
|
|
606
|
+
(error: Error, template?: string, ...args: unknown[]): void;
|
|
607
|
+
(properties: Record<string, unknown>, template?: string, ...args: unknown[]): void;
|
|
608
|
+
}
|
|
609
|
+
interface OperationOptions {
|
|
610
|
+
/** Level of the completion event. Default `'info'`. */
|
|
611
|
+
completeLevel?: LogLevel;
|
|
612
|
+
/** Level of the abandonment event. Default `'warn'`. */
|
|
613
|
+
abandonLevel?: LogLevel;
|
|
614
|
+
/** Completions slower than this (ms) log at `warn` instead. */
|
|
615
|
+
warnAfter?: number;
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* A timed operation (SerilogTimings): begin it, do the work, `complete()`
|
|
619
|
+
* or `abandon()` — one event with `Outcome` and `Elapsed`. Disposing an
|
|
620
|
+
* unfinished operation abandons it.
|
|
621
|
+
*/
|
|
622
|
+
declare class Operation {
|
|
623
|
+
#private;
|
|
624
|
+
constructor(logger: Logger, template: string, args: unknown[], options?: OperationOptions);
|
|
625
|
+
/** Milliseconds since the operation began. */
|
|
626
|
+
get elapsed(): number;
|
|
627
|
+
/** Adds a property to the completion event. */
|
|
628
|
+
enrich(name: string, value: unknown, destructure?: boolean): this;
|
|
629
|
+
complete(): void;
|
|
630
|
+
complete(name: string, value: unknown): void;
|
|
631
|
+
abandon(error?: Error): void;
|
|
632
|
+
/** Ends the operation without logging anything. */
|
|
633
|
+
cancel(): void;
|
|
634
|
+
[Symbol.dispose](): void;
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* The logger. Immutable: `forContext` / `forSource` return a new logger
|
|
638
|
+
* bound to extra properties, sharing the pipeline. Also a `Sink`, so a
|
|
639
|
+
* logger can be written to by another (sub-loggers).
|
|
640
|
+
*/
|
|
641
|
+
declare class Logger implements Sink {
|
|
642
|
+
#private;
|
|
643
|
+
/** @internal */
|
|
644
|
+
constructor(ref: PipelineRef, context?: Record<string, unknown> | null, source?: string);
|
|
645
|
+
readonly name = "logger";
|
|
646
|
+
/** The `SourceContext` this logger is bound to, if any. */
|
|
647
|
+
get source(): string | undefined;
|
|
648
|
+
/** The current minimum level for this logger's source. */
|
|
649
|
+
get minimumLevel(): LogLevel;
|
|
650
|
+
/** Cheap check before building anything expensive to log. */
|
|
651
|
+
isEnabled(level: LogLevel): boolean;
|
|
652
|
+
verbose: LogMethod;
|
|
653
|
+
debug: LogMethod;
|
|
654
|
+
info: LogMethod;
|
|
655
|
+
warn: LogMethod;
|
|
656
|
+
error: LogMethod;
|
|
657
|
+
fatal: LogMethod;
|
|
658
|
+
/**
|
|
659
|
+
* Writes an event at `level`. Argument shapes:
|
|
660
|
+
* `(template, ...args)`
|
|
661
|
+
* `(error, template?, ...args)`
|
|
662
|
+
* `(properties, template?, ...args)` — one-off properties on this event
|
|
663
|
+
*/
|
|
664
|
+
write(level: LogLevel, ...args: LogArgs): void;
|
|
665
|
+
/** Sink entry point: an event from another logger, re-dispatched through this one's level, context, enrichers, filters and sinks. */
|
|
666
|
+
emit(event: LogEvent): void;
|
|
667
|
+
/** A logger bound to `name = value` (Serilog's `ForContext`), or to several properties at once. */
|
|
668
|
+
forContext(name: string, value: unknown, destructure?: boolean): Logger;
|
|
669
|
+
forContext(properties: Record<string, unknown>, destructure?: boolean): Logger;
|
|
670
|
+
/** A logger whose events carry `SourceContext` — the name level overrides match on. Dotted names nest: `'app.db'`. */
|
|
671
|
+
forSource(source: string): Logger;
|
|
672
|
+
/** pino / bunyan spelling of `forContext`. */
|
|
673
|
+
child(properties: Record<string, unknown>, destructure?: boolean): Logger;
|
|
674
|
+
/** Starts a timed operation; `complete()` / `abandon()` log one event with `Outcome` and `Elapsed`. */
|
|
675
|
+
beginOperation(template: string, ...args: unknown[]): Operation;
|
|
676
|
+
/** `beginOperation` with options (levels, `warnAfter`). */
|
|
677
|
+
operation(options: OperationOptions, template: string, ...args: unknown[]): Operation;
|
|
678
|
+
/**
|
|
679
|
+
* Runs `fn` as a timed operation: completes when it returns (or its
|
|
680
|
+
* promise resolves), abandons with the error when it throws (or rejects),
|
|
681
|
+
* then rethrows.
|
|
682
|
+
*/
|
|
683
|
+
timed<R>(template: string, fn: (operation: Operation) => R, ...args: unknown[]): R;
|
|
684
|
+
/** Waits for every sink that buffers to send what it holds. */
|
|
685
|
+
flush(): Promise<void>;
|
|
686
|
+
/** Flushes, then closes the sinks — call once, before the process exits (Serilog's `CloseAndFlush`). */
|
|
687
|
+
close(): Promise<void>;
|
|
688
|
+
/** The sinks this logger writes to. */
|
|
689
|
+
get sinks(): readonly Sink[];
|
|
690
|
+
/** @internal — swaps the pipeline for every logger sharing this ref. */
|
|
691
|
+
_replace(options: LoggerOptions): void;
|
|
692
|
+
}
|
|
693
|
+
/** Creates an independent logger. With no options: `info` and above, to the console (pretty on a terminal, JSON elsewhere). */
|
|
694
|
+
declare function createLogger(options?: LoggerOptions): Logger;
|
|
695
|
+
/**
|
|
696
|
+
* Serilog's fluent `LoggerConfiguration`, for muscle memory:
|
|
697
|
+
*
|
|
698
|
+
* const log = new LoggerConfiguration()
|
|
699
|
+
* .minimumLevel.debug()
|
|
700
|
+
* .minimumLevel.override('next', 'warn')
|
|
701
|
+
* .enrich.withProperty('Application', 'shop')
|
|
702
|
+
* .writeTo.console()
|
|
703
|
+
* .createLogger();
|
|
704
|
+
*/
|
|
705
|
+
declare class LoggerConfiguration {
|
|
706
|
+
#private;
|
|
707
|
+
readonly minimumLevel: {
|
|
708
|
+
verbose: () => LoggerConfiguration;
|
|
709
|
+
debug: () => LoggerConfiguration;
|
|
710
|
+
info: () => LoggerConfiguration;
|
|
711
|
+
information: () => LoggerConfiguration;
|
|
712
|
+
warn: () => LoggerConfiguration;
|
|
713
|
+
warning: () => LoggerConfiguration;
|
|
714
|
+
error: () => LoggerConfiguration;
|
|
715
|
+
fatal: () => LoggerConfiguration;
|
|
716
|
+
is: (level: LevelOrSwitch) => LoggerConfiguration;
|
|
717
|
+
controlledBy: (levelSwitch: LevelSwitch) => LoggerConfiguration;
|
|
718
|
+
override: (source: string, level: LevelOrSwitch) => LoggerConfiguration;
|
|
719
|
+
};
|
|
720
|
+
readonly writeTo: {
|
|
721
|
+
sink: (...sinks: Sink[]) => LoggerConfiguration;
|
|
722
|
+
console: (options?: ConsoleSinkOptions) => LoggerConfiguration;
|
|
723
|
+
stream: (stream: StreamLike, options?: StreamSinkOptions) => LoggerConfiguration;
|
|
724
|
+
http: (options: HttpSinkOptions) => LoggerConfiguration;
|
|
725
|
+
seq: (options: SeqSinkOptions) => LoggerConfiguration;
|
|
726
|
+
/** A sub-logger with its own filters, enrichers and sinks (Serilog's `WriteTo.Logger`). */
|
|
727
|
+
logger: (configure: (configuration: LoggerConfiguration) => void, restrictedToMinimumLevel?: LevelOrSwitch) => LoggerConfiguration;
|
|
728
|
+
};
|
|
729
|
+
readonly auditTo: {
|
|
730
|
+
sink: (...sinks: Sink[]) => LoggerConfiguration;
|
|
731
|
+
};
|
|
732
|
+
readonly enrich: {
|
|
733
|
+
with: (...enrichers: Enricher[]) => LoggerConfiguration;
|
|
734
|
+
fromLogContext: () => LoggerConfiguration;
|
|
735
|
+
withProperty: (name: string, value: unknown, destructure?: boolean) => LoggerConfiguration;
|
|
736
|
+
withProperties: (properties: Record<string, unknown>, destructure?: boolean) => LoggerConfiguration;
|
|
737
|
+
};
|
|
738
|
+
readonly filter: {
|
|
739
|
+
with: (...filters: Filter[]) => LoggerConfiguration;
|
|
740
|
+
byExcluding: (predicate: (event: LogEvent) => boolean) => LoggerConfiguration;
|
|
741
|
+
byIncludingOnly: (predicate: (event: LogEvent) => boolean) => LoggerConfiguration;
|
|
742
|
+
};
|
|
743
|
+
readonly destructure: {
|
|
744
|
+
toMaximumDepth: (depth: number) => LoggerConfiguration;
|
|
745
|
+
toMaximumStringLength: (length: number) => LoggerConfiguration;
|
|
746
|
+
toMaximumCollectionCount: (count: number) => LoggerConfiguration;
|
|
747
|
+
with: (...policies: DestructuringPolicy[]) => LoggerConfiguration;
|
|
748
|
+
byTransforming: <T extends object>(type: abstract new (...args: never[]) => T, transform: (value: T) => unknown) => LoggerConfiguration;
|
|
749
|
+
/** Keys (or dotted paths) whose values are replaced by `[Redacted]`. */
|
|
750
|
+
redact: (...keys: string[]) => LoggerConfiguration;
|
|
751
|
+
};
|
|
752
|
+
readonly readFrom: {
|
|
753
|
+
/** `LOGIT_LEVEL` and `LOGIT_OVERRIDES` from the environment (they are read by default; this makes it explicit). */
|
|
754
|
+
env: () => LoggerConfiguration;
|
|
755
|
+
};
|
|
756
|
+
/** Disables the automatic `LogContext` enricher. */
|
|
757
|
+
withoutLogContext(): LoggerConfiguration;
|
|
758
|
+
/** The options as a plain object, for `createLogger()` or `configure()`. */
|
|
759
|
+
toOptions(): LoggerOptions;
|
|
760
|
+
createLogger(): Logger;
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* The default logger: `import { log } from '@unhingged/logit'` and go.
|
|
764
|
+
* Until `configure()` is called it writes `info` and above to the console —
|
|
765
|
+
* pretty on a terminal, JSON in a container or on Vercel. Every logger made
|
|
766
|
+
* from it (`log.forSource(...)`) follows a later `configure()`.
|
|
767
|
+
*/
|
|
768
|
+
declare const log: Logger;
|
|
769
|
+
/** Reconfigures the global `log` (and every logger derived from it) in place. Returns it. */
|
|
770
|
+
declare function configure(options?: LoggerOptions | LoggerConfiguration): Logger;
|
|
771
|
+
/** Flushes and closes the global logger's sinks — Serilog's `Log.CloseAndFlush()`. */
|
|
772
|
+
declare function closeAndFlush(): Promise<void>;
|
|
773
|
+
|
|
774
|
+
/**
|
|
775
|
+
* Ambient properties — Serilog's `LogContext`. Everything logged inside
|
|
776
|
+
* `LogContext.run({ requestId }, fn)` carries `requestId`, however deep the
|
|
777
|
+
* call stack and across `await`s, because the frames live in an
|
|
778
|
+
* `AsyncLocalStorage` when one is available (Node, Bun, Deno, Next.js
|
|
779
|
+
* middleware and the edge runtime). Where there is none (a browser) the
|
|
780
|
+
* frames fall back to a plain stack, which is right for synchronous code.
|
|
781
|
+
*
|
|
782
|
+
* `push()` is the no-callback form, for `using`:
|
|
783
|
+
*
|
|
784
|
+
* using _ = LogContext.push({ userId });
|
|
785
|
+
*/
|
|
786
|
+
interface ContextFrame {
|
|
787
|
+
readonly properties: Readonly<Record<string, unknown>>;
|
|
788
|
+
readonly parent: ContextFrame | null;
|
|
789
|
+
/** Serilog's `IDiagnosticContext`: values collected during a request for its completion event. */
|
|
790
|
+
readonly diagnostics?: Map<string, unknown>;
|
|
791
|
+
}
|
|
792
|
+
/** The subset of `AsyncLocalStorage` we need — structural, so any implementation (or a test double) fits. */
|
|
793
|
+
interface ContextStore {
|
|
794
|
+
getStore(): ContextFrame | undefined;
|
|
795
|
+
run<R>(frame: ContextFrame | undefined, fn: () => R): R;
|
|
796
|
+
enterWith?(frame: ContextFrame | undefined): void;
|
|
797
|
+
}
|
|
798
|
+
interface ContextHandle {
|
|
799
|
+
/** Restores the previous frame. Calling it twice is harmless. */
|
|
800
|
+
dispose(): void;
|
|
801
|
+
[Symbol.dispose](): void;
|
|
802
|
+
}
|
|
803
|
+
declare const LogContext: {
|
|
804
|
+
/**
|
|
805
|
+
* Runs `fn` with `properties` added to the ambient context. Async
|
|
806
|
+
* functions are followed through every `await` when an
|
|
807
|
+
* AsyncLocalStorage-backed store is active.
|
|
808
|
+
*/
|
|
809
|
+
run<R>(properties: Record<string, unknown>, fn: () => R): R;
|
|
810
|
+
/**
|
|
811
|
+
* Pushes properties onto the ambient context until the handle is disposed.
|
|
812
|
+
* Prefer `run()` for async code; `push()` relies on `enterWith`, which
|
|
813
|
+
* binds the rest of the *current* async scope.
|
|
814
|
+
*/
|
|
815
|
+
push(properties: Record<string, unknown>): ContextHandle;
|
|
816
|
+
/** The merged ambient properties, innermost frame winning. */
|
|
817
|
+
current(): Record<string, unknown>;
|
|
818
|
+
/** The innermost frame, for enrichers that want to walk it themselves. */
|
|
819
|
+
frame(): ContextFrame | undefined;
|
|
820
|
+
/**
|
|
821
|
+
* Starts a request scope: ambient `properties` plus a fresh diagnostic
|
|
822
|
+
* bag that `diagnosticContext.set()` writes to and the request-completion
|
|
823
|
+
* event reads. Used by the Next.js and Express integrations.
|
|
824
|
+
*/
|
|
825
|
+
runScope<R>(properties: Record<string, unknown>, fn: (diagnostics: Map<string, unknown>) => R): R;
|
|
826
|
+
/** Replaces the backing store — `new AsyncLocalStorage()` on runtimes we cannot detect. */
|
|
827
|
+
use(next: ContextStore): void;
|
|
828
|
+
/** `true` when frames follow async execution (an AsyncLocalStorage-like store is active). */
|
|
829
|
+
readonly isAsync: boolean;
|
|
830
|
+
};
|
|
831
|
+
/**
|
|
832
|
+
* Serilog's `IDiagnosticContext`: set a property from anywhere inside a
|
|
833
|
+
* request scope and it lands on that request's single completion event —
|
|
834
|
+
* one place for "which user, which tenant, how many rows" instead of a log
|
|
835
|
+
* line per fact.
|
|
836
|
+
*/
|
|
837
|
+
declare const diagnosticContext: {
|
|
838
|
+
set(name: string, value: unknown): void;
|
|
839
|
+
/** `true` inside a request scope (so a library can skip the work of computing a value nobody will collect). */
|
|
840
|
+
readonly active: boolean;
|
|
841
|
+
};
|
|
842
|
+
|
|
843
|
+
/**
|
|
844
|
+
* The logger's own diagnostics — Serilog's `SelfLog`. Off by default: a
|
|
845
|
+
* sink that fails must never take the application down, so failures go here
|
|
846
|
+
* and nowhere else. Enable it while setting up a sink, or point it at
|
|
847
|
+
* `console.error` in development.
|
|
848
|
+
*/
|
|
849
|
+
type SelfLogOutput = (message: string) => void;
|
|
850
|
+
declare const selfLog: {
|
|
851
|
+
/** `'stderr'` writes to `console.error`; a function receives each line. */
|
|
852
|
+
enable(target: SelfLogOutput | "stderr"): void;
|
|
853
|
+
disable(): void;
|
|
854
|
+
readonly enabled: boolean;
|
|
855
|
+
/** Writes one line (prefixed with the time) if enabled; swallows its own errors. */
|
|
856
|
+
write(message: string, error?: unknown): void;
|
|
857
|
+
};
|
|
858
|
+
|
|
859
|
+
/** A sink that only sees events at or above `level` (Serilog's `restrictedToMinimumLevel`, for sinks that do not take the option themselves). */
|
|
860
|
+
declare function restricted(sink: Sink, level: LevelOrSwitch): Sink;
|
|
861
|
+
/** Serilog's `WriteTo.Conditional`: events the predicate accepts go to the sink, the rest are skipped. */
|
|
862
|
+
declare function conditional(predicate: (event: LogEvent) => boolean, sink: Sink): Sink;
|
|
863
|
+
/** Serilog's `AuditTo`: a failure in this sink propagates to the logging call instead of being swallowed. */
|
|
864
|
+
declare function audit(sink: Sink): Sink;
|
|
865
|
+
interface MapSinkOptions {
|
|
866
|
+
/** Sinks kept open at once; the least recently used is closed beyond this. Default 100. */
|
|
867
|
+
maxSinks?: number;
|
|
868
|
+
restrictedToMinimumLevel?: LevelOrSwitch;
|
|
869
|
+
}
|
|
870
|
+
/**
|
|
871
|
+
* Serilog.Sinks.Map: one sink per value of a key — a file per tenant, a
|
|
872
|
+
* stream per job. `keyOf` reads the key from the event (return `undefined`
|
|
873
|
+
* to skip); `create` builds the sink the first time a key is seen.
|
|
874
|
+
*/
|
|
875
|
+
declare function mapSink<K extends string | number>(keyOf: (event: LogEvent) => K | undefined, create: (key: K) => Sink, options?: MapSinkOptions): Sink;
|
|
876
|
+
|
|
877
|
+
export { type BatchingOptions, type BatchingSink, CLEF_MEDIA_TYPE, type CapturedError, type ClefFormatterOptions, type ConsoleSinkOptions, type ContextFrame, type ContextHandle, type ContextStore, DEFAULT_DESTRUCTURING, DEFAULT_OUTPUT_TEMPLATE, type DestructuringOptions, type DestructuringPolicy, type Enricher, type FetchLike, type Filter, type FormatName, type Formatter, type HoleToken, type HttpSinkOptions, type JsonFormatterOptions, LEVELS, LEVEL_CODES, LEVEL_NUMBERS, LEVEL_ORDER, type LevelOrSwitch, LevelSwitch, LogContext, LogEvent, type LogEventInit, type LogLevel, type LogMethod, Logger, LoggerConfiguration, type LoggerOptions, type MapSinkOptions, Matching, type MemorySink, type MessageTemplate, Operation, type OperationOptions, type PrettyFormatterOptions, type RenderOptions, SERILOG_LEVEL_NAMES, type SeqSinkOptions, type Sink, type SinkOptions, type StreamLike, type StreamSinkOptions, type TemplateToken, type TextFormatterOptions, type TextToken, type TraceContext, type ValueStyles, ansi, audit, batchingSink, byExcluding, byIncludingOnly, byTransforming, callbackSink, captureError, captureProperty, captureValue, clefFormatter, closeAndFlush, conditional, configure, consoleSink, createLogger, detectColors, diagnosticContext, formatDate, formatError, formatLevel, formatNumber, fromLogContext, httpSink, isLevel, isoTimestamp, jsonFormatter, jsonReplacer, levelAtLeast, log, mapSink, memorySink, parseLevel, parseTemplate, prettyFormatter, rateLimited, renderTemplate, renderValue, resolveFormatter, resolveLevel, resolveStyles, restricted, sampled, selfLog, seqSink, streamSink, templateHash, textFormatter, toJson, withComputed, withEnvironment, withProperties, withProperty, withTraceContext };
|