converse-mcp-server 2.3.1 → 2.4.1
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 +771 -738
- package/docs/API.md +10 -1
- package/docs/PROVIDERS.md +8 -4
- package/package.json +12 -12
- package/src/async/asyncJobStore.js +82 -52
- package/src/async/eventBus.js +25 -20
- package/src/async/fileCache.js +121 -40
- package/src/async/jobRunner.js +65 -39
- package/src/async/providerStreamNormalizer.js +203 -117
- package/src/config.js +374 -102
- package/src/continuationStore.js +32 -24
- package/src/index.js +45 -25
- package/src/prompts/helpPrompt.js +328 -305
- package/src/providers/anthropic.js +303 -119
- package/src/providers/codex.js +103 -45
- package/src/providers/deepseek.js +24 -8
- package/src/providers/google.js +337 -93
- package/src/providers/index.js +1 -1
- package/src/providers/interface.js +16 -11
- package/src/providers/mistral.js +179 -69
- package/src/providers/openai-compatible.js +231 -94
- package/src/providers/openai.js +1094 -914
- package/src/providers/openrouter-endpoints-client.js +220 -216
- package/src/providers/openrouter.js +426 -381
- package/src/providers/xai.js +153 -56
- package/src/resources/helpResource.js +70 -67
- package/src/router.js +95 -67
- package/src/services/summarizationService.js +51 -24
- package/src/systemPrompts.js +89 -89
- package/src/tools/cancelJob.js +31 -19
- package/src/tools/chat.js +997 -883
- package/src/tools/checkStatus.js +86 -65
- package/src/tools/consensus.js +400 -234
- package/src/tools/index.js +39 -16
- package/src/transport/httpTransport.js +82 -55
- package/src/utils/contextProcessor.js +54 -37
- package/src/utils/errorHandler.js +95 -45
- package/src/utils/fileValidator.js +107 -98
- package/src/utils/formatStatus.js +122 -64
- package/src/utils/logger.js +459 -449
- package/src/utils/pathUtils.js +2 -2
- package/src/utils/tokenLimiter.js +216 -216
package/src/utils/logger.js
CHANGED
|
@@ -1,450 +1,460 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Logger Utility
|
|
3
|
-
*
|
|
4
|
-
* Structured logging system with different log levels and development/production modes.
|
|
5
|
-
* Provides consistent logging interface across all modules with proper error handling.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { inspect } from 'util';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Check if console output should be suppressed
|
|
12
|
-
* @returns {boolean} True if console output should be suppressed
|
|
13
|
-
*/
|
|
14
|
-
function shouldSuppressConsole() {
|
|
15
|
-
return
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
*
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
*
|
|
97
|
-
* @
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
*
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
*
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
].filter(Boolean);
|
|
198
|
-
|
|
199
|
-
// Output main log line
|
|
200
|
-
const logLine = parts.join(' ');
|
|
201
|
-
|
|
202
|
-
if (!shouldSuppressConsole()) {
|
|
203
|
-
if (level === 'error') {
|
|
204
|
-
console.error(logLine);
|
|
205
|
-
} else {
|
|
206
|
-
console.log(logLine);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// Output additional data if provided
|
|
211
|
-
if (metadata.data !== undefined) {
|
|
212
|
-
const formattedData = formatData(metadata.data);
|
|
213
|
-
if (formattedData) {
|
|
214
|
-
if (!shouldSuppressConsole()) {
|
|
215
|
-
if (level === 'error') {
|
|
216
|
-
console.error(formattedData);
|
|
217
|
-
} else {
|
|
218
|
-
console.log(formattedData);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// Output error details if provided
|
|
225
|
-
if (metadata.error && metadata.error instanceof Error) {
|
|
226
|
-
const errorInfo = formatError(metadata.error);
|
|
227
|
-
const formattedError = formatData(errorInfo);
|
|
228
|
-
if (level === 'error') {
|
|
229
|
-
if (!shouldSuppressConsole()) {
|
|
230
|
-
console.error(formattedError);
|
|
231
|
-
}
|
|
232
|
-
} else {
|
|
233
|
-
if (!shouldSuppressConsole()) {
|
|
234
|
-
console.log(formattedError);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Create logger instance for a specific module
|
|
242
|
-
* @param {string} moduleName - Name of the module
|
|
243
|
-
* @returns {object} Logger instance
|
|
244
|
-
*/
|
|
245
|
-
export function createLogger(moduleName) {
|
|
246
|
-
return {
|
|
247
|
-
/**
|
|
248
|
-
* Log error message
|
|
249
|
-
* @param {string} message - Error message
|
|
250
|
-
* @param {object} metadata - Additional metadata
|
|
251
|
-
*/
|
|
252
|
-
error(message, metadata = {}) {
|
|
253
|
-
log('error', message, { ...metadata, module: moduleName });
|
|
254
|
-
},
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Log warning message
|
|
258
|
-
* @param {string} message - Warning message
|
|
259
|
-
* @param {object} metadata - Additional metadata
|
|
260
|
-
*/
|
|
261
|
-
warn(message, metadata = {}) {
|
|
262
|
-
log('warn', message, { ...metadata, module: moduleName });
|
|
263
|
-
},
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Log info message
|
|
267
|
-
* @param {string} message - Info message
|
|
268
|
-
* @param {object} metadata - Additional metadata
|
|
269
|
-
*/
|
|
270
|
-
info(message, metadata = {}) {
|
|
271
|
-
log('info', message, { ...metadata, module: moduleName });
|
|
272
|
-
},
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Log debug message
|
|
276
|
-
* @param {string} message - Debug message
|
|
277
|
-
* @param {object} metadata - Additional metadata
|
|
278
|
-
*/
|
|
279
|
-
debug(message, metadata = {}) {
|
|
280
|
-
log('debug', message, { ...metadata, module: moduleName });
|
|
281
|
-
},
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Log trace message
|
|
285
|
-
* @param {string} message - Trace message
|
|
286
|
-
* @param {object} metadata - Additional metadata
|
|
287
|
-
*/
|
|
288
|
-
trace(message, metadata = {}) {
|
|
289
|
-
log('trace', message, { ...metadata, module: moduleName });
|
|
290
|
-
},
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* Log with custom operation context
|
|
294
|
-
* @param {string} operation - Operation name
|
|
295
|
-
* @returns {object} Logger with operation context
|
|
296
|
-
*/
|
|
297
|
-
operation(operation) {
|
|
298
|
-
return {
|
|
299
|
-
error: (message, metadata = {}) =>
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
/**
|
|
331
|
-
*
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
*
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
logger.
|
|
372
|
-
...metadata,
|
|
373
|
-
data: { duration: `${duration}ms` }
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Logger Utility
|
|
3
|
+
*
|
|
4
|
+
* Structured logging system with different log levels and development/production modes.
|
|
5
|
+
* Provides consistent logging interface across all modules with proper error handling.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { inspect } from 'util';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Check if console output should be suppressed
|
|
12
|
+
* @returns {boolean} True if console output should be suppressed
|
|
13
|
+
*/
|
|
14
|
+
function shouldSuppressConsole() {
|
|
15
|
+
return (
|
|
16
|
+
process.env.LOG_LEVEL === 'silent' ||
|
|
17
|
+
process.env.NODE_ENV === 'test' ||
|
|
18
|
+
process.env.MCP_TRANSPORT === 'stdio'
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Log levels in order of severity (lower number = higher severity)
|
|
24
|
+
*/
|
|
25
|
+
const LOG_LEVELS = {
|
|
26
|
+
silent: -1,
|
|
27
|
+
error: 0,
|
|
28
|
+
warn: 1,
|
|
29
|
+
info: 2,
|
|
30
|
+
debug: 3,
|
|
31
|
+
trace: 4,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Logger configuration
|
|
36
|
+
*/
|
|
37
|
+
let loggerConfig = {
|
|
38
|
+
level: process.env.LOG_LEVEL || 'info',
|
|
39
|
+
isDevelopment: process.env.NODE_ENV === 'development',
|
|
40
|
+
enableColors: process.env.NODE_ENV !== 'production',
|
|
41
|
+
enableTimestamps: true,
|
|
42
|
+
enableStackTrace: process.env.NODE_ENV === 'development',
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* ANSI color codes for console output
|
|
47
|
+
*/
|
|
48
|
+
const COLORS = {
|
|
49
|
+
reset: '\x1b[0m',
|
|
50
|
+
bright: '\x1b[1m',
|
|
51
|
+
dim: '\x1b[2m',
|
|
52
|
+
red: '\x1b[31m',
|
|
53
|
+
green: '\x1b[32m',
|
|
54
|
+
yellow: '\x1b[33m',
|
|
55
|
+
blue: '\x1b[34m',
|
|
56
|
+
magenta: '\x1b[35m',
|
|
57
|
+
cyan: '\x1b[36m',
|
|
58
|
+
white: '\x1b[37m',
|
|
59
|
+
gray: '\x1b[90m',
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Log level color mapping
|
|
64
|
+
*/
|
|
65
|
+
const LEVEL_COLORS = {
|
|
66
|
+
error: COLORS.red,
|
|
67
|
+
warn: COLORS.yellow,
|
|
68
|
+
info: COLORS.green,
|
|
69
|
+
debug: COLORS.blue,
|
|
70
|
+
trace: COLORS.gray,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Format timestamp for log entries
|
|
75
|
+
* @returns {string} Formatted timestamp
|
|
76
|
+
*/
|
|
77
|
+
function formatTimestamp() {
|
|
78
|
+
return new Date().toISOString();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Format log level for display
|
|
83
|
+
* @param {string} level - Log level
|
|
84
|
+
* @returns {string} Formatted log level
|
|
85
|
+
*/
|
|
86
|
+
function formatLevel(level) {
|
|
87
|
+
const upperLevel = level.toUpperCase().padEnd(5);
|
|
88
|
+
if (loggerConfig.enableColors) {
|
|
89
|
+
const color = LEVEL_COLORS[level] || COLORS.white;
|
|
90
|
+
return `${color}${upperLevel}${COLORS.reset}`;
|
|
91
|
+
}
|
|
92
|
+
return upperLevel;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Format context information
|
|
97
|
+
* @param {string} module - Module name
|
|
98
|
+
* @param {string} operation - Operation name
|
|
99
|
+
* @returns {string} Formatted context
|
|
100
|
+
*/
|
|
101
|
+
function formatContext(module, operation) {
|
|
102
|
+
if (!module && !operation) return '';
|
|
103
|
+
|
|
104
|
+
const context = [module, operation].filter(Boolean).join(':');
|
|
105
|
+
if (loggerConfig.enableColors) {
|
|
106
|
+
return `${COLORS.dim}[${context}]${COLORS.reset}`;
|
|
107
|
+
}
|
|
108
|
+
return `[${context}]`;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Format error objects for logging
|
|
113
|
+
* @param {Error} error - Error object
|
|
114
|
+
* @returns {object} Formatted error information
|
|
115
|
+
*/
|
|
116
|
+
function formatError(error) {
|
|
117
|
+
if (!(error instanceof Error)) {
|
|
118
|
+
return { error };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const errorInfo = {
|
|
122
|
+
name: error.name,
|
|
123
|
+
message: error.message,
|
|
124
|
+
code: error.code,
|
|
125
|
+
details: error.details,
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
if (loggerConfig.enableStackTrace && error.stack) {
|
|
129
|
+
errorInfo.stack = error.stack;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return errorInfo;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Format log data for output
|
|
137
|
+
* @param {any} data - Data to format
|
|
138
|
+
* @returns {string} Formatted data
|
|
139
|
+
*/
|
|
140
|
+
function formatData(data) {
|
|
141
|
+
if (data === null || data === undefined) {
|
|
142
|
+
return '';
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (typeof data === 'string') {
|
|
146
|
+
return data;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (data instanceof Error) {
|
|
150
|
+
const errorInfo = formatError(data);
|
|
151
|
+
if (loggerConfig.isDevelopment) {
|
|
152
|
+
return inspect(errorInfo, {
|
|
153
|
+
depth: 3,
|
|
154
|
+
colors: loggerConfig.enableColors,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
return JSON.stringify(errorInfo);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (typeof data === 'object') {
|
|
161
|
+
if (loggerConfig.isDevelopment) {
|
|
162
|
+
return inspect(data, { depth: 2, colors: loggerConfig.enableColors });
|
|
163
|
+
}
|
|
164
|
+
return JSON.stringify(data);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return String(data);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Check if log level should be output
|
|
172
|
+
* @param {string} level - Log level to check
|
|
173
|
+
* @returns {boolean} True if should log
|
|
174
|
+
*/
|
|
175
|
+
function shouldLog(level) {
|
|
176
|
+
const currentLevel = LOG_LEVELS[loggerConfig.level] || LOG_LEVELS.info;
|
|
177
|
+
const messageLevel = LOG_LEVELS[level] || LOG_LEVELS.info;
|
|
178
|
+
return messageLevel <= currentLevel;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Core logging function
|
|
183
|
+
* @param {string} level - Log level
|
|
184
|
+
* @param {string} message - Log message
|
|
185
|
+
* @param {object} metadata - Additional metadata
|
|
186
|
+
*/
|
|
187
|
+
function log(level, message, metadata = {}) {
|
|
188
|
+
if (!shouldLog(level)) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const timestamp = loggerConfig.enableTimestamps ? formatTimestamp() : null;
|
|
193
|
+
const formattedLevel = formatLevel(level);
|
|
194
|
+
const context = formatContext(metadata.module, metadata.operation);
|
|
195
|
+
|
|
196
|
+
// Build log parts
|
|
197
|
+
const parts = [timestamp, formattedLevel, context, message].filter(Boolean);
|
|
198
|
+
|
|
199
|
+
// Output main log line
|
|
200
|
+
const logLine = parts.join(' ');
|
|
201
|
+
|
|
202
|
+
if (!shouldSuppressConsole()) {
|
|
203
|
+
if (level === 'error') {
|
|
204
|
+
console.error(logLine);
|
|
205
|
+
} else {
|
|
206
|
+
console.log(logLine);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Output additional data if provided
|
|
211
|
+
if (metadata.data !== undefined) {
|
|
212
|
+
const formattedData = formatData(metadata.data);
|
|
213
|
+
if (formattedData) {
|
|
214
|
+
if (!shouldSuppressConsole()) {
|
|
215
|
+
if (level === 'error') {
|
|
216
|
+
console.error(formattedData);
|
|
217
|
+
} else {
|
|
218
|
+
console.log(formattedData);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Output error details if provided
|
|
225
|
+
if (metadata.error && metadata.error instanceof Error) {
|
|
226
|
+
const errorInfo = formatError(metadata.error);
|
|
227
|
+
const formattedError = formatData(errorInfo);
|
|
228
|
+
if (level === 'error') {
|
|
229
|
+
if (!shouldSuppressConsole()) {
|
|
230
|
+
console.error(formattedError);
|
|
231
|
+
}
|
|
232
|
+
} else {
|
|
233
|
+
if (!shouldSuppressConsole()) {
|
|
234
|
+
console.log(formattedError);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Create logger instance for a specific module
|
|
242
|
+
* @param {string} moduleName - Name of the module
|
|
243
|
+
* @returns {object} Logger instance
|
|
244
|
+
*/
|
|
245
|
+
export function createLogger(moduleName) {
|
|
246
|
+
return {
|
|
247
|
+
/**
|
|
248
|
+
* Log error message
|
|
249
|
+
* @param {string} message - Error message
|
|
250
|
+
* @param {object} metadata - Additional metadata
|
|
251
|
+
*/
|
|
252
|
+
error(message, metadata = {}) {
|
|
253
|
+
log('error', message, { ...metadata, module: moduleName });
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Log warning message
|
|
258
|
+
* @param {string} message - Warning message
|
|
259
|
+
* @param {object} metadata - Additional metadata
|
|
260
|
+
*/
|
|
261
|
+
warn(message, metadata = {}) {
|
|
262
|
+
log('warn', message, { ...metadata, module: moduleName });
|
|
263
|
+
},
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Log info message
|
|
267
|
+
* @param {string} message - Info message
|
|
268
|
+
* @param {object} metadata - Additional metadata
|
|
269
|
+
*/
|
|
270
|
+
info(message, metadata = {}) {
|
|
271
|
+
log('info', message, { ...metadata, module: moduleName });
|
|
272
|
+
},
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Log debug message
|
|
276
|
+
* @param {string} message - Debug message
|
|
277
|
+
* @param {object} metadata - Additional metadata
|
|
278
|
+
*/
|
|
279
|
+
debug(message, metadata = {}) {
|
|
280
|
+
log('debug', message, { ...metadata, module: moduleName });
|
|
281
|
+
},
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Log trace message
|
|
285
|
+
* @param {string} message - Trace message
|
|
286
|
+
* @param {object} metadata - Additional metadata
|
|
287
|
+
*/
|
|
288
|
+
trace(message, metadata = {}) {
|
|
289
|
+
log('trace', message, { ...metadata, module: moduleName });
|
|
290
|
+
},
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Log with custom operation context
|
|
294
|
+
* @param {string} operation - Operation name
|
|
295
|
+
* @returns {object} Logger with operation context
|
|
296
|
+
*/
|
|
297
|
+
operation(operation) {
|
|
298
|
+
return {
|
|
299
|
+
error: (message, metadata = {}) =>
|
|
300
|
+
log('error', message, { ...metadata, module: moduleName, operation }),
|
|
301
|
+
warn: (message, metadata = {}) =>
|
|
302
|
+
log('warn', message, { ...metadata, module: moduleName, operation }),
|
|
303
|
+
info: (message, metadata = {}) =>
|
|
304
|
+
log('info', message, { ...metadata, module: moduleName, operation }),
|
|
305
|
+
debug: (message, metadata = {}) =>
|
|
306
|
+
log('debug', message, { ...metadata, module: moduleName, operation }),
|
|
307
|
+
trace: (message, metadata = {}) =>
|
|
308
|
+
log('trace', message, { ...metadata, module: moduleName, operation }),
|
|
309
|
+
};
|
|
310
|
+
},
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Configure logger settings
|
|
316
|
+
* @param {object} config - Logger configuration
|
|
317
|
+
*/
|
|
318
|
+
export function configureLogger(config) {
|
|
319
|
+
loggerConfig = { ...loggerConfig, ...config };
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Get current logger configuration
|
|
324
|
+
* @returns {object} Current configuration
|
|
325
|
+
*/
|
|
326
|
+
export function getLoggerConfig() {
|
|
327
|
+
return { ...loggerConfig };
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Global logger instance
|
|
332
|
+
*/
|
|
333
|
+
export const logger = createLogger('global');
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Create structured error for logging
|
|
337
|
+
* @param {string} message - Error message
|
|
338
|
+
* @param {string} code - Error code
|
|
339
|
+
* @param {object} details - Error details
|
|
340
|
+
* @param {Error} originalError - Original error
|
|
341
|
+
* @returns {Error} Structured error
|
|
342
|
+
*/
|
|
343
|
+
export function createStructuredError(
|
|
344
|
+
message,
|
|
345
|
+
code = 'UNKNOWN_ERROR',
|
|
346
|
+
details = {},
|
|
347
|
+
originalError = null,
|
|
348
|
+
) {
|
|
349
|
+
const error = new Error(message);
|
|
350
|
+
error.code = code;
|
|
351
|
+
error.details = details;
|
|
352
|
+
|
|
353
|
+
if (originalError) {
|
|
354
|
+
error.originalError = originalError;
|
|
355
|
+
error.cause = originalError;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
return error;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Log performance timing
|
|
363
|
+
* @param {string} operation - Operation name
|
|
364
|
+
* @param {number} startTime - Start time in milliseconds
|
|
365
|
+
* @param {object} metadata - Additional metadata
|
|
366
|
+
*/
|
|
367
|
+
export function logTiming(operation, startTime, metadata = {}) {
|
|
368
|
+
const duration = Date.now() - startTime;
|
|
369
|
+
|
|
370
|
+
if (duration > 1000) {
|
|
371
|
+
logger.warn(`Slow operation: ${operation}`, {
|
|
372
|
+
...metadata,
|
|
373
|
+
data: { duration: `${duration}ms` },
|
|
374
|
+
});
|
|
375
|
+
} else if (duration > 100) {
|
|
376
|
+
logger.info(`Operation completed: ${operation}`, {
|
|
377
|
+
...metadata,
|
|
378
|
+
data: { duration: `${duration}ms` },
|
|
379
|
+
});
|
|
380
|
+
} else {
|
|
381
|
+
logger.debug(`Operation completed: ${operation}`, {
|
|
382
|
+
...metadata,
|
|
383
|
+
data: { duration: `${duration}ms` },
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Performance timer utility
|
|
390
|
+
* @param {string} operation - Operation name
|
|
391
|
+
* @param {string} module - Module name
|
|
392
|
+
* @returns {function} Function to end timing
|
|
393
|
+
*/
|
|
394
|
+
export function startTimer(operation, module = 'timer') {
|
|
395
|
+
const startTime = Date.now();
|
|
396
|
+
const moduleLogger = createLogger(module);
|
|
397
|
+
|
|
398
|
+
moduleLogger.debug(`Starting: ${operation}`);
|
|
399
|
+
|
|
400
|
+
return (result = 'completed', metadata = {}) => {
|
|
401
|
+
const duration = Date.now() - startTime;
|
|
402
|
+
moduleLogger.debug(`${result}: ${operation}`, {
|
|
403
|
+
...metadata,
|
|
404
|
+
data: { duration: `${duration}ms` },
|
|
405
|
+
});
|
|
406
|
+
return duration;
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Log function entry and exit (for debugging)
|
|
412
|
+
* @param {string} functionName - Function name
|
|
413
|
+
* @param {string} module - Module name
|
|
414
|
+
* @returns {function} Function to end logging
|
|
415
|
+
*/
|
|
416
|
+
export function logFunction(functionName, module = 'function') {
|
|
417
|
+
const moduleLogger = createLogger(module);
|
|
418
|
+
const startTime = Date.now();
|
|
419
|
+
|
|
420
|
+
moduleLogger.trace(`Entering: ${functionName}`);
|
|
421
|
+
|
|
422
|
+
return (result = 'completed', error = null) => {
|
|
423
|
+
const duration = Date.now() - startTime;
|
|
424
|
+
|
|
425
|
+
if (error) {
|
|
426
|
+
moduleLogger.trace(`Exiting with error: ${functionName}`, {
|
|
427
|
+
data: { duration: `${duration}ms` },
|
|
428
|
+
error,
|
|
429
|
+
});
|
|
430
|
+
} else {
|
|
431
|
+
moduleLogger.trace(`Exiting: ${functionName}`, {
|
|
432
|
+
data: { duration: `${duration}ms`, result },
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Express error for consistent error logging across modules
|
|
440
|
+
*/
|
|
441
|
+
export class LoggedError extends Error {
|
|
442
|
+
constructor(message, code = 'LOGGED_ERROR', details = {}, logger = null) {
|
|
443
|
+
super(message);
|
|
444
|
+
this.name = 'LoggedError';
|
|
445
|
+
this.code = code;
|
|
446
|
+
this.details = details;
|
|
447
|
+
this.timestamp = new Date().toISOString();
|
|
448
|
+
|
|
449
|
+
// Log the error immediately
|
|
450
|
+
if (logger) {
|
|
451
|
+
logger.error(`${this.name}: ${message}`, {
|
|
452
|
+
data: { code, details },
|
|
453
|
+
});
|
|
454
|
+
} else {
|
|
455
|
+
global.logger?.error(`${this.name}: ${message}`, {
|
|
456
|
+
data: { code, details },
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
}
|
|
450
460
|
}
|