@pencroff-lab/kore 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -1
- package/dist/cjs/src/utils/format_dt.d.ts +16 -15
- package/dist/cjs/src/utils/format_dt.d.ts.map +1 -1
- package/dist/cjs/src/utils/format_dt.js +20 -16
- package/dist/cjs/src/utils/format_dt.js.map +1 -1
- package/dist/cjs/src/utils/index.d.ts +1 -0
- package/dist/cjs/src/utils/index.d.ts.map +1 -1
- package/dist/cjs/src/utils/index.js +1 -0
- package/dist/cjs/src/utils/index.js.map +1 -1
- package/dist/cjs/src/utils/logger.d.ts +271 -0
- package/dist/cjs/src/utils/logger.d.ts.map +1 -0
- package/dist/cjs/src/utils/logger.js +340 -0
- package/dist/cjs/src/utils/logger.js.map +1 -0
- package/dist/esm/src/utils/format_dt.d.ts +16 -15
- package/dist/esm/src/utils/format_dt.d.ts.map +1 -1
- package/dist/esm/src/utils/format_dt.js +20 -16
- package/dist/esm/src/utils/format_dt.js.map +1 -1
- package/dist/esm/src/utils/index.d.ts +1 -0
- package/dist/esm/src/utils/index.d.ts.map +1 -1
- package/dist/esm/src/utils/index.js +1 -0
- package/dist/esm/src/utils/index.js.map +1 -1
- package/dist/esm/src/utils/logger.d.ts +271 -0
- package/dist/esm/src/utils/logger.d.ts.map +1 -0
- package/dist/esm/src/utils/logger.js +335 -0
- package/dist/esm/src/utils/logger.js.map +1 -0
- package/docs/format_dt.md +42 -22
- package/docs/logger.md +342 -0
- package/docs/logging_guide.md +427 -0
- package/llms.txt +3 -1
- package/package.json +4 -1
package/docs/format_dt.md
CHANGED
|
@@ -25,27 +25,27 @@ interface DtStampOptions {
|
|
|
25
25
|
ms?: boolean;
|
|
26
26
|
tz?: "utc" | "local";
|
|
27
27
|
parts?: "datetime" | "date" | "time";
|
|
28
|
-
|
|
28
|
+
readable?: boolean;
|
|
29
29
|
}
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
| Option | Type | Default | Description |
|
|
33
33
|
|-------------|-----------------------------------|--------------|-----------------------------------------------------------------------------|
|
|
34
|
-
| `delimiter` | `string` | `"_"` | Character(s) between date/time segments.
|
|
34
|
+
| `delimiter` | `string` | `"_"` | Character(s) between date/time segments. |
|
|
35
35
|
| `ms` | `boolean` | `false` | Include milliseconds in the time portion. |
|
|
36
36
|
| `tz` | `"utc" \| "local"` | `"utc"` | Timezone for extracting date/time components. |
|
|
37
37
|
| `parts` | `"datetime" \| "date" \| "time"` | `"datetime"` | Which parts of the stamp to include. |
|
|
38
|
-
| `
|
|
38
|
+
| `readable` | `boolean` | `false` | When `true`, formats with human-readable separators. |
|
|
39
39
|
|
|
40
40
|
### Option Details
|
|
41
41
|
|
|
42
42
|
#### `delimiter`
|
|
43
43
|
|
|
44
|
-
Character(s) placed between date and time segments, and between time and milliseconds when `ms` is `true`.
|
|
44
|
+
Character(s) placed between date and time segments, and between time and milliseconds when `ms` is `true`.
|
|
45
45
|
|
|
46
46
|
#### `ms`
|
|
47
47
|
|
|
48
|
-
When `true`, appends milliseconds to the time portion, separated by the delimiter.
|
|
48
|
+
When `true`, appends milliseconds to the time portion, separated by the delimiter (or `.` in readable time-only mode).
|
|
49
49
|
|
|
50
50
|
#### `tz`
|
|
51
51
|
|
|
@@ -59,9 +59,13 @@ Controls which parts of the timestamp are included:
|
|
|
59
59
|
- `"date"` -- date only: `YYYYMMDD`
|
|
60
60
|
- `"time"` -- time only: `HHmmss` or `HHmmss_SSS` with `ms`
|
|
61
61
|
|
|
62
|
-
#### `
|
|
62
|
+
#### `readable`
|
|
63
63
|
|
|
64
|
-
When `true`,
|
|
64
|
+
When `true`, formats with human-readable separators:
|
|
65
|
+
- Dashes in date: `YYYY-MM-DD`
|
|
66
|
+
- Colons in time: `HH:MM:SS`
|
|
67
|
+
- `.` before milliseconds in time-only mode: `HH:MM:SS.mmm`
|
|
68
|
+
- Delimiter still used between date/time and between time/milliseconds in datetime mode
|
|
65
69
|
|
|
66
70
|
## Examples
|
|
67
71
|
|
|
@@ -74,11 +78,25 @@ dtStamp(new Date("2024-03-15T10:30:45.123Z"));
|
|
|
74
78
|
// "20240315_103045"
|
|
75
79
|
```
|
|
76
80
|
|
|
77
|
-
###
|
|
81
|
+
### Readable datetime with milliseconds
|
|
78
82
|
|
|
79
83
|
```typescript
|
|
80
|
-
dtStamp(new Date("2024-03-15T10:30:45.123Z"), {
|
|
81
|
-
// "
|
|
84
|
+
dtStamp(new Date("2024-03-15T10:30:45.123Z"), { readable: true, ms: true });
|
|
85
|
+
// "2024-03-15_10:30:45_123"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Readable date only
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
dtStamp(new Date("2024-03-15T10:30:45.123Z"), { readable: true, parts: "date" });
|
|
92
|
+
// "2024-03-15"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Readable time with milliseconds
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
dtStamp(new Date("2024-03-15T10:30:45.123Z"), { readable: true, parts: "time", ms: true });
|
|
99
|
+
// "10:30:45.123"
|
|
82
100
|
```
|
|
83
101
|
|
|
84
102
|
### Date only
|
|
@@ -125,15 +143,17 @@ dtStamp(new Date("2024-03-15T10:30:45.123Z"), { tz: "local" });
|
|
|
125
143
|
|
|
126
144
|
## Output Format Reference
|
|
127
145
|
|
|
128
|
-
| Options
|
|
129
|
-
|
|
130
|
-
| `{}`
|
|
131
|
-
| `{ ms: true }`
|
|
132
|
-
| `{
|
|
133
|
-
| `{
|
|
134
|
-
| `{ parts: "
|
|
135
|
-
| `{
|
|
136
|
-
| `{
|
|
137
|
-
| `{
|
|
138
|
-
| `{
|
|
139
|
-
| `{
|
|
146
|
+
| Options | Output |
|
|
147
|
+
|-----------------------------------------------------|-------------------------|
|
|
148
|
+
| `{}` | `20240315_103045` |
|
|
149
|
+
| `{ ms: true }` | `20240315_103045_123` |
|
|
150
|
+
| `{ parts: "date" }` | `20240315` |
|
|
151
|
+
| `{ parts: "time" }` | `103045` |
|
|
152
|
+
| `{ parts: "time", ms: true }` | `103045_123` |
|
|
153
|
+
| `{ delimiter: "-" }` | `20240315-103045` |
|
|
154
|
+
| `{ delimiter: "-", ms: true }` | `20240315-103045-123` |
|
|
155
|
+
| `{ readable: true }` | `2024-03-15_10:30:45` |
|
|
156
|
+
| `{ readable: true, ms: true }` | `2024-03-15_10:30:45_123` |
|
|
157
|
+
| `{ readable: true, parts: "date" }` | `2024-03-15` |
|
|
158
|
+
| `{ readable: true, parts: "time" }` | `10:30:45` |
|
|
159
|
+
| `{ readable: true, parts: "time", ms: true }` | `10:30:45.123` |
|
package/docs/logger.md
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
# Logger
|
|
2
|
+
|
|
3
|
+
Structured logging utility with transport dependency injection and Err integration.
|
|
4
|
+
|
|
5
|
+
The logger is a callable function with overloaded signatures and level constants attached as properties. Transports are injectable, making the logger testable without streams or process-level side effects. The built-in pretty transport renders to stderr with ANSI colors and automatic `Err` formatting.
|
|
6
|
+
|
|
7
|
+
For usage patterns, DI conventions, and error logging strategy, see the [Logging Guide](logging_guide.md).
|
|
8
|
+
|
|
9
|
+
## Exports
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { log, createLogger, prettyTransport, lvl } from "@pencroff-lab/kore";
|
|
13
|
+
import type {
|
|
14
|
+
Logger,
|
|
15
|
+
LevelValue,
|
|
16
|
+
LogEntry,
|
|
17
|
+
LogTransport,
|
|
18
|
+
LoggerOptions,
|
|
19
|
+
PrettyOptions,
|
|
20
|
+
} from "@pencroff-lab/kore";
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Types
|
|
24
|
+
|
|
25
|
+
### `LevelValue`
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
type LevelValue = "trace" | "debug" | "info" | "warn" | "error" | "fatal";
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Union type of valid log level strings.
|
|
32
|
+
|
|
33
|
+
### `LogEntry`
|
|
34
|
+
|
|
35
|
+
A single structured log entry passed to transports.
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
interface LogEntry {
|
|
39
|
+
level: LevelValue;
|
|
40
|
+
timestamp: number;
|
|
41
|
+
message: string;
|
|
42
|
+
context: Record<string, unknown>;
|
|
43
|
+
modules: string[];
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
| Property | Type | Description |
|
|
48
|
+
|-------------|----------------------------|--------------------------------------------------|
|
|
49
|
+
| `level` | `LevelValue` | Log level of this entry. |
|
|
50
|
+
| `timestamp` | `number` | Unix timestamp in milliseconds (`Date.now()`). |
|
|
51
|
+
| `message` | `string` | Log message. |
|
|
52
|
+
| `context` | `Record<string, unknown>` | Merged bindings and call-site context. |
|
|
53
|
+
| `modules` | `string[]` | Module chain accumulated by `child()` calls. |
|
|
54
|
+
|
|
55
|
+
### `LogTransport`
|
|
56
|
+
|
|
57
|
+
Transport interface for log output backends. Implement this to integrate any logging backend (file, remote service, test spy, etc.).
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
interface LogTransport {
|
|
61
|
+
write(entry: LogEntry): void;
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
#### Example: Pino transport
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import pino from "pino";
|
|
69
|
+
import type { LogTransport, LogEntry } from "@pencroff-lab/kore";
|
|
70
|
+
|
|
71
|
+
const pinoInstance = pino();
|
|
72
|
+
const pinoTransport: LogTransport = {
|
|
73
|
+
write(entry: LogEntry) {
|
|
74
|
+
const prefix = entry.modules.map((m) => `[${m}] `).join("");
|
|
75
|
+
pinoInstance[entry.level](entry.context, prefix + entry.message);
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
#### Example: Test spy transport
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import type { LogEntry, LogTransport } from "@pencroff-lab/kore";
|
|
84
|
+
|
|
85
|
+
const entries: LogEntry[] = [];
|
|
86
|
+
const spy: LogTransport = { write(e) { entries.push(e); } };
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### `PrettyOptions`
|
|
90
|
+
|
|
91
|
+
Options for the built-in pretty console transport.
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
interface PrettyOptions {
|
|
95
|
+
output?: { write(data: string): void };
|
|
96
|
+
colors?: boolean | "auto";
|
|
97
|
+
levelColors?: Partial<Record<LevelValue, string>>;
|
|
98
|
+
timestamp?: "short" | "iso" | ((ts: number) => string);
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
| Option | Type | Default | Description |
|
|
103
|
+
|---------------|-----------------------------------------------|------------------|----------------------------------------------------------|
|
|
104
|
+
| `output` | `{ write(data: string): void }` | `process.stderr` | Output stream. |
|
|
105
|
+
| `colors` | `boolean \| "auto"` | `"auto"` | ANSI colors. `"auto"` enables when output is a TTY. |
|
|
106
|
+
| `levelColors` | `Partial<Record<LevelValue, string>>` | (built-in) | Override ANSI escape sequences per level. |
|
|
107
|
+
| `timestamp` | `"short" \| "iso" \| ((ts: number) => string)` | `"short"` | Timestamp format. `"short"` is `HH:MM:SS.mmm` local time. |
|
|
108
|
+
|
|
109
|
+
### `LoggerOptions`
|
|
110
|
+
|
|
111
|
+
Options for `createLogger`.
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
interface LoggerOptions {
|
|
115
|
+
level?: LevelValue;
|
|
116
|
+
transports?: LogTransport[];
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
| Option | Type | Default | Description |
|
|
121
|
+
|--------------|------------------|---------------------------------------|--------------------------------------|
|
|
122
|
+
| `level` | `LevelValue` | `LOG_LEVEL` env or `"info"` | Minimum log level. |
|
|
123
|
+
| `transports` | `LogTransport[]` | `[prettyTransport()]` | Transports to write entries to. |
|
|
124
|
+
|
|
125
|
+
### `Logger`
|
|
126
|
+
|
|
127
|
+
Callable logger interface. The Logger is both a function (for logging) and an object (with level constants and the `child` method).
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
interface Logger {
|
|
131
|
+
readonly TRACE: "trace";
|
|
132
|
+
readonly DEBUG: "debug";
|
|
133
|
+
readonly INFO: "info";
|
|
134
|
+
readonly WARN: "warn";
|
|
135
|
+
readonly ERROR: "error";
|
|
136
|
+
readonly FATAL: "fatal";
|
|
137
|
+
|
|
138
|
+
(message: string): void;
|
|
139
|
+
(message: string, context: object | Err): void;
|
|
140
|
+
(message: string, detail: string): void;
|
|
141
|
+
(level: LevelValue, message: string): void;
|
|
142
|
+
(level: LevelValue, message: string, context: object | Err): void;
|
|
143
|
+
|
|
144
|
+
child(module: string, bindings?: object): Logger;
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### Call Signatures
|
|
149
|
+
|
|
150
|
+
| Signature | Level | Description |
|
|
151
|
+
|----------------------------------------|--------|-------------------------------------|
|
|
152
|
+
| `log(message)` | INFO | Log at default INFO level. |
|
|
153
|
+
| `log(message, context)` | INFO | INFO with context object or Err. |
|
|
154
|
+
| `log(message, detail)` | INFO | INFO with detail string. |
|
|
155
|
+
| `log(level, message)` | given | Log at specific level. |
|
|
156
|
+
| `log(level, message, context)` | given | Specific level with context or Err. |
|
|
157
|
+
|
|
158
|
+
Context handling:
|
|
159
|
+
- `Err` instances are stored as `{ err: <Err> }` in `context`
|
|
160
|
+
- Plain strings are stored as `{ detail: <string> }` in `context`
|
|
161
|
+
- Objects are used as-is
|
|
162
|
+
|
|
163
|
+
## `lvl`
|
|
164
|
+
|
|
165
|
+
Level constants object for use with `createLogger` options.
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
const lvl = {
|
|
169
|
+
TRACE: "trace",
|
|
170
|
+
DEBUG: "debug",
|
|
171
|
+
INFO: "info",
|
|
172
|
+
WARN: "warn",
|
|
173
|
+
ERROR: "error",
|
|
174
|
+
FATAL: "fatal",
|
|
175
|
+
} as const;
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Level hierarchy** (lowest to highest):
|
|
179
|
+
|
|
180
|
+
| Numeric | Level | Tag | Description |
|
|
181
|
+
|---------|---------|-------|--------------------------------------|
|
|
182
|
+
| 0 | `trace` | `TRC` | Detailed debugging information |
|
|
183
|
+
| 1 | `debug` | `DBG` | Debugging information |
|
|
184
|
+
| 2 | `info` | `INF` | General informational messages |
|
|
185
|
+
| 3 | `warn` | `WRN` | Warning messages |
|
|
186
|
+
| 4 | `error` | `ERR` | Error messages for failures |
|
|
187
|
+
| 5 | `fatal` | `FTL` | Fatal errors causing termination |
|
|
188
|
+
|
|
189
|
+
Consumer code should use level constants on the logger instance (`log.INFO`, `log.ERROR`, etc.) rather than importing `lvl` directly. The `lvl` export is intended for `createLogger` options only.
|
|
190
|
+
|
|
191
|
+
## `createLogger()`
|
|
192
|
+
|
|
193
|
+
Create a logger instance with optional module name and configuration.
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
function createLogger(module?: string, options?: LoggerOptions): Logger
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Parameters
|
|
200
|
+
|
|
201
|
+
| Parameter | Type | Default | Description |
|
|
202
|
+
|-----------|-----------------|-------------|-------------------------------------------------|
|
|
203
|
+
| `module` | `string` | `undefined` | Module name added as the first entry in `modules`. |
|
|
204
|
+
| `options` | `LoggerOptions` | `{}` | Logger configuration. |
|
|
205
|
+
|
|
206
|
+
### Examples
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
// Default logger (INFO level, pretty transport)
|
|
210
|
+
const logger = createLogger();
|
|
211
|
+
logger("Application ready");
|
|
212
|
+
|
|
213
|
+
// Module-specific logger
|
|
214
|
+
const dbLogger = createLogger("database");
|
|
215
|
+
dbLogger("Connected");
|
|
216
|
+
// Output: [database] Connected
|
|
217
|
+
|
|
218
|
+
// With explicit level and custom transport
|
|
219
|
+
const entries: LogEntry[] = [];
|
|
220
|
+
const spy: LogTransport = { write(e) { entries.push(e); } };
|
|
221
|
+
const testLogger = createLogger("test", {
|
|
222
|
+
transports: [spy],
|
|
223
|
+
level: lvl.TRACE,
|
|
224
|
+
});
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## `prettyTransport()`
|
|
228
|
+
|
|
229
|
+
Create a built-in pretty console transport.
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
function prettyTransport(options?: PrettyOptions): LogTransport
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Renders log entries to a human-readable format with optional ANSI colors. Writes to `process.stderr` by default.
|
|
236
|
+
|
|
237
|
+
### Output Format
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
{dim timestamp} {colored TAG} {[mod] [mod]} {message} {dim context}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Example (colors disabled):
|
|
244
|
+
|
|
245
|
+
```
|
|
246
|
+
12:34:56.789 INF [app] Server started {"port":3000}
|
|
247
|
+
12:34:56.800 ERR [app] Request failed
|
|
248
|
+
err: Err: Connection timeout [NET:TIMEOUT]
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
`Err` instances in context are rendered via `Err.toString()` on their own indented line below the main line.
|
|
252
|
+
|
|
253
|
+
### Examples
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
// Default: stderr, auto colors, short timestamps
|
|
257
|
+
const transport = prettyTransport();
|
|
258
|
+
|
|
259
|
+
// Disable colors, use ISO timestamps
|
|
260
|
+
const plain = prettyTransport({
|
|
261
|
+
colors: false,
|
|
262
|
+
timestamp: "iso",
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// Custom output stream
|
|
266
|
+
const buf: string[] = [];
|
|
267
|
+
const capture = prettyTransport({
|
|
268
|
+
output: { write(data) { buf.push(data); } },
|
|
269
|
+
colors: false,
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
// Custom timestamp formatter
|
|
273
|
+
const custom = prettyTransport({
|
|
274
|
+
timestamp: (ts) => new Date(ts).toLocaleDateString(),
|
|
275
|
+
});
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## `log`
|
|
279
|
+
|
|
280
|
+
Default logger instance created with no module name and default options. Provided for convenience; prefer `createLogger` with an explicit module name for production use.
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
export const log: Logger = createLogger();
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Examples
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
import { log } from "@pencroff-lab/kore";
|
|
290
|
+
|
|
291
|
+
log("Application started");
|
|
292
|
+
log(log.INFO, "Server listening", { port: 3000 });
|
|
293
|
+
log(log.ERROR, "Startup failed", err);
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## `child()`
|
|
297
|
+
|
|
298
|
+
Create a child logger with module-specific context.
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
child(module: string, bindings?: object): Logger
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Parameters
|
|
305
|
+
|
|
306
|
+
| Parameter | Type | Default | Description |
|
|
307
|
+
|------------|----------|-------------|---------------------------------------------------|
|
|
308
|
+
| `module` | `string` | (required) | Module name appended to the `modules` array. |
|
|
309
|
+
| `bindings` | `object` | `undefined` | Key-value pairs merged into every entry's context. |
|
|
310
|
+
|
|
311
|
+
Child loggers inherit level, transports, and parent bindings. Module names are accumulated, producing `[parent] [child]` prefixes in output.
|
|
312
|
+
|
|
313
|
+
### Examples
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
const appLog = createLogger("app");
|
|
317
|
+
|
|
318
|
+
// Service-scoped child
|
|
319
|
+
const dbLog = appLog.child("database", { version: "1.0" });
|
|
320
|
+
dbLog("Connected to postgres");
|
|
321
|
+
// Output: [app] [database] Connected to postgres {"version":"1.0"}
|
|
322
|
+
|
|
323
|
+
// Nested children
|
|
324
|
+
const userLog = dbLog.child("users");
|
|
325
|
+
userLog("User created");
|
|
326
|
+
// Output: [app] [database] [users] User created {"version":"1.0"}
|
|
327
|
+
|
|
328
|
+
// Run-scoped child with correlation ID
|
|
329
|
+
const runLog = appLog.child("handler", { runId: "abc-123" });
|
|
330
|
+
runLog(runLog.INFO, "Processing started");
|
|
331
|
+
// Output: [app] [handler] Processing started {"runId":"abc-123"}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Environment Configuration
|
|
335
|
+
|
|
336
|
+
```bash
|
|
337
|
+
# Minimum log level (default: info)
|
|
338
|
+
# Valid values: trace, debug, info, warn, error, fatal
|
|
339
|
+
LOG_LEVEL=debug
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
The logger reads `LOG_LEVEL` at creation time. When not set, defaults to `info`. The level can be overridden via `createLogger` options.
|