ntlogger 2.9.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +237 -2
- package/index.d.ts +192 -183
- package/lib/lifecycle.js +53 -0
- package/lib/logger.js +100 -57
- package/lib/pinoHooks.js +446 -0
- package/lib/processHandlers.js +305 -0
- package/lib/secretRedaction.js +675 -0
- package/lib/signalHandler.js +31 -48
- package/package.json +69 -13
- package/pino.d.ts +287 -0
- package/pino.js +434 -13
- package/plugins/README.md +129 -1
- package/plugins/discord.js +30 -48
- package/plugins/index.js +27 -11
- package/plugins/lib/httpDelivery.js +98 -0
- package/plugins/lib/syslogClient.js +18 -8
- package/plugins/mysql.js +73 -83
- package/plugins/openobserve.js +33 -207
- package/plugins/otel.js +263 -0
- package/plugins/postgres.js +69 -67
- package/plugins/sentry.js +36 -3
- package/plugins/syslog.js +6 -9
- package/plugins/teams.js +16 -67
- package/transports/pino.js +188 -12
package/index.d.ts
CHANGED
|
@@ -3,214 +3,218 @@
|
|
|
3
3
|
* @file index.d.ts
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
* Log levels supported by NightTimeLogger
|
|
8
|
-
*/
|
|
9
|
-
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'internal';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Sampling configuration for log levels
|
|
13
|
-
*/
|
|
14
|
-
export interface SamplingConfig {
|
|
15
|
-
[level: string]: number; // 0.0 to 1.0, where 1.0 = log all, 0.1 = log 10%
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Rate limit configuration for a log level
|
|
20
|
-
*/
|
|
21
|
-
export interface RateLimitConfig {
|
|
22
|
-
max: number; // Maximum number of logs
|
|
23
|
-
window: number; // Time window in milliseconds
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Rate limiting configuration for log levels
|
|
28
|
-
*/
|
|
29
|
-
export interface RateLimitConfigMap {
|
|
30
|
-
[level: string]: RateLimitConfig;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Deduplication configuration
|
|
35
|
-
*/
|
|
36
|
-
export interface DeduplicationConfig {
|
|
37
|
-
enabled: boolean;
|
|
38
|
-
threshold: number; // Number of duplicates before squishing (default: 3)
|
|
39
|
-
window: number; // Time window in milliseconds (default: 60000)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Plugin configuration
|
|
44
|
-
*/
|
|
45
|
-
export interface PluginConfig {
|
|
46
|
-
name: string;
|
|
47
|
-
enabled?: boolean;
|
|
48
|
-
config?: Record<string, any>;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Logger configuration options
|
|
53
|
-
*/
|
|
54
|
-
export interface LoggerConfig {
|
|
55
|
-
/** Minimum log level to be logged */
|
|
56
|
-
level?: LogLevel;
|
|
57
|
-
/** Enable console logging (default: true) */
|
|
58
|
-
console?: boolean;
|
|
59
|
-
/** Enable file logging (default: true) */
|
|
60
|
-
file?: boolean;
|
|
61
|
-
/** Filename for log file (default: `${location}.log`) */
|
|
62
|
-
filename?: string;
|
|
63
|
-
/** Directory path where log files will be saved (default: './logs') */
|
|
64
|
-
path?: string;
|
|
65
|
-
/** Maximum size of log file in bytes (default: 1048576 = 1MB) */
|
|
66
|
-
maxSize?: number;
|
|
67
|
-
/** Maximum number of log files to retain (default: 5) */
|
|
68
|
-
maxFiles?: number;
|
|
69
|
-
/** Include timestamp in log messages (default: true) */
|
|
70
|
-
timestamp?: boolean;
|
|
71
|
-
/** Skip cache and create new logger instance (default: false) */
|
|
72
|
-
skipCache?: boolean;
|
|
73
|
-
/** Enable call site path reporting (default: false) */
|
|
74
|
-
reportPath?: boolean;
|
|
75
|
-
/** Enable debug mode for logger itself (default: false) */
|
|
76
|
-
debug?: boolean;
|
|
77
|
-
/** Log sampling rates per level */
|
|
78
|
-
sampling?: SamplingConfig;
|
|
79
|
-
/** Rate limiting configuration per level */
|
|
80
|
-
rateLimit?: RateLimitConfigMap;
|
|
81
|
-
/** Log deduplication configuration */
|
|
82
|
-
deduplication?: DeduplicationConfig;
|
|
83
|
-
/** Enable performance metrics (default: NODE_ENV === 'development') */
|
|
84
|
-
performanceMetrics?: boolean;
|
|
85
|
-
/** Interval in milliseconds to log statistics (default: 0 = disabled) */
|
|
86
|
-
statsInterval?: number;
|
|
87
|
-
/** Plugin configurations */
|
|
88
|
-
plugins?: PluginConfig[];
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Statistics object returned by getStats()
|
|
93
|
-
*/
|
|
94
|
-
export interface LoggerStats {
|
|
95
|
-
sampling: {
|
|
96
|
-
total: Record<string, number>;
|
|
97
|
-
sampled: Record<string, number>;
|
|
98
|
-
rateLimited: Record<string, number>;
|
|
99
|
-
} | null;
|
|
100
|
-
deduplication: {
|
|
101
|
-
totalDeduplicated: number;
|
|
102
|
-
uniqueMessages: number;
|
|
103
|
-
activeEntries: number;
|
|
104
|
-
} | null;
|
|
105
|
-
performance: {
|
|
106
|
-
enabled: boolean;
|
|
107
|
-
avgLogProcessingTime?: number;
|
|
108
|
-
avgTransportTime?: number;
|
|
109
|
-
logProcessingSamples?: number;
|
|
110
|
-
transportSamples?: number;
|
|
111
|
-
} | null;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Logger instance interface
|
|
116
|
-
*/
|
|
117
|
-
export interface Logger {
|
|
118
|
-
/**
|
|
119
|
-
* Log an informational message
|
|
120
|
-
* @param message - The message to log
|
|
121
|
-
* @param meta - Optional metadata object
|
|
122
|
-
*/
|
|
123
|
-
info(message: string, meta?: Record<string, any>): void;
|
|
124
|
-
info(message: Record<string, any>): void;
|
|
125
|
-
|
|
6
|
+
declare namespace logger {
|
|
126
7
|
/**
|
|
127
|
-
* Log
|
|
128
|
-
* @param message - The message to log
|
|
129
|
-
* @param meta - Optional metadata object
|
|
8
|
+
* Log levels supported by NightTimeLogger
|
|
130
9
|
*/
|
|
131
|
-
warn
|
|
132
|
-
warn(message: Record<string, any>): void;
|
|
10
|
+
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'internal';
|
|
133
11
|
|
|
134
12
|
/**
|
|
135
|
-
*
|
|
136
|
-
* @param message - The message to log
|
|
137
|
-
* @param meta - Optional metadata object
|
|
13
|
+
* Sampling configuration for log levels
|
|
138
14
|
*/
|
|
139
|
-
|
|
140
|
-
|
|
15
|
+
export interface SamplingConfig {
|
|
16
|
+
[level: string]: number; // 0.0 to 1.0, where 1.0 = log all, 0.1 = log 10%
|
|
17
|
+
}
|
|
141
18
|
|
|
142
19
|
/**
|
|
143
|
-
*
|
|
144
|
-
* @param message - The message to log
|
|
145
|
-
* @param meta - Optional metadata object
|
|
20
|
+
* Rate limit configuration for a log level
|
|
146
21
|
*/
|
|
147
|
-
|
|
148
|
-
|
|
22
|
+
export interface RateLimitConfig {
|
|
23
|
+
max: number; // Maximum number of logs
|
|
24
|
+
window: number; // Time window in milliseconds
|
|
25
|
+
}
|
|
149
26
|
|
|
150
27
|
/**
|
|
151
|
-
*
|
|
152
|
-
* @param message - The message to log
|
|
153
|
-
* @param meta - Optional metadata object
|
|
28
|
+
* Rate limiting configuration for log levels
|
|
154
29
|
*/
|
|
155
|
-
|
|
156
|
-
|
|
30
|
+
export interface RateLimitConfigMap {
|
|
31
|
+
[level: string]: RateLimitConfig;
|
|
32
|
+
}
|
|
157
33
|
|
|
158
34
|
/**
|
|
159
|
-
*
|
|
160
|
-
* @param message - The message to log
|
|
161
|
-
* @param meta - Optional metadata object
|
|
35
|
+
* Deduplication configuration
|
|
162
36
|
*/
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
* @param message - The message to log
|
|
169
|
-
* @param meta - Optional metadata object
|
|
170
|
-
*/
|
|
171
|
-
internal(message: string, meta?: Record<string, any>): void;
|
|
172
|
-
internal(message: Record<string, any>): void;
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Create a child logger with persistent context
|
|
176
|
-
* @param context - Context object to merge into all logs
|
|
177
|
-
* @returns Child logger instance
|
|
178
|
-
*/
|
|
179
|
-
child(context: Record<string, any>): Logger;
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Start a performance timer (development mode only)
|
|
183
|
-
* @param label - Timer label
|
|
184
|
-
*/
|
|
185
|
-
time?(label: string): void;
|
|
37
|
+
export interface DeduplicationConfig {
|
|
38
|
+
enabled: boolean;
|
|
39
|
+
threshold: number; // Number of duplicates before squishing (default: 3)
|
|
40
|
+
window: number; // Time window in milliseconds (default: 60000)
|
|
41
|
+
}
|
|
186
42
|
|
|
187
43
|
/**
|
|
188
|
-
*
|
|
189
|
-
* @param label - Timer label
|
|
190
|
-
* @returns Duration in milliseconds or null if timer not found
|
|
44
|
+
* Plugin configuration
|
|
191
45
|
*/
|
|
192
|
-
|
|
46
|
+
export interface PluginConfig {
|
|
47
|
+
name: string;
|
|
48
|
+
enabled?: boolean;
|
|
49
|
+
config?: Record<string, any>;
|
|
50
|
+
}
|
|
193
51
|
|
|
194
52
|
/**
|
|
195
|
-
*
|
|
196
|
-
* @returns Statistics object
|
|
53
|
+
* Logger configuration options
|
|
197
54
|
*/
|
|
198
|
-
|
|
55
|
+
export interface LoggerConfig {
|
|
56
|
+
/** Minimum log level to be logged */
|
|
57
|
+
level?: LogLevel;
|
|
58
|
+
/** Enable console logging (default: true) */
|
|
59
|
+
console?: boolean;
|
|
60
|
+
/** Enable file logging (default: true) */
|
|
61
|
+
file?: boolean;
|
|
62
|
+
/** Filename for combined log file (default: combined.log) */
|
|
63
|
+
filename?: string;
|
|
64
|
+
/** Directory path where log files will be saved (default: './logs') */
|
|
65
|
+
path?: string;
|
|
66
|
+
/** Maximum size of log file in bytes (default: 1048576 = 1MB) */
|
|
67
|
+
maxSize?: number;
|
|
68
|
+
/** Maximum number of log files to retain (default: 5) */
|
|
69
|
+
maxFiles?: number;
|
|
70
|
+
/** Include timestamp in log messages (default: true) */
|
|
71
|
+
timestamp?: boolean;
|
|
72
|
+
/** Skip cache and create new logger instance (default: false) */
|
|
73
|
+
skipCache?: boolean;
|
|
74
|
+
/** Enable call site path reporting (default: false) */
|
|
75
|
+
reportPath?: boolean;
|
|
76
|
+
/** Enable debug mode for logger itself (default: false) */
|
|
77
|
+
debug?: boolean;
|
|
78
|
+
/** Log sampling rates per level */
|
|
79
|
+
sampling?: SamplingConfig;
|
|
80
|
+
/** Rate limiting configuration per level */
|
|
81
|
+
rateLimit?: RateLimitConfigMap;
|
|
82
|
+
/** Log deduplication configuration */
|
|
83
|
+
deduplication?: DeduplicationConfig;
|
|
84
|
+
/** Enable performance metrics (default: NODE_ENV === 'development') */
|
|
85
|
+
performanceMetrics?: boolean;
|
|
86
|
+
/** Interval in milliseconds to log statistics (default: 0 = disabled) */
|
|
87
|
+
statsInterval?: number;
|
|
88
|
+
/** Maximum flush/stream shutdown wait in milliseconds (default: 30000). */
|
|
89
|
+
shutdownTimeout?: number;
|
|
90
|
+
/** Plugin configurations */
|
|
91
|
+
plugins?: PluginConfig[];
|
|
92
|
+
}
|
|
199
93
|
|
|
200
94
|
/**
|
|
201
|
-
*
|
|
202
|
-
* @returns Promise that resolves when all logs are flushed
|
|
95
|
+
* Statistics object returned by getStats()
|
|
203
96
|
*/
|
|
204
|
-
|
|
97
|
+
export interface LoggerStats {
|
|
98
|
+
sampling: {
|
|
99
|
+
total: Record<string, number>;
|
|
100
|
+
sampled: Record<string, number>;
|
|
101
|
+
rateLimited: Record<string, number>;
|
|
102
|
+
} | null;
|
|
103
|
+
deduplication: {
|
|
104
|
+
totalDeduplicated: number;
|
|
105
|
+
uniqueMessages: number;
|
|
106
|
+
activeEntries: number;
|
|
107
|
+
} | null;
|
|
108
|
+
performance: {
|
|
109
|
+
enabled: boolean;
|
|
110
|
+
avgLogProcessingTime?: number;
|
|
111
|
+
avgTransportTime?: number;
|
|
112
|
+
logProcessingSamples?: number;
|
|
113
|
+
transportSamples?: number;
|
|
114
|
+
} | null;
|
|
115
|
+
}
|
|
205
116
|
|
|
206
117
|
/**
|
|
207
|
-
*
|
|
208
|
-
* @returns Promise that resolves when logger is closed
|
|
118
|
+
* Logger instance interface
|
|
209
119
|
*/
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
120
|
+
export interface Logger {
|
|
121
|
+
/**
|
|
122
|
+
* Log an informational message
|
|
123
|
+
* @param message - The message to log
|
|
124
|
+
* @param meta - Optional metadata object
|
|
125
|
+
*/
|
|
126
|
+
info(message: string, meta?: Record<string, any>): void;
|
|
127
|
+
info(message: Record<string, any>): void;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Log a warning message
|
|
131
|
+
* @param message - The message to log
|
|
132
|
+
* @param meta - Optional metadata object
|
|
133
|
+
*/
|
|
134
|
+
warn(message: string, meta?: Record<string, any>): void;
|
|
135
|
+
warn(message: Record<string, any>): void;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Log an error message
|
|
139
|
+
* @param message - The message to log
|
|
140
|
+
* @param meta - Optional metadata object
|
|
141
|
+
*/
|
|
142
|
+
error(message: string, meta?: Record<string, any>): void;
|
|
143
|
+
error(message: Record<string, any>): void;
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Log a debug message
|
|
147
|
+
* @param message - The message to log
|
|
148
|
+
* @param meta - Optional metadata object
|
|
149
|
+
*/
|
|
150
|
+
debug(message: string, meta?: Record<string, any>): void;
|
|
151
|
+
debug(message: Record<string, any>): void;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Log a trace message
|
|
155
|
+
* @param message - The message to log
|
|
156
|
+
* @param meta - Optional metadata object
|
|
157
|
+
*/
|
|
158
|
+
trace(message: string, meta?: Record<string, any>): void;
|
|
159
|
+
trace(message: Record<string, any>): void;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Log a fatal message
|
|
163
|
+
* @param message - The message to log
|
|
164
|
+
* @param meta - Optional metadata object
|
|
165
|
+
*/
|
|
166
|
+
fatal(message: string, meta?: Record<string, any>): void;
|
|
167
|
+
fatal(message: Record<string, any>): void;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Log an internal message (logger system messages)
|
|
171
|
+
* @param message - The message to log
|
|
172
|
+
* @param meta - Optional metadata object
|
|
173
|
+
*/
|
|
174
|
+
internal(message: string, meta?: Record<string, any>): void;
|
|
175
|
+
internal(message: Record<string, any>): void;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Create a child logger with persistent context
|
|
179
|
+
* @param context - Context object to merge into all logs
|
|
180
|
+
* @returns Child logger instance
|
|
181
|
+
*/
|
|
182
|
+
child(context: Record<string, any>): Logger;
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Start a performance timer (development mode only)
|
|
186
|
+
* @param label - Timer label
|
|
187
|
+
*/
|
|
188
|
+
time?(label: string): void;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* End a performance timer and log duration (development mode only)
|
|
192
|
+
* @param label - Timer label
|
|
193
|
+
* @returns Duration in milliseconds or null if timer not found
|
|
194
|
+
*/
|
|
195
|
+
timeEnd?(label: string): number | null;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Get logging statistics
|
|
199
|
+
* @returns Statistics object
|
|
200
|
+
*/
|
|
201
|
+
getStats(): LoggerStats;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Flush all pending logs (returns Promise)
|
|
205
|
+
* @returns Promise that resolves when all logs are flushed
|
|
206
|
+
*/
|
|
207
|
+
flush(): Promise<void>;
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Close the logger and flush all pending logs (returns Promise)
|
|
211
|
+
* @returns Promise that resolves when logger is closed
|
|
212
|
+
*/
|
|
213
|
+
close(): Promise<void>;
|
|
214
|
+
|
|
215
|
+
/** Current log level */
|
|
216
|
+
level: string;
|
|
217
|
+
}
|
|
214
218
|
}
|
|
215
219
|
|
|
216
220
|
/**
|
|
@@ -219,7 +223,12 @@ export interface Logger {
|
|
|
219
223
|
* @param config - Configuration options for the logger
|
|
220
224
|
* @returns Logger instance
|
|
221
225
|
*/
|
|
222
|
-
declare function logger(location?: string, config?: LoggerConfig): Logger;
|
|
226
|
+
declare function logger(location?: string, config?: logger.LoggerConfig): logger.Logger;
|
|
227
|
+
|
|
228
|
+
declare namespace logger {
|
|
229
|
+
/** Opt in to process-wide signal handlers; returns an unregister function. */
|
|
230
|
+
function setupSignalHandlers(options?: { timeout?: number }): () => void;
|
|
231
|
+
}
|
|
223
232
|
|
|
224
233
|
export = logger;
|
|
225
234
|
|
package/lib/lifecycle.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const delay = () => new Promise(resolve => setTimeout(resolve, 1));
|
|
4
|
+
|
|
5
|
+
function withTimeout(operation, timeout, label) {
|
|
6
|
+
let timer;
|
|
7
|
+
return Promise.race([
|
|
8
|
+
operation,
|
|
9
|
+
new Promise((_, reject) => {
|
|
10
|
+
timer = setTimeout(() => reject(new Error(`${label} timed out after ${timeout}ms`)), timeout);
|
|
11
|
+
}),
|
|
12
|
+
]).finally(() => clearTimeout(timer));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Winston uses readable-stream, so inspect both its buffers and file sinks.
|
|
16
|
+
function busy(stream) {
|
|
17
|
+
return !!(stream && (stream._writableState?.length || stream._readableState?.length));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function drain(logger, state, timeout = 5000) {
|
|
21
|
+
const deadline = Date.now() + timeout;
|
|
22
|
+
while (state.pending || busy(logger) || logger.transports.some(t =>
|
|
23
|
+
busy(t) || busy(t._stream) || busy(t._dest) || t._opening || t._rotate)) {
|
|
24
|
+
if (state.error) throw state.error;
|
|
25
|
+
if (Date.now() >= deadline) throw new Error('Logger drain timed out');
|
|
26
|
+
await delay();
|
|
27
|
+
}
|
|
28
|
+
if (state.error) throw state.error;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Winston calls close on unpipe but doesn't await the result. Retain that promise.
|
|
32
|
+
function trackClose(transport) {
|
|
33
|
+
if (transport._ntlClose) return;
|
|
34
|
+
const close = transport.close?.bind(transport);
|
|
35
|
+
let promise;
|
|
36
|
+
transport._ntlClose = () => {
|
|
37
|
+
if (!promise) {
|
|
38
|
+
// File._final already ended and drained this stream before unpipe.
|
|
39
|
+
// Calling File.close(callback) on that finished stream never calls back.
|
|
40
|
+
if (transport instanceof require('winston').transports.File && transport._stream?._writableState.finished) {
|
|
41
|
+
return (promise = Promise.resolve());
|
|
42
|
+
}
|
|
43
|
+
promise = close && close.length > 0
|
|
44
|
+
? new Promise((resolve, reject) => close(err => err ? reject(err) : resolve()))
|
|
45
|
+
: Promise.resolve().then(() => close?.());
|
|
46
|
+
promise.catch(() => {}); // unpipe cannot consume a rejected promise
|
|
47
|
+
}
|
|
48
|
+
return promise;
|
|
49
|
+
};
|
|
50
|
+
transport.close = transport._ntlClose;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
module.exports = { withTimeout, drain, trackClose };
|