Skip to content

Commit d380041

Browse files
committed
reduce cardinality for mongo metrics
1 parent 388df44 commit d380041

File tree

1 file changed

+28
-6
lines changed

1 file changed

+28
-6
lines changed

src/metrics/mongodb.ts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import { MongoClient, MongoClientOptions } from 'mongodb';
33

44
/**
55
* MongoDB command duration histogram
6-
* Tracks MongoDB command duration by command, collection, and database
6+
* Tracks MongoDB command duration by command, collection family, and database
77
*/
88
export const mongoCommandDuration = new promClient.Histogram({
99
name: 'hawk_mongo_command_duration_seconds',
10-
help: 'Histogram of MongoDB command duration by command, collection, and db',
11-
labelNames: ['command', 'collection', 'db'],
10+
help: 'Histogram of MongoDB command duration by command, collection family, and db',
11+
labelNames: ['command', 'collection_family', 'db'],
1212
buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10],
1313
});
1414

@@ -22,6 +22,27 @@ export const mongoCommandErrors = new promClient.Counter({
2222
labelNames: ['command', 'error_code'],
2323
});
2424

25+
/**
26+
* Extract collection family from full collection name
27+
* Reduces cardinality by grouping dynamic collections
28+
* @param collectionName - Full collection name (e.g., "events:projectId")
29+
* @returns Collection family (e.g., "events")
30+
*/
31+
function getCollectionFamily(collectionName: string): string {
32+
if (collectionName === 'unknown') {
33+
return 'unknown';
34+
}
35+
36+
// Extract prefix before colon for dynamic collections
37+
const colonIndex = collectionName.indexOf(':');
38+
39+
if (colonIndex > 0) {
40+
return collectionName.substring(0, colonIndex);
41+
}
42+
43+
return collectionName;
44+
}
45+
2546
/**
2647
* Enhance MongoClient options with monitoring
2748
* @param options - Original MongoDB connection options
@@ -45,12 +66,13 @@ export function setupMongoMetrics(client: MongoClient): void {
4566

4667
// Extract collection name from the command
4768
const collection = event.command ? ((event.command)[event.commandName] || 'unknown') : 'unknown';
69+
const collectionFamily = getCollectionFamily(collection);
4870
const db = event.databaseName || 'unknown';
4971

5072
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5173
(client as any)[metadataKey] = {
5274
startTime: Date.now(),
53-
collection,
75+
collectionFamily,
5476
db,
5577
commandName: event.commandName,
5678
};
@@ -65,7 +87,7 @@ export function setupMongoMetrics(client: MongoClient): void {
6587
const duration = (Date.now() - metadata.startTime) / 1000;
6688

6789
mongoCommandDuration
68-
.labels(metadata.commandName, metadata.collection, metadata.db)
90+
.labels(metadata.commandName, metadata.collectionFamily, metadata.db)
6991
.observe(duration);
7092

7193
// Clean up metadata
@@ -83,7 +105,7 @@ export function setupMongoMetrics(client: MongoClient): void {
83105
const duration = (Date.now() - metadata.startTime) / 1000;
84106

85107
mongoCommandDuration
86-
.labels(metadata.commandName, metadata.collection, metadata.db)
108+
.labels(metadata.commandName, metadata.collectionFamily, metadata.db)
87109
.observe(duration);
88110

89111
// Track error

0 commit comments

Comments
 (0)