@@ -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 */
88export 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