diff --git a/lib/db/feature-toggle-store.js b/lib/db/feature-toggle-store.js index 2ccb7cb4e6..31d5d0727b 100644 --- a/lib/db/feature-toggle-store.js +++ b/lib/db/feature-toggle-store.js @@ -48,6 +48,14 @@ class FeatureToggleStore { .map(this.rowToFeature); } + count() { + return this.db + .count('*') + .from(TABLE) + .where({ archived: 0 }) + .then(res => Number(res[0].count)); + } + getFeature(name) { return this.db .first(FEATURE_COLUMNS) diff --git a/lib/metrics.js b/lib/metrics.js index 9e1af37543..78f77e44c5 100644 --- a/lib/metrics.js +++ b/lib/metrics.js @@ -7,12 +7,15 @@ const { FEATURE_ARCHIVED, FEATURE_REVIVED, } = require('./event-type'); +const { version } = require('./routes/api-def'); +const THREE_HOURS = 3 * 60 * 60 * 1000; exports.startMonitoring = ( enable, eventBus, eventStore, - clientMetricsStore + clientMetricsStore, + featureToggleStore ) => { if (!enable) { return; @@ -44,6 +47,20 @@ exports.startMonitoring = ( help: 'Number of times a feature toggle has been used', labelNames: ['toggle', 'active', 'appName'], }); + const featureTogglesTotal = new client.Gauge({ + name: 'feature_toggles_total', + help: 'Number of feature toggles', + labelNames: ['version'], + }); + + async function collectFeatureToggleMetrics() { + featureTogglesTotal.reset(); + const togglesCount = await featureToggleStore.count(); + featureTogglesTotal.labels(version).set(togglesCount); + } + + collectFeatureToggleMetrics(); + setInterval(() => collectFeatureToggleMetrics(), THREE_HOURS); eventBus.on(events.REQUEST_TIME, ({ path, method, time, statusCode }) => { requestDuration.labels(path, method, statusCode).observe(time); diff --git a/lib/metrics.test.js b/lib/metrics.test.js index 81ffe6bbdc..d5c03d8583 100644 --- a/lib/metrics.test.js +++ b/lib/metrics.test.js @@ -11,7 +11,16 @@ const { startMonitoring } = require('./metrics'); const { register: prometheusRegister } = require('prom-client'); test.before(() => { - startMonitoring(true, eventBus, eventStore, clientMetricsStore); + const featureToggleStore = { + count: () => 123, + }; + startMonitoring( + true, + eventBus, + eventStore, + clientMetricsStore, + featureToggleStore + ); }); test('should collect metrics for requests', t => { @@ -70,3 +79,8 @@ test('should collect metrics for db query timings', t => { /db_query_duration_seconds{quantile="0\.99",store="foo",action="bar"} 0.1337/ ); }); + +test('should collect metrics for feature toggle size', t => { + const metrics = prometheusRegister.metrics(); + t.regex(metrics, /feature_toggles_total{version="(.*)"} 123/); +}); diff --git a/lib/server-impl.js b/lib/server-impl.js index cb257b4975..018655caaf 100644 --- a/lib/server-impl.js +++ b/lib/server-impl.js @@ -33,7 +33,8 @@ async function createApp(options) { options.serverMetrics, eventBus, stores.eventStore, - stores.clientMetricsStore + stores.clientMetricsStore, + stores.featureToggleStore ); if (typeof config.eventHook === 'function') {