UNPKG

alepha

Version:

Easy-to-use modern TypeScript framework for building many kind of applications.

71 lines (61 loc) 1.9 kB
import { $hook, $inject, Alepha } from "alepha"; import { $route } from "alepha/server"; import { collectDefaultMetrics, Histogram, Registry } from "prom-client"; export class ServerMetricsProvider { protected readonly register: Registry = new Registry(); protected readonly alepha = $inject(Alepha); protected httpRequestDuration?: Histogram<string>; public readonly options: ServerMetricsProviderOptions = {}; public readonly metrics = $route({ method: "GET", path: "/metrics", silent: true, handler: () => this.register.metrics(), }); protected readonly onStart = $hook({ on: "start", handler: () => { collectDefaultMetrics({ register: this.register, ...this.options, }); this.httpRequestDuration = new Histogram({ name: "http_request_duration_seconds", help: "Duration of HTTP requests in seconds", labelNames: ["method", "path", "code"], registers: [this.register], }); }, }); protected readonly onRequest = $hook({ on: "server:onRequest", priority: "first", handler: ({ request }) => { const end = this.httpRequestDuration?.startTimer(); request.metadata.metricsTimer = end; }, }); protected readonly onResponse = $hook({ on: "server:onResponse", priority: "last", handler: ({ request, response, route }) => { const timerEnd = request.metadata.metricsTimer as | MetricsTimerEnd | undefined; if (timerEnd) { timerEnd({ method: request.method, path: route.path, code: response.status, }); } }, }); } export interface ServerMetricsProviderOptions { prefix?: string; gcDurationBuckets?: number[]; eventLoopMonitoringPrecision?: number; labels?: object; } type MetricsTimerEnd = (labels?: Record<string, string | number>) => number;