Skip to content

Commit 5aaab2a

Browse files
committed
improve mongo logs
1 parent 81cc005 commit 5aaab2a

File tree

1 file changed

+94
-10
lines changed

1 file changed

+94
-10
lines changed

src/metrics/mongodb.ts

Lines changed: 94 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,74 @@ function formatParams(params: any): string {
132132
}
133133

134134
/**
135-
* Log MongoDB command details to console
136-
* Format: [requestId] db.collection.command(params)
135+
* Colorize duration based on performance thresholds
136+
* @param duration - Duration in milliseconds
137+
* @returns Colorized duration string
138+
*/
139+
function colorizeDuration(duration: number): string {
140+
let color: Effect;
141+
142+
if (duration < 50) {
143+
color = Effect.ForegroundGreen;
144+
} else if (duration < 100) {
145+
color = Effect.ForegroundYellow;
146+
} else {
147+
color = Effect.ForegroundRed;
148+
}
149+
150+
return sgr(`${duration}ms`, color);
151+
}
152+
153+
/**
154+
* Interface for storing command information with timestamp
155+
*/
156+
interface StoredCommandInfo {
157+
formattedCommand: string;
158+
timestamp: number;
159+
}
160+
161+
/**
162+
* Map to store formatted command information by requestId
163+
*/
164+
const commandInfoMap = new Map<number, StoredCommandInfo>();
165+
166+
/**
167+
* Timeout for cleaning up stale command info (30 seconds)
168+
*/
169+
const COMMAND_INFO_TIMEOUT_MS = 30000;
170+
171+
/**
172+
* Cleanup stale command info to prevent memory leaks
173+
* Removes entries older than COMMAND_INFO_TIMEOUT_MS
174+
*/
175+
function cleanupStaleCommandInfo(): void {
176+
const now = Date.now();
177+
const keysToDelete: number[] = [];
178+
179+
for (const [requestId, info] of commandInfoMap.entries()) {
180+
if (now - info.timestamp > COMMAND_INFO_TIMEOUT_MS) {
181+
keysToDelete.push(requestId);
182+
}
183+
}
184+
185+
if (keysToDelete.length > 0) {
186+
console.warn(`Cleaning up ${keysToDelete.length} stale MongoDB command info entries (possible memory leak)`);
187+
for (const key of keysToDelete) {
188+
commandInfoMap.delete(key);
189+
}
190+
}
191+
}
192+
193+
/**
194+
* Periodic cleanup interval
195+
*/
196+
setInterval(cleanupStaleCommandInfo, COMMAND_INFO_TIMEOUT_MS);
197+
198+
/**
199+
* Store MongoDB command details for later logging
137200
* @param event - MongoDB command event
138201
*/
139-
function logCommandStarted(event: any): void {
202+
function storeCommandInfo(event: any): void {
140203
const collectionRaw = extractCollectionFromCommand(event.command, event.commandName);
141204
const collection = sgr(normalizeCollectionName(collectionRaw), Effect.ForegroundGreen);
142205
const db = event.databaseName || 'unknown db';
@@ -147,28 +210,49 @@ function logCommandStarted(event: any): void {
147210
const projection = event.command.projection;
148211
const params = filter || update || pipeline;
149212
const paramsStr = formatParams(params);
213+
const projectionStr = projection ? ` projection: ${formatParams(projection)}` : '';
214+
215+
const formattedCommand = `[${event.requestId}] ${db}.${collection}.${commandName}(${paramsStr})${projectionStr}`;
150216

151-
console.log(`[${event.requestId}] ${db}.${collection}.${commandName}(${paramsStr}) ${projection ? `projection: ${formatParams(projection)}` : ''}`);
217+
commandInfoMap.set(event.requestId, {
218+
formattedCommand,
219+
timestamp: Date.now(),
220+
});
152221
}
153222

154223
/**
155224
* Log MongoDB command success to console
156-
* Format: [requestId] commandName ✓ duration
225+
* Format: [requestId] db.collection.command(params) ✓ duration
157226
* @param event - MongoDB command event
158227
*/
159228
function logCommandSucceeded(event: any): void {
160-
console.log(`[${event.requestId}] ${event.commandName}${event.duration}ms`);
229+
const info = commandInfoMap.get(event.requestId);
230+
const durationStr = colorizeDuration(event.duration);
231+
232+
if (info) {
233+
console.log(`${info.formattedCommand}${durationStr}`);
234+
commandInfoMap.delete(event.requestId);
235+
} else {
236+
console.log(`[${event.requestId}] ${event.commandName}${durationStr}`);
237+
}
161238
}
162239

163240
/**
164241
* Log MongoDB command failure to console
165-
* Format: [requestId] ✗ error
242+
* Format: [requestId] db.collection.command(params) ✗ error duration
166243
* @param event - MongoDB command event
167244
*/
168245
function logCommandFailed(event: any): void {
169246
const errorMsg = event.failure?.message || event.failure?.errmsg || 'Unknown error';
170-
171-
console.error(`[${event.requestId}] ${event.commandName}${errorMsg} (${event.duration}ms)`);
247+
const info = commandInfoMap.get(event.requestId);
248+
const durationStr = colorizeDuration(event.duration);
249+
250+
if (info) {
251+
console.error(`${info.formattedCommand}${errorMsg} ${durationStr}`);
252+
commandInfoMap.delete(event.requestId);
253+
} else {
254+
console.error(`[${event.requestId}] ${event.commandName}${errorMsg} ${durationStr}`);
255+
}
172256
}
173257

174258
/**
@@ -177,7 +261,7 @@ function logCommandFailed(event: any): void {
177261
*/
178262
export function setupMongoMetrics(client: MongoClient): void {
179263
client.on('commandStarted', (event) => {
180-
logCommandStarted(event);
264+
storeCommandInfo(event);
181265

182266
// Store start time and metadata for this command
183267
const metadataKey = `${event.requestId}`;

0 commit comments

Comments
 (0)