@arivlabs/logger 1.4.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +70 -0
- package/README.md +238 -86
- package/dist/index.d.ts +247 -68
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +392 -82
- package/dist/index.js.map +1 -1
- package/dist/index.test.js +237 -93
- package/dist/index.test.js.map +1 -1
- package/package.json +6 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,49 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
*
|
|
2
|
+
* @arivlabs/logger v2.0.0
|
|
3
|
+
*
|
|
4
|
+
* Structured logging for Node.js services with CloudWatch support.
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Async logging by default (high performance, non-blocking via SonicBoom)
|
|
8
|
+
* - Crash-safe logging via synchronous flush on fatal errors
|
|
9
|
+
* - Flexible types (define your own service/domain types)
|
|
10
|
+
* - Automatic sensitive data redaction
|
|
11
|
+
* - Child loggers with context
|
|
12
|
+
* - Graceful shutdown with proper drain handling
|
|
13
|
+
* - Buffer metrics for operational observability
|
|
14
|
+
*
|
|
15
|
+
* Architecture Notes:
|
|
16
|
+
* - Production mode uses pino.destination() (SonicBoom) for buffered async writes
|
|
17
|
+
* - SonicBoom provides flushSync() for crash-safe logging before process exit
|
|
18
|
+
* - Pretty mode uses pino-pretty transport (worker thread) - flush() is a no-op
|
|
19
|
+
* - Sync mode (enableAsync: false) writes immediately - flush() is a no-op
|
|
20
|
+
* - pino.final() was deprecated in Node 14+ and removed in pino v10; we use
|
|
21
|
+
* direct flushSync() calls instead for crash-safe logging
|
|
22
|
+
* - Timestamps use ISO 8601 format with field name "time" (same as pino.stdTimeFunctions.isoTime)
|
|
23
|
+
*
|
|
24
|
+
* Operational Considerations:
|
|
25
|
+
* - Async logging can lose buffered logs on abrupt process termination (SIGKILL, OOM)
|
|
26
|
+
* - flushSync() is best-effort; under extreme backpressure, logs may still be dropped
|
|
27
|
+
* - Worker thread transports (pretty mode) have different ordering/timing guarantees
|
|
28
|
+
* - Use getBufferMetrics() to monitor buffer state in production
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* import { createLogger } from '@arivlabs/logger';
|
|
33
|
+
*
|
|
34
|
+
* const logger = createLogger({ service: 'my-service' });
|
|
35
|
+
*
|
|
36
|
+
* logger.info('Server started', { port: 3000 });
|
|
37
|
+
* logger.domain('auth').info('User logged in', { userId: '123' });
|
|
38
|
+
*
|
|
39
|
+
* // IMPORTANT: Call on shutdown to flush buffered logs
|
|
40
|
+
* process.on('SIGTERM', async () => {
|
|
41
|
+
* await logger.shutdown();
|
|
42
|
+
* process.exit(0);
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
7
45
|
*/
|
|
8
|
-
|
|
46
|
+
import { type Logger as PinoLogger } from 'pino';
|
|
9
47
|
/**
|
|
10
48
|
* Redaction configuration for masking sensitive data
|
|
11
49
|
*/
|
|
@@ -25,36 +63,85 @@ export interface RedactConfig {
|
|
|
25
63
|
remove?: boolean;
|
|
26
64
|
}
|
|
27
65
|
/**
|
|
28
|
-
* Default sensitive field patterns that are always redacted
|
|
29
|
-
* These
|
|
66
|
+
* Default sensitive field patterns that are always redacted.
|
|
67
|
+
* These cover common security-sensitive fields.
|
|
68
|
+
*
|
|
69
|
+
* Note: This is a readonly tuple. When merged with user paths, the result is string[].
|
|
30
70
|
*/
|
|
31
|
-
export declare const DEFAULT_REDACT_PATHS: readonly ["password", "secret", "token", "apiKey", "api_key", "accessToken", "access_token", "refreshToken", "refresh_token", "sessionToken", "session_token", "secretAccessKey", "secret_access_key", "privateKey", "private_key", "*.password", "*.secret", "*.token", "*.apiKey", "*.api_key", "*.accessToken", "*.secretAccessKey", "*.privateKey", "req.headers.authorization", "req.headers.cookie", "req.headers[\"x-api-key\"]", "credentials.accessKeyId", "credentials.secretAccessKey", "credentials.sessionToken"];
|
|
71
|
+
export declare const DEFAULT_REDACT_PATHS: readonly ["password", "secret", "token", "apiKey", "api_key", "accessToken", "access_token", "refreshToken", "refresh_token", "sessionToken", "session_token", "secretAccessKey", "secret_access_key", "privateKey", "private_key", "*.password", "*.secret", "*.token", "*.apiKey", "*.api_key", "*.accessToken", "*.refreshToken", "*.secretAccessKey", "*.privateKey", "req.headers.authorization", "req.headers.cookie", "req.headers[\"x-api-key\"]", "credentials.accessKeyId", "credentials.secretAccessKey", "credentials.sessionToken"];
|
|
32
72
|
/**
|
|
33
73
|
* Logger configuration options
|
|
34
74
|
*/
|
|
35
75
|
export interface LoggerConfig {
|
|
36
|
-
/** Service name (e.g., 'api-gateway') */
|
|
37
|
-
service:
|
|
38
|
-
/** Environment (defaults to NODE_ENV or 'development') */
|
|
76
|
+
/** Service name (e.g., 'api-gateway', 'worker-service') */
|
|
77
|
+
service: string;
|
|
78
|
+
/** Environment (defaults to ENV or NODE_ENV or 'development') */
|
|
39
79
|
environment?: string;
|
|
40
80
|
/** Log level (defaults to 'debug' in dev, 'info' in prod) */
|
|
41
81
|
level?: string;
|
|
42
|
-
/** Enable pretty printing (defaults to true in development) */
|
|
82
|
+
/** Enable pretty printing (defaults to true in development/local) */
|
|
43
83
|
pretty?: boolean;
|
|
44
84
|
/**
|
|
45
|
-
* Redaction configuration for masking sensitive data
|
|
85
|
+
* Redaction configuration for masking sensitive data.
|
|
46
86
|
* Sensitive fields are automatically masked. Use this to add custom paths.
|
|
47
87
|
*/
|
|
48
88
|
redact?: RedactConfig;
|
|
89
|
+
/**
|
|
90
|
+
* Enable async (buffered) logging mode.
|
|
91
|
+
*
|
|
92
|
+
* - `true`: Logs are buffered and written asynchronously (high performance).
|
|
93
|
+
* You MUST call `logger.shutdown()` before process exit.
|
|
94
|
+
* - `false`: All logs are written synchronously (guaranteed immediate write).
|
|
95
|
+
* - Default: `true` in production, `false` in development/local/test.
|
|
96
|
+
*/
|
|
97
|
+
enableAsync?: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Buffer size before auto-flush in async mode (default: 4096 bytes).
|
|
100
|
+
* Lower = more frequent writes, higher = better batching.
|
|
101
|
+
*/
|
|
102
|
+
asyncBufferSize?: number;
|
|
103
|
+
/**
|
|
104
|
+
* Custom base fields to include in every log entry.
|
|
105
|
+
*/
|
|
106
|
+
base?: Record<string, unknown>;
|
|
107
|
+
/**
|
|
108
|
+
* Register handlers for uncaughtException and unhandledRejection.
|
|
109
|
+
* When true, these events will be logged with synchronous flush for crash-safety.
|
|
110
|
+
*
|
|
111
|
+
* In production mode (SonicBoom destination), flushSync() ensures buffered logs
|
|
112
|
+
* are written before process exit. This is best-effort - under extreme conditions
|
|
113
|
+
* (SIGKILL, OOM, system crash), some logs may still be lost.
|
|
114
|
+
*
|
|
115
|
+
* In pretty mode (development), logs are sent to a worker thread transport
|
|
116
|
+
* and crash-safe delivery cannot be guaranteed.
|
|
117
|
+
*
|
|
118
|
+
* Default: false (opt-in for safety).
|
|
119
|
+
*/
|
|
120
|
+
handleExceptions?: boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Whether to call process.exit(1) after logging fatal errors from
|
|
123
|
+
* uncaughtException/unhandledRejection handlers.
|
|
124
|
+
*
|
|
125
|
+
* - `true`: Logger will exit the process after logging (default for backward compat)
|
|
126
|
+
* - `false`: Logger only logs, allowing app to handle exit and other cleanup
|
|
127
|
+
*
|
|
128
|
+
* Setting this to `false` is recommended when:
|
|
129
|
+
* - You have other cleanup to perform (DB connections, metrics, etc.)
|
|
130
|
+
* - You have other exception handlers installed
|
|
131
|
+
* - You want the app to control exit behavior
|
|
132
|
+
*
|
|
133
|
+
* Only applies when handleExceptions is true.
|
|
134
|
+
* Default: true
|
|
135
|
+
*/
|
|
136
|
+
exitOnFatal?: boolean;
|
|
49
137
|
}
|
|
50
138
|
/**
|
|
51
|
-
* Log data object
|
|
52
|
-
* Pass Error objects as `err` or `error` - both work and will be serialized properly
|
|
139
|
+
* Log data object.
|
|
140
|
+
* Pass Error objects as `err` or `error` - both work and will be serialized properly.
|
|
53
141
|
*
|
|
54
142
|
* @example
|
|
55
143
|
* logger.error('Request failed', { err: error }); // Works
|
|
56
144
|
* logger.error('Request failed', { error: error }); // Also works - auto-converted to err
|
|
57
|
-
* logger.error('Request failed', { error: err.message }); // Bad - loses error type/stack
|
|
58
145
|
*/
|
|
59
146
|
export type LogData = Record<string, unknown> & {
|
|
60
147
|
/** Pass Error objects here for proper serialization (type, message, stack, custom props) */
|
|
@@ -63,17 +150,56 @@ export type LogData = Record<string, unknown> & {
|
|
|
63
150
|
error?: Error | unknown;
|
|
64
151
|
};
|
|
65
152
|
/**
|
|
66
|
-
* Flexible log method signature supporting multiple calling conventions
|
|
153
|
+
* Flexible log method signature supporting multiple calling conventions.
|
|
67
154
|
*/
|
|
68
155
|
export interface FlexibleLogFn {
|
|
156
|
+
/** String message with optional data object (intuitive style) */
|
|
69
157
|
(msg: string, data?: LogData): void;
|
|
158
|
+
/** Object with msg property (pino native style) */
|
|
70
159
|
(obj: LogData & {
|
|
71
160
|
msg?: string;
|
|
72
161
|
}): void;
|
|
162
|
+
/** Object first, then message (pino native style) */
|
|
73
163
|
(obj: LogData, msg?: string): void;
|
|
74
164
|
}
|
|
75
165
|
/**
|
|
76
|
-
*
|
|
166
|
+
* Request context for correlation tracking.
|
|
167
|
+
*/
|
|
168
|
+
export interface RequestContext {
|
|
169
|
+
/** Correlation ID for request tracing */
|
|
170
|
+
correlationId: string;
|
|
171
|
+
/** Optional user ID */
|
|
172
|
+
userId?: string;
|
|
173
|
+
/** Optional tenant ID */
|
|
174
|
+
tenantId?: string;
|
|
175
|
+
/** Optional domain context */
|
|
176
|
+
domain?: string;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Buffer metrics for operational observability.
|
|
180
|
+
* Use these to monitor logger health and detect backpressure issues.
|
|
181
|
+
*/
|
|
182
|
+
export interface BufferMetrics {
|
|
183
|
+
/** Whether the logger is operating in async (buffered) mode */
|
|
184
|
+
isAsync: boolean;
|
|
185
|
+
/** Whether the logger is in pretty mode (worker thread transport) */
|
|
186
|
+
isPrettyMode: boolean;
|
|
187
|
+
/** Whether buffer metrics are available (false in pretty mode) */
|
|
188
|
+
metricsAvailable: boolean;
|
|
189
|
+
/**
|
|
190
|
+
* Whether the underlying stream is currently experiencing backpressure.
|
|
191
|
+
* When true, writes may be queued or dropped depending on configuration.
|
|
192
|
+
* Only available when metricsAvailable is true.
|
|
193
|
+
*/
|
|
194
|
+
isBackpressured?: boolean;
|
|
195
|
+
/**
|
|
196
|
+
* Whether the destination stream is destroyed/closed.
|
|
197
|
+
* Only available when metricsAvailable is true.
|
|
198
|
+
*/
|
|
199
|
+
isDestroyed?: boolean;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Extended logger interface with domain support and flexible API.
|
|
77
203
|
*/
|
|
78
204
|
export interface ArivLogger {
|
|
79
205
|
/** Log at trace level */
|
|
@@ -88,53 +214,97 @@ export interface ArivLogger {
|
|
|
88
214
|
error: FlexibleLogFn;
|
|
89
215
|
/** Log at fatal level */
|
|
90
216
|
fatal: FlexibleLogFn;
|
|
91
|
-
/**
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
217
|
+
/**
|
|
218
|
+
* Create a child logger for a specific domain.
|
|
219
|
+
* @example
|
|
220
|
+
* const authLogger = logger.domain('auth');
|
|
221
|
+
* authLogger.info('User logged in', { userId });
|
|
222
|
+
*/
|
|
223
|
+
domain(name: string): ArivLogger;
|
|
224
|
+
/**
|
|
225
|
+
* Create a child logger with request context.
|
|
226
|
+
* @example
|
|
227
|
+
* const reqLogger = logger.withContext({
|
|
228
|
+
* correlationId: 'abc-123',
|
|
229
|
+
* tenantId: 'tenant-1',
|
|
230
|
+
* domain: 'discovery'
|
|
231
|
+
* });
|
|
232
|
+
*/
|
|
233
|
+
withContext(context: RequestContext): ArivLogger;
|
|
234
|
+
/**
|
|
235
|
+
* Create a child logger with additional bindings.
|
|
236
|
+
* @example
|
|
237
|
+
* const jobLogger = logger.child({ jobId: '123' });
|
|
238
|
+
*/
|
|
239
|
+
child(bindings: LogData): ArivLogger;
|
|
240
|
+
/** Check if a log level is enabled */
|
|
241
|
+
isLevelEnabled(level: string): boolean;
|
|
242
|
+
/** Current log level (readable and writable) */
|
|
100
243
|
level: string;
|
|
244
|
+
/**
|
|
245
|
+
* Flush all buffered logs to destination synchronously.
|
|
246
|
+
*
|
|
247
|
+
* **Important: This is a no-op in the following cases:**
|
|
248
|
+
* - Pretty mode (development): pino-pretty runs in a worker thread without flushSync()
|
|
249
|
+
* - Sync mode (`enableAsync: false`): Writes are immediate, no buffer to flush
|
|
250
|
+
*
|
|
251
|
+
* Only performs work when ALL conditions are met:
|
|
252
|
+
* - Production mode (JSON output with SonicBoom destination)
|
|
253
|
+
* - Async mode enabled (`enableAsync: true` or production defaults)
|
|
254
|
+
* - Buffer has pending data (`minLength > 0`)
|
|
255
|
+
*
|
|
256
|
+
* For guaranteed delivery during shutdown, use shutdown() instead.
|
|
257
|
+
*/
|
|
258
|
+
flush(): void;
|
|
259
|
+
/**
|
|
260
|
+
* Graceful shutdown - flushes logs and prepares for exit.
|
|
261
|
+
* Call this on SIGTERM/SIGINT handlers before process.exit().
|
|
262
|
+
*
|
|
263
|
+
* This method:
|
|
264
|
+
* 1. Cleans up exception handlers if registered
|
|
265
|
+
* 2. Synchronously flushes the buffer (production mode only)
|
|
266
|
+
* 3. Closes the destination stream with a 5s timeout
|
|
267
|
+
*
|
|
268
|
+
* In pretty mode (development), this is largely a no-op since the
|
|
269
|
+
* pino-pretty transport runs in a worker thread.
|
|
270
|
+
*
|
|
271
|
+
* @returns Promise that resolves when shutdown is complete
|
|
272
|
+
*/
|
|
273
|
+
shutdown(): Promise<void>;
|
|
274
|
+
/**
|
|
275
|
+
* Get buffer metrics for operational observability.
|
|
276
|
+
* Use this to monitor logger health and detect backpressure issues.
|
|
277
|
+
*
|
|
278
|
+
* Note: In pretty mode, detailed metrics are not available since the
|
|
279
|
+
* transport runs in a worker thread.
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* ```typescript
|
|
283
|
+
* // Monitor buffer health
|
|
284
|
+
* setInterval(() => {
|
|
285
|
+
* const metrics = logger.getBufferMetrics();
|
|
286
|
+
* if (metrics.isBackpressured) {
|
|
287
|
+
* console.warn('Logger buffer backpressure detected');
|
|
288
|
+
* }
|
|
289
|
+
* }, 5000);
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
getBufferMetrics(): BufferMetrics;
|
|
293
|
+
/** Access to underlying pino logger (for advanced use cases) */
|
|
294
|
+
readonly pino: PinoLogger;
|
|
101
295
|
}
|
|
102
296
|
/**
|
|
103
|
-
*
|
|
104
|
-
*/
|
|
105
|
-
export interface RequestContext {
|
|
106
|
-
correlationId: string;
|
|
107
|
-
userId?: string;
|
|
108
|
-
tenantId?: string;
|
|
109
|
-
domain?: LogDomain;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Create a structured logger for an ArivLabs service
|
|
113
|
-
*
|
|
114
|
-
* Supports flexible calling conventions:
|
|
115
|
-
* - Intuitive style: `logger.info('Message', { key: value })`
|
|
116
|
-
* - Pino native style: `logger.info({ msg: 'Message', key: value })`
|
|
297
|
+
* Create a structured logger for a service.
|
|
117
298
|
*
|
|
118
299
|
* @example
|
|
119
300
|
* ```typescript
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
* const logger = createLogger({ service: 'api-gateway' });
|
|
123
|
-
*
|
|
124
|
-
* // Basic logging (intuitive style - recommended)
|
|
301
|
+
* // Basic usage
|
|
302
|
+
* const logger = createLogger({ service: 'my-service' });
|
|
125
303
|
* logger.info('Server started', { port: 3000 });
|
|
126
304
|
*
|
|
127
|
-
* // Error logging - both { err } and { error } work
|
|
128
|
-
* logger.error('Request failed', { err: error }); // ✅ Works
|
|
129
|
-
* logger.error('Request failed', { error: error }); // ✅ Also works
|
|
130
|
-
* logger.error('Request failed', { error: err.message }); // ❌ Bad - pass Error object
|
|
131
|
-
*
|
|
132
|
-
* // Also works: pino native style
|
|
133
|
-
* logger.info({ msg: 'Server started', port: 3000 });
|
|
134
|
-
*
|
|
135
305
|
* // Domain-specific logging
|
|
136
|
-
* const
|
|
137
|
-
*
|
|
306
|
+
* const authLog = logger.domain('auth');
|
|
307
|
+
* authLog.info('User logged in', { userId: '123' });
|
|
138
308
|
*
|
|
139
309
|
* // Request context logging
|
|
140
310
|
* const reqLog = logger.withContext({
|
|
@@ -142,25 +312,34 @@ export interface RequestContext {
|
|
|
142
312
|
* tenantId: 'tenant-1',
|
|
143
313
|
* domain: 'discovery'
|
|
144
314
|
* });
|
|
145
|
-
*
|
|
315
|
+
*
|
|
316
|
+
* // Error logging - both { err } and { error } work
|
|
317
|
+
* logger.error('Request failed', { err: error });
|
|
318
|
+
* logger.error('Request failed', { error }); // Auto-converted
|
|
319
|
+
*
|
|
320
|
+
* // IMPORTANT: Graceful shutdown (required for async mode)
|
|
321
|
+
* process.on('SIGTERM', async () => {
|
|
322
|
+
* await logger.shutdown();
|
|
323
|
+
* process.exit(0);
|
|
324
|
+
* });
|
|
146
325
|
* ```
|
|
147
326
|
*
|
|
148
327
|
* CloudWatch Insights queries:
|
|
149
|
-
* - Filter by service: `
|
|
150
|
-
* - Filter by domain: `
|
|
151
|
-
* - Filter errors: `
|
|
152
|
-
* - Filter by tenant: `
|
|
328
|
+
* - Filter by service: `filter service = "my-service"`
|
|
329
|
+
* - Filter by domain: `filter domain = "auth"`
|
|
330
|
+
* - Filter errors: `filter level >= 50`
|
|
331
|
+
* - Filter by tenant: `filter tenant_id = "xxx"`
|
|
153
332
|
*/
|
|
154
333
|
export declare function createLogger(config: LoggerConfig): ArivLogger;
|
|
155
334
|
/**
|
|
156
|
-
* Create a domain-specific child logger
|
|
157
|
-
* @deprecated Use logger.domain() instead
|
|
335
|
+
* Create a domain-specific child logger.
|
|
336
|
+
* @deprecated Use `logger.domain(name)` instead.
|
|
158
337
|
*/
|
|
159
|
-
export declare function createDomainLogger(logger: ArivLogger, domain:
|
|
338
|
+
export declare function createDomainLogger(logger: ArivLogger, domain: string): ArivLogger;
|
|
160
339
|
/**
|
|
161
|
-
* Create a child logger with request context
|
|
162
|
-
* @deprecated Use logger.withContext() instead
|
|
340
|
+
* Create a child logger with request context.
|
|
341
|
+
* @deprecated Use `logger.withContext()` instead.
|
|
163
342
|
*/
|
|
164
|
-
export declare function createRequestLogger(logger: ArivLogger, domain:
|
|
343
|
+
export declare function createRequestLogger(logger: ArivLogger, domain: string, correlationId: string, userId?: string, tenantId?: string): ArivLogger;
|
|
165
344
|
export type { Logger as PinoLogger } from 'pino';
|
|
166
345
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|