workadventure/pusher/src/Controller/PrometheusController.ts
2022-02-03 01:17:27 +01:00

55 lines
2.1 KiB
TypeScript

import { App } from "../Server/sifrr.server";
import { HttpRequest, HttpResponse } from "uWebSockets.js";
import { register, collectDefaultMetrics } from "prom-client";
interface IPrometheusValue {
labels: { [label: string]: string };
value: number;
}
interface IPrometheusMetric {
name: string;
help: string;
type: string;
values: Array<IPrometheusValue>;
}
export class PrometheusController {
constructor(private App: App) {
collectDefaultMetrics({
gcDurationBuckets: [0.001, 0.01, 0.1, 1, 2, 5], // These are the default buckets.
});
this.App.get("/metrics", this.metrics.bind(this));
this.App.get("/metrics.json", this.metricsAsJSON.bind(this));
}
private metrics(res: HttpResponse, req: HttpRequest): void {
res.writeHeader("Content-Type", register.contentType);
res.end(register.metrics());
}
private async getAllMetrics() : Promise<IPrometheusMetric[]> {
return await Promise.all(
(register.getMetricsAsArray() as any[])
.map((metric) => metric.get() as Promise<IPrometheusMetric>));
}
private metricsAsJSON(res: HttpResponse, req: HttpRequest): void {
this.getAllMetrics().then((items) => {
let json : { [key : string] : number | { [label : string] : number } } = {};
for (const item of items) {
for (const value of item.values) {
if (value.labels && Object.keys(value.labels).length > 0) {
const key = Object.keys(value.labels)
.map((label) => label + ':' + value.labels[label]).join('|');
const data : { [label : string] : number } = (json[item.name] as { [label : string] : number }) || { };
data[key] = value.value;
json[item.name] = data;
} else {
json[item.name] = value.value;
}
}
}
res.writeHeader('Content-Type', 'application/json');
res.end(JSON.stringify(json));
});
}
}