Skip to content

Commit de8f7cd

Browse files
added metric per topics
1 parent 0b0e99e commit de8f7cd

2 files changed

Lines changed: 59 additions & 7 deletions

File tree

src/common/metrics/api.metrics.service.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export class ApiMetricsService {
2323
private static transactionsPendingResultsCounter: Counter<string>;
2424
private static batchUpdatesCounter: Counter<string>;
2525
private static subscriptionsConnectionsGauge: Gauge<string>;
26+
private static subscriptionsTopicConnectionsGauge: Gauge<string>;
2627

2728
constructor(
2829
private readonly apiConfigService: ApiConfigService,
@@ -40,6 +41,14 @@ export class ApiMetricsService {
4041
});
4142
}
4243

44+
if (!ApiMetricsService.subscriptionsTopicConnectionsGauge) {
45+
ApiMetricsService.subscriptionsTopicConnectionsGauge = new Gauge({
46+
name: 'websocket_subscriptions_topic_connections',
47+
help: 'Unique websocket clients per topic',
48+
labelNames: ['topic'],
49+
});
50+
}
51+
4352
if (!ApiMetricsService.vmQueriesHistogram) {
4453
ApiMetricsService.vmQueriesHistogram = new Histogram({
4554
name: 'vm_query',
@@ -191,10 +200,16 @@ export class ApiMetricsService {
191200
}
192201

193202
@OnEvent(MetricsEvents.SetWebsocketMetrics)
194-
setWebsocketSubscriptionsMetrics(payload: { connectedClients: number }) {
195-
const { connectedClients } = payload;
203+
setWebsocketSubscriptionsMetrics(payload: { connectedClients: number; topics?: Record<string, number> }) {
204+
const { connectedClients, topics } = payload;
196205

197206
ApiMetricsService.subscriptionsConnectionsGauge.set(connectedClients);
207+
208+
if (topics) {
209+
for (const [topic, count] of Object.entries(topics)) {
210+
ApiMetricsService.subscriptionsTopicConnectionsGauge.set({ topic }, count);
211+
}
212+
}
198213
}
199214

200215

src/crons/websocket/websocket.cron.service.ts

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,52 @@ export class WebsocketCronService {
4848
@Cron('*/1 * * * * *')
4949
handleWebsocketMetrics() {
5050
const connectedClients = this.server.sockets.sockets.size ?? 0;
51-
// TODO: add more metrics in the future
52-
// const subscriptions: Record<string, number> = {};
5351

54-
// this.server.sockets.adapter.rooms.forEach((socketsSet, roomName) => {
55-
// subscriptions[roomName] = socketsSet.size;
56-
// });
52+
// Efficient unique-listener counts per topic
53+
const adapter = this.server.sockets.adapter as any;
54+
const sids: Map<string, Set<string>> = adapter?.sids ?? new Map();
55+
56+
const topicPrefixes: Array<{ key: string; prefix?: string; room?: string }> = [
57+
{ key: 'tx', prefix: TransactionsGateway.keyPrefix },
58+
{ key: 'customTx', prefix: TransactionsCustomGateway.keyPrefix },
59+
{ key: 'events', prefix: EventsGateway.keyPrefix },
60+
{ key: 'customEvents', prefix: EventsCustomGateway.keyPrefix },
61+
{ key: 'blocks', prefix: BlocksGateway.keyPrefix },
62+
{ key: 'pool', prefix: PoolGateway.keyPrefix },
63+
{ key: 'stats', room: 'statsRoom' },
64+
];
65+
66+
const topics: Record<string, number> = {};
67+
for (const { key } of topicPrefixes) topics[key] = 0;
68+
69+
// Count unique sockets per prefix-based topic by scanning socket -> rooms map once
70+
if (sids && sids.size > 0) {
71+
for (const [, rooms] of sids) {
72+
// Track whether this socket has been counted for a given topic key
73+
const matched: Record<string, boolean> = {};
74+
75+
for (const roomName of rooms) {
76+
for (const { key, prefix } of topicPrefixes) {
77+
if (!prefix || matched[key]) continue;
78+
if (roomName.startsWith(prefix)) {
79+
topics[key] += 1;
80+
matched[key] = true;
81+
}
82+
}
83+
}
84+
}
85+
}
86+
87+
// Handle exact-room topics (like statsRoom) directly from rooms map
88+
const rooms: Map<string, Set<string>> = adapter?.rooms ?? new Map();
89+
const statsRoomSet = rooms.get('statsRoom');
90+
if (statsRoomSet) {
91+
topics['stats'] = statsRoomSet.size;
92+
}
5793

5894
this.eventEmitter.emit(MetricsEvents.SetWebsocketMetrics, {
5995
connectedClients,
96+
topics,
6097
});
6198
}
6299

0 commit comments

Comments
 (0)