import { createGauge, type Gauge } from './util/metrics'; type RestrictedRecord = Record; type Query = () => Promise; type MapResult = (result: R) => { count: number; labels: RestrictedRecord['labelNames']>; }; type GaugeDefinition = { name: string; help: string; labelNames: string[]; query: Query; map: MapResult; }; type Task = () => Promise; export class DbMetricsMonitor { private tasks: Set = new Set(); private gauges: Map> = new Map(); constructor() {} registerGaugeDbMetric(definition: GaugeDefinition) { const gauge = createGauge(definition); this.gauges.set(definition.name, gauge); this.tasks.add(async () => { const result = await definition.query(); if (result) { const { count, labels } = definition.map(result); gauge.reset(); gauge.labels(labels).set(count); } }); } refreshDbMetrics = async () => { for (const task of this.tasks) { await task(); } }; async getLastValue(name: string): Promise { const gauge = await this.gauges.get(name)?.gauge?.get(); if (gauge && gauge.values.length > 0) { return gauge.values[0].value; } return undefined; } }