Skip to content

Commit 7a7e687

Browse files
Merge branch 'master' into options-http
2 parents c7c99ed + 3aa418f commit 7a7e687

File tree

3 files changed

+48
-27
lines changed

3 files changed

+48
-27
lines changed

package-lock.json

Lines changed: 13 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
"crypto-random-string": "^5.0.0",
2121
"csv-parser": "^3.0.0",
2222
"elastic-apm-node": "^4.9.0",
23-
"elastic-apm-utils": "^4.1.1",
23+
"elastic-apm-utils": "^4.1.2",
2424
"got": "^14.4.5",
2525
"gunzip-maybe": "^1.4.2",
26-
"h-logger2": "^1.3.1",
26+
"h-logger2": "^1.3.2",
2727
"h-logger2-elastic": "^6.2.1",
2828
"http-errors": "^2.0.0",
2929
"ipaddr.js": "^2.2.0",
@@ -98,7 +98,7 @@
9898
"eslint": "^8.57.1",
9999
"husky": "^9.1.7",
100100
"lint-staged": "^15.2.11",
101-
"mocha": "^11.0.1",
101+
"mocha": "^11.0.2",
102102
"mock-fs": "^5.4.1",
103103
"nock": "^13.5.6",
104104
"relative-day-utc": "^1.3.0",
@@ -114,7 +114,7 @@
114114
},
115115
"optionalDependencies": {
116116
"bufferutil": "^4.0.8",
117-
"utf-8-validate": "^6.0.3"
117+
"utf-8-validate": "^6.0.5"
118118
},
119119
"scripts": {
120120
"build": "tsc && npm run download:files && npm run commit:hash && cp -r public dist",
@@ -125,8 +125,8 @@
125125
"prepare": "npm run download:files; husky || echo 'Failed to install husky'",
126126
"stats": "tsx probes-stats/known.ts",
127127
"start": "ELASTIC_APM_CONFIG_FILE=elastic-apm-node.cjs node --max_old_space_size=3584 --max-semi-space-size=128 --experimental-loader elastic-apm-node/loader.mjs -r elastic-apm-node/start.js dist/src/index.js",
128-
"start:dev": "NODE_ENV=development FAKE_PROBE_IP=1 ELASTIC_APM_CONFIG_FILE=elastic-apm-node.cjs tsx src/index.ts",
129-
"start:test": "NODE_ENV=test knex migrate:latest && NODE_ENV=test ELASTIC_APM_CONFIG_FILE=elastic-apm-node.cjs tsx src/index.ts",
128+
"start:dev": "NODE_ENV=development FAKE_PROBE_IP=1 tsx src/index.ts",
129+
"start:test": "NODE_ENV=test knex migrate:latest && NODE_ENV=test tsx src/index.ts",
130130
"lint": "npm run lint:js && npm run lint:types && npm run lint:docs",
131131
"lint:fix": "npm run lint:js:fix && npm run lint:types && npm run lint:docs",
132132
"lint:docs": "spectral lint public/**/spec.yaml",

src/lib/metrics.ts

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import _ from 'lodash';
22
import apmAgent from 'elastic-apm-node';
33
import type { Server as SocketServer } from 'socket.io';
4+
import type { Knex } from 'knex';
45

56
import { scopedLogger } from './logger.js';
67
import { fetchProbes, getWsServer, PROBES_NAMESPACE } from './ws/server.js';
78
import { getMeasurementRedisClient, type RedisClient } from './redis/measurement-client.js';
9+
import { USERS_TABLE } from './http/auth.js';
10+
import { client } from './sql/client.js';
811

912
const logger = scopedLogger('metrics');
1013

@@ -19,6 +22,7 @@ export class MetricsAgent {
1922
constructor (
2023
private readonly io: SocketServer,
2124
private readonly redis: RedisClient,
25+
private readonly sql: Knex,
2226
) {}
2327

2428
run (): void {
@@ -32,11 +36,11 @@ export class MetricsAgent {
3236
// finished measurements use 2 keys
3337
// 1 global key tracks the in-progress measurements
3438
return Math.round((dbSize - awaitingSize - 1) / 2);
35-
});
39+
}, 60 * 1000);
3640

3741
this.registerAsyncCollector(`gp.probe.count.local`, async () => {
3842
return this.io.of(PROBES_NAMESPACE).local.fetchSockets().then(sockets => sockets.length);
39-
});
43+
}, 10 * 1000);
4044

4145
this.registerAsyncGroupCollector('global probe stats', async () => {
4246
const probes = await fetchProbes();
@@ -52,7 +56,24 @@ export class MetricsAgent {
5256
'gp.probe.count.adopted': probes.filter(probe => probe.owner).length,
5357
'gp.probe.count.total': probes.length,
5458
};
55-
});
59+
}, 10 * 1000);
60+
61+
this.registerAsyncGroupCollector(`user stats`, async () => {
62+
const result = await this.sql(USERS_TABLE)
63+
.count('user_type as c')
64+
.groupBy('user_type')
65+
.select<{ user_type: string, c: number }[]>([ 'user_type' ]);
66+
67+
const countByType = _(result)
68+
.mapKeys(record => `gp.user.count.${record.user_type}`)
69+
.mapValues(record => record.c)
70+
.value();
71+
72+
return {
73+
...countByType,
74+
'gp.user.count.total': _.sum(Object.values(countByType)),
75+
};
76+
}, 60 * 1000);
5677
}
5778

5879
recordMeasurementTime (type: string, time: number): void {
@@ -138,17 +159,17 @@ export class MetricsAgent {
138159
});
139160
}
140161

141-
private registerAsyncCollector (name: string, callback: () => Promise<number>): void {
162+
private registerAsyncCollector (name: string, callback: () => Promise<number>, interval: number): void {
142163
this.timers[name] = setInterval(() => {
143164
callback().then((value) => {
144165
this.recordAsyncDatapoint(name, value);
145166
}).catch((error) => {
146167
logger.error(`Failed to collect an async metric "${name}"`, error);
147168
});
148-
}, 10 * 1000);
169+
}, interval);
149170
}
150171

151-
private registerAsyncGroupCollector (groupName: string, callback: () => Promise<{[k: string]: number}>): void {
172+
private registerAsyncGroupCollector (groupName: string, callback: () => Promise<{[k: string]: number}>, interval: number): void {
152173
this.timers[groupName] = setInterval(() => {
153174
callback().then((group) => {
154175
Object.entries(group).forEach(([ key, value ]) => {
@@ -157,15 +178,15 @@ export class MetricsAgent {
157178
}).catch((error) => {
158179
logger.error(`Failed to collect an async metric group "${groupName}"`, error);
159180
});
160-
}, 10 * 1000);
181+
}, interval);
161182
}
162183
}
163184

164185
let agent: MetricsAgent;
165186

166187
export const getMetricsAgent = () => {
167188
if (!agent) {
168-
agent = new MetricsAgent(getWsServer(), getMeasurementRedisClient());
189+
agent = new MetricsAgent(getWsServer(), getMeasurementRedisClient(), client);
169190
}
170191

171192
return agent;

0 commit comments

Comments
 (0)