From 266e8ad797314c1033d56abb82cc99ce6886f860 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Mon, 25 Jan 2021 12:40:15 +0000 Subject: [PATCH 1/2] Collectors can now be async --- changelog.d/304.misc | 1 + src/bridge.ts | 6 +++--- src/components/prometheusmetrics.ts | 29 ++++++++++++++++++----------- 3 files changed, 22 insertions(+), 14 deletions(-) create mode 100644 changelog.d/304.misc diff --git a/changelog.d/304.misc b/changelog.d/304.misc new file mode 100644 index 00000000..3d116275 --- /dev/null +++ b/changelog.d/304.misc @@ -0,0 +1 @@ +Fetch metrics asynchronously \ No newline at end of file diff --git a/src/bridge.ts b/src/bridge.ts index 62196e28..8bf63f9e 100644 --- a/src/bridge.ts +++ b/src/bridge.ts @@ -1404,9 +1404,9 @@ export class Bridge { * } * }) */ - public registerBridgeGauges(counterFunc: () => BridgeGaugesCounts) { - this.getPrometheusMetrics().registerBridgeGauges(() => { - const counts = counterFunc(); + public registerBridgeGauges(counterFunc: () => Promise|BridgeGaugesCounts) { + this.getPrometheusMetrics().registerBridgeGauges(async () => { + const counts = await counterFunc(); if (counts.matrixGhosts !== undefined) { counts.matrixGhosts = Object.keys(this.intents.size).length; } diff --git a/src/components/prometheusmetrics.ts b/src/components/prometheusmetrics.ts index 04f28744..70ed642a 100644 --- a/src/components/prometheusmetrics.ts +++ b/src/components/prometheusmetrics.ts @@ -18,7 +18,8 @@ import { AgeCounters } from "./agecounters"; import JsSdk from "matrix-js-sdk"; import { Request, Response } from "express"; import { Bridge } from ".."; -type CollectorFunction = () => void; +import Logger from "./logging"; +type CollectorFunction = () => Promise|void; export interface BridgeGaugesCounts { matrixRoomConfigs?: number; @@ -100,6 +101,9 @@ interface GagueOpts { * * @constructor */ + +const log = Logger.get('PrometheusMetrics'); + export class PrometheusMetrics { public static AgeCounters = AgeCounters; private timers: {[name: string]: PromClient.Histogram} = {}; @@ -179,7 +183,7 @@ export class PrometheusMetrics { * @param {BridgeGaugesCallback} counterFunc A function that when invoked * returns the current counts of various items in the bridge. */ - public registerBridgeGauges (counterFunc: () => BridgeGaugesCounts) { + public async registerBridgeGauges (counterFunc: () => Promise|BridgeGaugesCounts) { const matrixRoomsGauge = this.addGauge({ name: "matrix_configured_rooms", help: "Current count of configured rooms by matrix room ID", @@ -220,8 +224,8 @@ export class PrometheusMetrics { labels: ["age"], }); - this.addCollector(function () { - const counts = counterFunc(); + this.addCollector(async () => { + const counts = await counterFunc(); if (counts.matrixRoomConfigs) {matrixRoomsGauge.set(counts.matrixRoomConfigs);} @@ -239,10 +243,6 @@ export class PrometheusMetrics { }); } - public refresh () { - this.collectors.forEach((f) => f()); - } - /** * Adds a new collector function. These collector functions are run whenever * the /metrics page is about to be generated, allowing code to update values @@ -381,9 +381,8 @@ export class PrometheusMetrics { // For now, leave this unauthenticated. checkToken: false, handler: async (_req: Request, res: Response) => { - this.refresh(); - try { + await this.refresh(); const exposition = await this.register.metrics(); res.set("Content-Type", "text/plain"); @@ -391,11 +390,19 @@ export class PrometheusMetrics { } catch (e) { res.status(500); - res.set("Content-Type", "text/plain"); res.send(e.toString()); } }, }); } + + private async refresh () { + try { + await Promise.all(this.collectors.map((f) => f())); + } + catch (ex) { + log.warn(`Failed to refresh metrics:`, ex); + } + } } From 51846f47973462a5cd2d42858108e4215cb3e358 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Mon, 25 Jan 2021 13:20:00 +0000 Subject: [PATCH 2/2] Reinstate refresh as a public method --- src/components/prometheusmetrics.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/components/prometheusmetrics.ts b/src/components/prometheusmetrics.ts index 70ed642a..61a7c3ea 100644 --- a/src/components/prometheusmetrics.ts +++ b/src/components/prometheusmetrics.ts @@ -177,6 +177,18 @@ export class PrometheusMetrics { }); } + /** + * Fetch metrics from all configured collectors + */ + public async refresh () { + try { + await Promise.all(this.collectors.map((f) => f())); + } + catch (ex) { + log.warn(`Failed to refresh metrics:`, ex); + } + } + /** * Registers some exported metrics that expose counts of various kinds of * objects within the bridge. @@ -396,13 +408,4 @@ export class PrometheusMetrics { }, }); } - - private async refresh () { - try { - await Promise.all(this.collectors.map((f) => f())); - } - catch (ex) { - log.warn(`Failed to refresh metrics:`, ex); - } - } }