Skip to content

Commit 328d7a1

Browse files
Monitoring: tag HTTP response rate histogram by route rather than request url
1 parent 6a3437c commit 328d7a1

2 files changed

Lines changed: 44 additions & 5 deletions

File tree

src/util/monitoring/Monitoring.ts

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616
along with this program. If not, see <https://www.gnu.org/licenses/>.
1717
*/
1818

19-
import * as client from "prom-client";
20-
import { Router } from "express";
2119
import http, { IncomingMessage, ServerResponse } from "node:http";
20+
import * as client from "prom-client";
21+
import { Application, Router } from "express";
22+
import { sleep } from "@spacebar/util";
2223

2324
export class Monitoring {
2425
static isInitialised = false;
@@ -29,8 +30,38 @@ export class Monitoring {
2930
Monitoring.isInitialised = true;
3031
}
3132

32-
public static attach(router: Router) {
33-
router.get("/metrics", async (req, res) => {
33+
public static attach(app: Application) {
34+
const a = app;
35+
const http_request_total = new client.Counter({
36+
name: "node_http_request_total",
37+
help: "The total number of HTTP requests received",
38+
labelNames: ["path", "method", "status_code"],
39+
});
40+
client.register.registerMetric(http_request_total);
41+
42+
const http_response_rate_histogram = new client.Histogram({
43+
name: "node_http_duration",
44+
labelNames: ["path", "method", "status_code"],
45+
help: "The duration of HTTP requests in seconds",
46+
buckets: [0.0, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 10],
47+
});
48+
client.register.registerMetric(http_response_rate_histogram);
49+
50+
app.use((req, res, next) => {
51+
const endTimer = http_response_rate_histogram.startTimer();
52+
res.on("finish", () => {
53+
const r = req;
54+
const path = (res.locals.lambertRouteBase ?? req.baseUrl ?? "") + req.route?.path;
55+
if (!req.route?.path) {
56+
console.log(req);
57+
}
58+
endTimer({ method: req.method, path, status_code: res.statusCode });
59+
http_request_total.inc({ method: req.method, path, status_code: res.statusCode });
60+
});
61+
next();
62+
});
63+
64+
app.get("/metrics", async (req, res) => {
3465
res.setHeader("Content-Type", client.register.contentType);
3566
const metrics = await client.register.metrics();
3667
res.send(metrics);

src/util/util/lambert-server/Server.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,15 @@ export class Server {
5454
if (router.default) router = router.default;
5555
if (!router || router?.prototype?.constructor?.name !== "router") throw `File doesn't export any default router`;
5656

57-
this.app.use(path, <Router>router);
57+
this.app.use(
58+
path,
59+
// TODO: I wish this middleware wasn't nessecary to preserve base path param names for monitoring...
60+
(_, res, next) => {
61+
res.locals.lambertRouteBase = path;
62+
next();
63+
},
64+
<Router>router,
65+
);
5866

5967
if (this.options.serverInitLogging && process.env.LOG_ROUTES !== "false") console.log(`[Server] Route ${path} registered`);
6068

0 commit comments

Comments
 (0)