@rawnodes/logger 1.5.1 → 1.7.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 +228 -148
- package/dist/index.d.mts +25 -3
- package/dist/index.d.ts +25 -3
- package/dist/index.js +131 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +129 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# @rawnodes/logger
|
|
2
2
|
|
|
3
|
-
Flexible Winston-based logger with AsyncLocalStorage context, level
|
|
3
|
+
Flexible Winston-based logger with AsyncLocalStorage context, level rules, and multiple output formats.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
+
- **Multiple Formats** - JSON, plain (colored), logfmt, simple
|
|
7
8
|
- **Context Propagation** - Automatic context via AsyncLocalStorage
|
|
8
|
-
- **Level
|
|
9
|
+
- **Level Rules** - Configure log levels per module/context in config
|
|
9
10
|
- **Lazy Meta** - Defer metadata creation until log level check passes
|
|
10
11
|
- **Timing Utilities** - Built-in performance measurement
|
|
11
12
|
- **Request ID** - Generate and extract request IDs
|
|
12
|
-
- **Secret Masking** -
|
|
13
|
-
- **Singleton Factory** - Easy setup with `createSingletonLogger()`
|
|
13
|
+
- **Secret Masking** - Automatic masking of sensitive data
|
|
14
14
|
- **TypeScript First** - Full generic type support
|
|
15
15
|
|
|
16
16
|
## Installation
|
|
@@ -23,241 +23,321 @@ npm install @rawnodes/logger
|
|
|
23
23
|
|
|
24
24
|
## Quick Start
|
|
25
25
|
|
|
26
|
-
### 1. Create your app logger
|
|
27
|
-
|
|
28
26
|
```typescript
|
|
29
|
-
|
|
30
|
-
import { createSingletonLogger, type LoggerContext } from '@rawnodes/logger';
|
|
27
|
+
import { Logger } from '@rawnodes/logger';
|
|
31
28
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
29
|
+
const logger = Logger.create({
|
|
30
|
+
level: 'info',
|
|
31
|
+
console: { format: 'plain' },
|
|
32
|
+
});
|
|
36
33
|
|
|
37
|
-
|
|
34
|
+
logger.info('Hello world');
|
|
35
|
+
logger.info('User logged in', { userId: 123 });
|
|
38
36
|
```
|
|
39
37
|
|
|
40
|
-
|
|
38
|
+
## Configuration
|
|
39
|
+
|
|
40
|
+
### Basic Config
|
|
41
41
|
|
|
42
42
|
```typescript
|
|
43
|
-
|
|
44
|
-
import { AppLogger } from './logger/app.logger.js';
|
|
43
|
+
import { Logger } from '@rawnodes/logger';
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
level: 'info',
|
|
48
|
-
console: {
|
|
49
|
-
file: {
|
|
45
|
+
const logger = Logger.create({
|
|
46
|
+
level: 'info', // default log level
|
|
47
|
+
console: { format: 'plain' }, // console output format
|
|
48
|
+
file: { // optional file output
|
|
49
|
+
format: 'json',
|
|
50
50
|
dirname: 'logs',
|
|
51
51
|
filename: 'app-%DATE%.log',
|
|
52
|
-
level: 'info',
|
|
53
52
|
datePattern: 'YYYY-MM-DD',
|
|
54
53
|
maxFiles: '14d',
|
|
54
|
+
maxSize: '20m',
|
|
55
55
|
},
|
|
56
56
|
});
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
###
|
|
59
|
+
### Level Rules
|
|
60
|
+
|
|
61
|
+
Configure different log levels for specific modules or contexts:
|
|
60
62
|
|
|
61
63
|
```typescript
|
|
62
|
-
|
|
64
|
+
const logger = Logger.create({
|
|
65
|
+
level: {
|
|
66
|
+
default: 'info',
|
|
67
|
+
rules: [
|
|
68
|
+
{ match: { context: 'auth' }, level: 'debug' }, // debug for auth module
|
|
69
|
+
{ match: { context: 'database' }, level: 'warn' }, // warn for database
|
|
70
|
+
{ match: { userId: 123 }, level: 'debug' }, // debug for user 123
|
|
71
|
+
{ match: { context: 'api', userId: 456 }, level: 'silly' }, // combined match
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
console: { format: 'plain' },
|
|
75
|
+
});
|
|
63
76
|
|
|
64
|
-
const
|
|
77
|
+
const authLogger = logger.for('auth');
|
|
78
|
+
authLogger.debug('This will be logged'); // matches rule
|
|
79
|
+
|
|
80
|
+
const dbLogger = logger.for('database');
|
|
81
|
+
dbLogger.info('This will NOT be logged'); // level is warn
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Rules from config are **readonly** and cannot be removed via API.
|
|
65
85
|
|
|
86
|
+
### Output Formats
|
|
87
|
+
|
|
88
|
+
| Format | Description | Example |
|
|
89
|
+
|--------|-------------|---------|
|
|
90
|
+
| `json` | Structured JSON | `{"level":"info","message":"hello","timestamp":"..."}` |
|
|
91
|
+
| `plain` | Colored, human-readable | `[2025-01-01T12:00:00] info [APP] hello` |
|
|
92
|
+
| `logfmt` | Key=value pairs | `level=info msg=hello context=APP ts=2025-01-01T12:00:00` |
|
|
93
|
+
| `simple` | Minimal | `[2025-01-01T12:00:00] info: hello` |
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
// Different formats for console and file
|
|
97
|
+
const logger = Logger.create({
|
|
98
|
+
level: 'info',
|
|
99
|
+
console: { format: 'plain' }, // colored for development
|
|
100
|
+
file: {
|
|
101
|
+
format: 'json', // structured for log aggregation
|
|
102
|
+
dirname: 'logs',
|
|
103
|
+
filename: 'app-%DATE%.log',
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Singleton Pattern
|
|
109
|
+
|
|
110
|
+
For app-wide logging:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
// src/logger.ts
|
|
114
|
+
import { createSingletonLogger, type LoggerContext } from '@rawnodes/logger';
|
|
115
|
+
|
|
116
|
+
export interface AppContext extends LoggerContext {
|
|
117
|
+
userId?: number;
|
|
118
|
+
requestId?: string;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export const AppLogger = createSingletonLogger<AppContext>();
|
|
122
|
+
|
|
123
|
+
// src/main.ts
|
|
124
|
+
import { AppLogger } from './logger.js';
|
|
125
|
+
|
|
126
|
+
AppLogger.init({
|
|
127
|
+
level: {
|
|
128
|
+
default: 'info',
|
|
129
|
+
rules: [{ match: { context: 'debug-module' }, level: 'debug' }],
|
|
130
|
+
},
|
|
131
|
+
console: { format: 'plain' },
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Anywhere in your app
|
|
135
|
+
const logger = AppLogger.for('UserService');
|
|
66
136
|
logger.info('User created', { userId: 123 });
|
|
67
|
-
logger.error('Failed to create user', { error });
|
|
68
137
|
```
|
|
69
138
|
|
|
70
|
-
|
|
139
|
+
## Context Propagation
|
|
140
|
+
|
|
141
|
+
Automatically include context in all logs within an async scope:
|
|
71
142
|
|
|
72
143
|
```typescript
|
|
73
144
|
// Express middleware
|
|
74
145
|
app.use((req, res, next) => {
|
|
75
|
-
const context
|
|
146
|
+
const context = {
|
|
76
147
|
userId: req.user?.id,
|
|
77
148
|
requestId: req.headers['x-request-id'] || generateRequestId(),
|
|
78
149
|
};
|
|
79
150
|
AppLogger.getStore().run(context, () => next());
|
|
80
151
|
});
|
|
81
|
-
```
|
|
82
152
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
console: {
|
|
90
|
-
level: string; // Console transport level
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
file?: {
|
|
94
|
-
dirname: string; // Log directory
|
|
95
|
-
filename: string; // Filename pattern (supports %DATE%)
|
|
96
|
-
level: string; // File transport level
|
|
97
|
-
datePattern: string; // Date pattern for rotation
|
|
98
|
-
zippedArchive?: boolean;
|
|
99
|
-
maxSize?: string; // e.g., '20m'
|
|
100
|
-
maxFiles?: string; // e.g., '14d'
|
|
101
|
-
};
|
|
102
|
-
}
|
|
153
|
+
// All logs within this request will include userId and requestId
|
|
154
|
+
logger.info('Processing request');
|
|
155
|
+
// Output: [2025-01-01T12:00:00] info [APP] Processing request
|
|
156
|
+
// userId: 123
|
|
157
|
+
// requestId: abc-123
|
|
103
158
|
```
|
|
104
159
|
|
|
105
|
-
## Level Overrides
|
|
160
|
+
## Dynamic Level Overrides
|
|
106
161
|
|
|
107
|
-
|
|
162
|
+
Add/remove level overrides at runtime:
|
|
108
163
|
|
|
109
164
|
```typescript
|
|
110
|
-
// Enable debug
|
|
165
|
+
// Enable debug for specific user (e.g., for troubleshooting)
|
|
111
166
|
logger.setLevelOverride({ userId: 123 }, 'debug');
|
|
112
167
|
|
|
113
|
-
// Enable debug
|
|
114
|
-
|
|
115
|
-
logger.setLevelOverride({ context: 'auth' }, 'debug');
|
|
116
|
-
|
|
117
|
-
// Enable debug for specific user in specific module
|
|
118
|
-
logger.setLevelOverride({ context: 'auth', userId: 123 }, 'debug');
|
|
119
|
-
|
|
120
|
-
// Now only auth module logs for user 123 will include debug level
|
|
121
|
-
// Other users and modules still get the default level
|
|
168
|
+
// Enable debug for specific module
|
|
169
|
+
logger.setLevelOverride({ context: 'payments' }, 'debug');
|
|
122
170
|
|
|
123
|
-
// Remove override
|
|
124
|
-
logger.removeLevelOverride({
|
|
171
|
+
// Remove override
|
|
172
|
+
logger.removeLevelOverride({ userId: 123 });
|
|
125
173
|
|
|
126
|
-
//
|
|
174
|
+
// Clear all dynamic overrides (keeps config rules)
|
|
127
175
|
logger.clearLevelOverrides();
|
|
176
|
+
|
|
177
|
+
// Get all overrides
|
|
178
|
+
const overrides = logger.getLevelOverrides();
|
|
179
|
+
// [{ match: { context: 'payments' }, level: 'debug', readonly: false }]
|
|
128
180
|
```
|
|
129
181
|
|
|
130
182
|
## Lazy Meta
|
|
131
183
|
|
|
132
|
-
|
|
184
|
+
Defer expensive object creation:
|
|
133
185
|
|
|
134
186
|
```typescript
|
|
135
|
-
// Object
|
|
136
|
-
logger.debug('
|
|
187
|
+
// BAD: Object created even if debug is disabled
|
|
188
|
+
logger.debug('Data processed', { result: expensiveSerialize(data) });
|
|
137
189
|
|
|
138
|
-
// Function
|
|
139
|
-
logger.debug('
|
|
190
|
+
// GOOD: Function only called when debug is enabled
|
|
191
|
+
logger.debug('Data processed', () => ({ result: expensiveSerialize(data) }));
|
|
140
192
|
```
|
|
141
193
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
## Timing
|
|
194
|
+
## Child Loggers
|
|
145
195
|
|
|
146
|
-
|
|
196
|
+
Create scoped loggers:
|
|
147
197
|
|
|
148
198
|
```typescript
|
|
149
|
-
const logger = AppLogger.
|
|
199
|
+
const logger = AppLogger.for('PaymentService');
|
|
200
|
+
logger.info('Processing payment');
|
|
201
|
+
// Output: [timestamp] info [PaymentService] Processing payment
|
|
202
|
+
|
|
203
|
+
const stripeLogger = logger.for('Stripe');
|
|
204
|
+
stripeLogger.info('Charging card');
|
|
205
|
+
// Output: [timestamp] info [Stripe] Charging card
|
|
206
|
+
```
|
|
150
207
|
|
|
151
|
-
|
|
152
|
-
const timer = logger.time('database-query');
|
|
153
|
-
await db.query('SELECT ...');
|
|
154
|
-
logger.timeEnd(timer); // Logs: "database-query completed in 45.23ms"
|
|
208
|
+
## Utilities
|
|
155
209
|
|
|
156
|
-
|
|
157
|
-
|
|
210
|
+
### Timing
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
import { measureAsync, measureSync } from '@rawnodes/logger';
|
|
214
|
+
|
|
215
|
+
// Async
|
|
216
|
+
const { result, timing } = await measureAsync('fetch-users', async () => {
|
|
158
217
|
return await userService.findAll();
|
|
159
218
|
});
|
|
219
|
+
console.log(timing); // { label: 'fetch-users', durationMs: 45.23, durationFormatted: '45.23ms' }
|
|
220
|
+
|
|
221
|
+
// Sync
|
|
222
|
+
const { result, timing } = measureSync('compute', () => {
|
|
223
|
+
return heavyComputation();
|
|
224
|
+
});
|
|
160
225
|
```
|
|
161
226
|
|
|
162
|
-
|
|
227
|
+
### Request ID
|
|
163
228
|
|
|
164
229
|
```typescript
|
|
165
|
-
import { generateRequestId, getOrGenerateRequestId } from '@rawnodes/logger';
|
|
166
|
-
|
|
167
|
-
// Generate new request ID
|
|
168
|
-
const requestId = generateRequestId();
|
|
169
|
-
// => "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
|
230
|
+
import { generateRequestId, extractRequestId, getOrGenerateRequestId } from '@rawnodes/logger';
|
|
170
231
|
|
|
171
|
-
//
|
|
172
|
-
|
|
173
|
-
//
|
|
232
|
+
// Generate new
|
|
233
|
+
generateRequestId(); // "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
|
234
|
+
generateRequestId({ short: true }); // "a1b2c3d4"
|
|
235
|
+
generateRequestId({ prefix: 'req' }); // "req-a1b2c3d4-e5f6-..."
|
|
174
236
|
|
|
175
|
-
//
|
|
176
|
-
|
|
177
|
-
// => "req-a1b2c3d4-e5f6-..."
|
|
237
|
+
// Extract from headers (checks x-request-id, x-correlation-id, x-trace-id)
|
|
238
|
+
extractRequestId(req.headers); // string | undefined
|
|
178
239
|
|
|
179
|
-
// Extract
|
|
180
|
-
|
|
240
|
+
// Extract or generate
|
|
241
|
+
getOrGenerateRequestId(req.headers); // always returns string
|
|
181
242
|
```
|
|
182
243
|
|
|
183
|
-
|
|
244
|
+
### Secret Masking
|
|
245
|
+
|
|
246
|
+
Automatically masks sensitive fields in logs:
|
|
184
247
|
|
|
185
248
|
```typescript
|
|
186
|
-
import { maskSecrets } from '@rawnodes/logger';
|
|
249
|
+
import { maskSecrets, createMasker } from '@rawnodes/logger';
|
|
187
250
|
|
|
188
|
-
|
|
251
|
+
maskSecrets({
|
|
189
252
|
user: 'admin',
|
|
190
253
|
password: 'secret123',
|
|
191
|
-
|
|
192
|
-
url: 'postgres://user:pass@localhost/db',
|
|
254
|
+
apiKey: 'key_abc123',
|
|
193
255
|
});
|
|
256
|
+
// { user: 'admin', password: '***', apiKey: '***' }
|
|
194
257
|
|
|
195
|
-
//
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
// url: 'postgres://user:***@localhost/db'
|
|
201
|
-
// }
|
|
258
|
+
// Custom masker
|
|
259
|
+
const masker = createMasker({
|
|
260
|
+
patterns: ['ssn', 'creditCard'],
|
|
261
|
+
mask: '[REDACTED]'
|
|
262
|
+
});
|
|
202
263
|
```
|
|
203
264
|
|
|
204
|
-
|
|
265
|
+
**Default masked patterns:** `password`, `secret`, `token`, `apikey`, `api_key`, `api-key`, `auth`, `credential`, `private`
|
|
205
266
|
|
|
206
|
-
|
|
267
|
+
## Logfmt Utilities
|
|
268
|
+
|
|
269
|
+
Helper functions for logfmt format:
|
|
207
270
|
|
|
208
271
|
```typescript
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
272
|
+
import { flattenObject, formatLogfmt, formatLogfmtValue } from '@rawnodes/logger';
|
|
273
|
+
|
|
274
|
+
flattenObject({ user: { id: 123, name: 'John' } });
|
|
275
|
+
// { 'user.id': 123, 'user.name': 'John' }
|
|
212
276
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const childLogger = baseLogger.getChildLogger('EmailService');
|
|
277
|
+
formatLogfmt({ level: 'info', msg: 'hello', userId: 123 });
|
|
278
|
+
// "level=info msg=hello userId=123"
|
|
216
279
|
```
|
|
217
280
|
|
|
218
281
|
## API Reference
|
|
219
282
|
|
|
220
|
-
###
|
|
283
|
+
### Logger
|
|
221
284
|
|
|
222
|
-
Creates a singleton logger factory.
|
|
223
|
-
|
|
224
|
-
Returns:
|
|
225
285
|
```typescript
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
286
|
+
class Logger<TContext> {
|
|
287
|
+
static create(config: LoggerConfig, store?: LoggerStore): Logger;
|
|
288
|
+
|
|
229
289
|
for(context: string): Logger;
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
290
|
+
getStore(): LoggerStore<TContext>;
|
|
291
|
+
|
|
292
|
+
// Logging
|
|
293
|
+
error(message: string, error?: Error, meta?: Meta): void;
|
|
294
|
+
warn(message: string, meta?: Meta): void;
|
|
295
|
+
info(message: string, meta?: Meta): void;
|
|
296
|
+
http(message: string, meta?: Meta): void;
|
|
297
|
+
verbose(message: string, meta?: Meta): void;
|
|
298
|
+
debug(message: string, meta?: Meta): void;
|
|
299
|
+
silly(message: string, meta?: Meta): void;
|
|
300
|
+
|
|
301
|
+
// Level overrides
|
|
302
|
+
setLevelOverride(match: LevelOverrideMatch, level: LogLevel): void;
|
|
303
|
+
removeLevelOverride(match: LevelOverrideMatch): boolean;
|
|
233
304
|
clearLevelOverrides(): void;
|
|
305
|
+
getLevelOverrides(): LevelOverride[];
|
|
306
|
+
|
|
307
|
+
// Winston profiling
|
|
308
|
+
profile(id: string, meta?: object): void;
|
|
234
309
|
}
|
|
235
310
|
```
|
|
236
311
|
|
|
237
|
-
###
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
312
|
+
### Types
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
type LogLevel = 'error' | 'warn' | 'info' | 'http' | 'verbose' | 'debug' | 'silly';
|
|
316
|
+
type LogFormat = 'json' | 'plain' | 'logfmt' | 'simple';
|
|
317
|
+
type Meta = object | (() => object);
|
|
318
|
+
|
|
319
|
+
interface LoggerConfig {
|
|
320
|
+
level: LogLevel | {
|
|
321
|
+
default: LogLevel;
|
|
322
|
+
rules?: LevelRule[];
|
|
323
|
+
};
|
|
324
|
+
console: { format: LogFormat };
|
|
325
|
+
file?: {
|
|
326
|
+
format: LogFormat;
|
|
327
|
+
dirname: string;
|
|
328
|
+
filename: string;
|
|
329
|
+
datePattern?: string;
|
|
330
|
+
maxFiles?: string;
|
|
331
|
+
maxSize?: string;
|
|
332
|
+
zippedArchive?: boolean;
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
interface LevelRule {
|
|
337
|
+
match: Record<string, unknown> & { context?: string };
|
|
338
|
+
level: LogLevel;
|
|
339
|
+
}
|
|
340
|
+
```
|
|
261
341
|
|
|
262
342
|
## Integration Examples
|
|
263
343
|
|
|
@@ -295,7 +375,7 @@ export class LoggerMiddleware implements NestMiddleware {
|
|
|
295
375
|
}
|
|
296
376
|
```
|
|
297
377
|
|
|
298
|
-
### Telegraf
|
|
378
|
+
### Telegraf
|
|
299
379
|
|
|
300
380
|
```typescript
|
|
301
381
|
import { Telegraf } from 'telegraf';
|
package/dist/index.d.mts
CHANGED
|
@@ -10,7 +10,12 @@ declare const LOG_LEVELS: {
|
|
|
10
10
|
type LogLevel = keyof typeof LOG_LEVELS;
|
|
11
11
|
declare function isValidLogLevel(level: string): level is LogLevel;
|
|
12
12
|
declare function assertLogLevel(level: string): asserts level is LogLevel;
|
|
13
|
+
type LogFormat = 'json' | 'plain' | 'logfmt' | 'simple';
|
|
14
|
+
interface ConsoleConfig {
|
|
15
|
+
format: LogFormat;
|
|
16
|
+
}
|
|
13
17
|
interface FileConfig {
|
|
18
|
+
format: LogFormat;
|
|
14
19
|
dirname: string;
|
|
15
20
|
filename: string;
|
|
16
21
|
datePattern?: string;
|
|
@@ -18,8 +23,20 @@ interface FileConfig {
|
|
|
18
23
|
maxSize?: string;
|
|
19
24
|
maxFiles?: string;
|
|
20
25
|
}
|
|
21
|
-
interface
|
|
26
|
+
interface LevelRule {
|
|
27
|
+
match: Record<string, unknown> & {
|
|
28
|
+
context?: string;
|
|
29
|
+
};
|
|
22
30
|
level: LogLevel;
|
|
31
|
+
}
|
|
32
|
+
interface LevelConfigObject {
|
|
33
|
+
default: LogLevel;
|
|
34
|
+
rules?: LevelRule[];
|
|
35
|
+
}
|
|
36
|
+
type LevelConfig = LogLevel | LevelConfigObject;
|
|
37
|
+
interface LoggerConfig {
|
|
38
|
+
level: LevelConfig;
|
|
39
|
+
console: ConsoleConfig;
|
|
23
40
|
file?: FileConfig;
|
|
24
41
|
}
|
|
25
42
|
type LoggerContext = Record<string, unknown>;
|
|
@@ -29,6 +46,7 @@ type LevelOverrideMatch<TContext extends LoggerContext> = Partial<TContext> & {
|
|
|
29
46
|
interface LevelOverride<TContext extends LoggerContext> {
|
|
30
47
|
match: LevelOverrideMatch<TContext>;
|
|
31
48
|
level: LogLevel;
|
|
49
|
+
readonly?: boolean;
|
|
32
50
|
}
|
|
33
51
|
type Meta = object | (() => object);
|
|
34
52
|
|
|
@@ -46,7 +64,7 @@ declare class Logger<TContext extends LoggerContext = LoggerContext> {
|
|
|
46
64
|
for(context: string): Logger<TContext>;
|
|
47
65
|
getStore(): LoggerStore<TContext>;
|
|
48
66
|
setLevelOverride(match: LevelOverrideMatch<TContext>, level: LogLevel): void;
|
|
49
|
-
removeLevelOverride(match: LevelOverrideMatch<TContext>):
|
|
67
|
+
removeLevelOverride(match: LevelOverrideMatch<TContext>): boolean;
|
|
50
68
|
clearLevelOverrides(): void;
|
|
51
69
|
getLevelOverrides(): LevelOverride<TContext>[];
|
|
52
70
|
profile(id: string, meta?: object): void;
|
|
@@ -102,4 +120,8 @@ interface MaskSecretsOptions {
|
|
|
102
120
|
declare function maskSecrets(obj: unknown, options?: MaskSecretsOptions): unknown;
|
|
103
121
|
declare function createMasker(options?: MaskSecretsOptions): (obj: unknown) => unknown;
|
|
104
122
|
|
|
105
|
-
|
|
123
|
+
declare function flattenObject(obj: Record<string, unknown>, prefix?: string): Record<string, unknown>;
|
|
124
|
+
declare function formatLogfmtValue(value: unknown): string;
|
|
125
|
+
declare function formatLogfmt(data: Record<string, unknown>): string;
|
|
126
|
+
|
|
127
|
+
export { type ConsoleConfig, type FileConfig, LOG_LEVELS, type LevelConfig, type LevelConfigObject, type LevelOverride, type LevelOverrideMatch, type LevelRule, type LogFormat, type LogLevel, Logger, type LoggerConfig, type LoggerContext, LoggerStore, type MaskSecretsOptions, type Meta, type RequestIdOptions, type SingletonLogger, type TimingResult, assertLogLevel, createMasker, createSingletonLogger, extractRequestId, flattenObject, formatLogfmt, formatLogfmtValue, generateRequestId, getOrGenerateRequestId, isValidLogLevel, maskSecrets, measureAsync, measureSync };
|
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,12 @@ declare const LOG_LEVELS: {
|
|
|
10
10
|
type LogLevel = keyof typeof LOG_LEVELS;
|
|
11
11
|
declare function isValidLogLevel(level: string): level is LogLevel;
|
|
12
12
|
declare function assertLogLevel(level: string): asserts level is LogLevel;
|
|
13
|
+
type LogFormat = 'json' | 'plain' | 'logfmt' | 'simple';
|
|
14
|
+
interface ConsoleConfig {
|
|
15
|
+
format: LogFormat;
|
|
16
|
+
}
|
|
13
17
|
interface FileConfig {
|
|
18
|
+
format: LogFormat;
|
|
14
19
|
dirname: string;
|
|
15
20
|
filename: string;
|
|
16
21
|
datePattern?: string;
|
|
@@ -18,8 +23,20 @@ interface FileConfig {
|
|
|
18
23
|
maxSize?: string;
|
|
19
24
|
maxFiles?: string;
|
|
20
25
|
}
|
|
21
|
-
interface
|
|
26
|
+
interface LevelRule {
|
|
27
|
+
match: Record<string, unknown> & {
|
|
28
|
+
context?: string;
|
|
29
|
+
};
|
|
22
30
|
level: LogLevel;
|
|
31
|
+
}
|
|
32
|
+
interface LevelConfigObject {
|
|
33
|
+
default: LogLevel;
|
|
34
|
+
rules?: LevelRule[];
|
|
35
|
+
}
|
|
36
|
+
type LevelConfig = LogLevel | LevelConfigObject;
|
|
37
|
+
interface LoggerConfig {
|
|
38
|
+
level: LevelConfig;
|
|
39
|
+
console: ConsoleConfig;
|
|
23
40
|
file?: FileConfig;
|
|
24
41
|
}
|
|
25
42
|
type LoggerContext = Record<string, unknown>;
|
|
@@ -29,6 +46,7 @@ type LevelOverrideMatch<TContext extends LoggerContext> = Partial<TContext> & {
|
|
|
29
46
|
interface LevelOverride<TContext extends LoggerContext> {
|
|
30
47
|
match: LevelOverrideMatch<TContext>;
|
|
31
48
|
level: LogLevel;
|
|
49
|
+
readonly?: boolean;
|
|
32
50
|
}
|
|
33
51
|
type Meta = object | (() => object);
|
|
34
52
|
|
|
@@ -46,7 +64,7 @@ declare class Logger<TContext extends LoggerContext = LoggerContext> {
|
|
|
46
64
|
for(context: string): Logger<TContext>;
|
|
47
65
|
getStore(): LoggerStore<TContext>;
|
|
48
66
|
setLevelOverride(match: LevelOverrideMatch<TContext>, level: LogLevel): void;
|
|
49
|
-
removeLevelOverride(match: LevelOverrideMatch<TContext>):
|
|
67
|
+
removeLevelOverride(match: LevelOverrideMatch<TContext>): boolean;
|
|
50
68
|
clearLevelOverrides(): void;
|
|
51
69
|
getLevelOverrides(): LevelOverride<TContext>[];
|
|
52
70
|
profile(id: string, meta?: object): void;
|
|
@@ -102,4 +120,8 @@ interface MaskSecretsOptions {
|
|
|
102
120
|
declare function maskSecrets(obj: unknown, options?: MaskSecretsOptions): unknown;
|
|
103
121
|
declare function createMasker(options?: MaskSecretsOptions): (obj: unknown) => unknown;
|
|
104
122
|
|
|
105
|
-
|
|
123
|
+
declare function flattenObject(obj: Record<string, unknown>, prefix?: string): Record<string, unknown>;
|
|
124
|
+
declare function formatLogfmtValue(value: unknown): string;
|
|
125
|
+
declare function formatLogfmt(data: Record<string, unknown>): string;
|
|
126
|
+
|
|
127
|
+
export { type ConsoleConfig, type FileConfig, LOG_LEVELS, type LevelConfig, type LevelConfigObject, type LevelOverride, type LevelOverrideMatch, type LevelRule, type LogFormat, type LogLevel, Logger, type LoggerConfig, type LoggerContext, LoggerStore, type MaskSecretsOptions, type Meta, type RequestIdOptions, type SingletonLogger, type TimingResult, assertLogLevel, createMasker, createSingletonLogger, extractRequestId, flattenObject, formatLogfmt, formatLogfmtValue, generateRequestId, getOrGenerateRequestId, isValidLogLevel, maskSecrets, measureAsync, measureSync };
|