-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmongodb.ts
More file actions
96 lines (81 loc) · 3.1 KB
/
Copy pathmongodb.ts
File metadata and controls
96 lines (81 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
import client from 'prom-client';
import { MongoClient, MongoClientOptions } from 'mongodb';
/**
* MongoDB command duration histogram
* Tracks MongoDB command duration by command, collection, and database
*/
export const mongoCommandDuration = new client.Histogram({
name: 'hawk_mongo_command_duration_seconds',
help: 'Histogram of MongoDB command duration by command, collection, and db',
labelNames: ['command', 'collection', 'db'],
buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10],
});
/**
* MongoDB command errors counter
* Tracks failed MongoDB commands grouped by command and error code
*/
export const mongoCommandErrors = new client.Counter({
name: 'hawk_mongo_command_errors_total',
help: 'Counter of failed MongoDB commands grouped by command and error code',
labelNames: ['command', 'error_code'],
});
/**
* Enhance MongoClient options with monitoring
* @param options - Original MongoDB connection options
* @returns Enhanced options with monitoring enabled
*/
export function withMongoMetrics(options: MongoClientOptions = {}): MongoClientOptions {
return {
...options,
monitorCommands: true,
};
}
/**
* Setup MongoDB metrics monitoring on a MongoClient
* @param client - MongoDB client to monitor
*/
export function setupMongoMetrics(client: MongoClient): void {
client.on('commandStarted', (event) => {
// Store start time for this command
const startTimeKey = `${event.requestId}`;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(client as any)[startTimeKey] = Date.now();
});
client.on('commandSucceeded', (event) => {
const startTimeKey = `${event.requestId}`;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const startTime = (client as any)[startTimeKey];
if (startTime) {
const duration = (Date.now() - startTime) / 1000;
const collection = event.command?.collection || event.command?.[event.commandName] || 'unknown';
const db = event.databaseName || 'unknown';
mongoCommandDuration
.labels(event.commandName, collection, db)
.observe(duration);
// Clean up start time
// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (client as any)[startTimeKey];
}
});
client.on('commandFailed', (event) => {
const startTimeKey = `${event.requestId}`;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const startTime = (client as any)[startTimeKey];
if (startTime) {
const duration = (Date.now() - startTime) / 1000;
const collection = event.command?.collection || event.command?.[event.commandName] || 'unknown';
const db = event.databaseName || 'unknown';
mongoCommandDuration
.labels(event.commandName, collection, db)
.observe(duration);
// Track error
const errorCode = event.failure?.code?.toString() || 'unknown';
mongoCommandErrors
.labels(event.commandName, errorCode)
.inc();
// Clean up start time
// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (client as any)[startTimeKey];
}
});
}