From d5f834e8515461b747b9ff9f5ff2a7d822b77793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20G=C3=B3is?= Date: Wed, 3 Sep 2025 08:44:28 +0100 Subject: [PATCH] chore: add unknown flag metric for unique flag names (#10601) https://linear.app/unleash/issue/2-3845/add-metric-for-unique-unknown-flag-names Adds a new unknown flag metric for unique unknown flag names. image --- .../metrics/unknown-flags/unknown-flags-store.ts | 14 +++++++++++--- src/lib/metrics.ts | 12 +++++++++++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/lib/features/metrics/unknown-flags/unknown-flags-store.ts b/src/lib/features/metrics/unknown-flags/unknown-flags-store.ts index 480f282a38..ab92ace325 100644 --- a/src/lib/features/metrics/unknown-flags/unknown-flags-store.ts +++ b/src/lib/features/metrics/unknown-flags/unknown-flags-store.ts @@ -37,12 +37,16 @@ export type QueryParams = { }[]; }; +type CountParams = { + unique?: boolean; +}; + export interface IUnknownFlagsStore { insert(flags: UnknownFlagReport[]): Promise; getAll(params?: QueryParams): Promise; clear(hoursAgo: number): Promise; deleteAll(): Promise; - count(): Promise; + count(params?: CountParams): Promise; } export class UnknownFlagsStore implements IUnknownFlagsStore { @@ -157,8 +161,12 @@ export class UnknownFlagsStore implements IUnknownFlagsStore { await this.db(TABLE).delete(); } - async count(): Promise { - const row = await this.db(TABLE).count('* as count').first(); + async count({ unique }: CountParams = {}): Promise { + const countQuery = unique + ? this.db(TABLE).countDistinct({ count: 'name' }).first() + : this.db(TABLE).count('* as count').first(); + + const row = await countQuery; return Number(row?.count ?? 0); } } diff --git a/src/lib/metrics.ts b/src/lib/metrics.ts index 003c574207..9a1eb538f6 100644 --- a/src/lib/metrics.ts +++ b/src/lib/metrics.ts @@ -761,7 +761,12 @@ export function registerPrometheusMetrics( const unknownFlagsGauge = createGauge({ name: 'unknown_flags', - help: 'Number of unknown flags reported in the last 24 hours, if any. Maximum of 1000.', + help: 'Number of unknown flag reports (name + app + env) in the last 24 hours, if any.', + }); + + const unknownFlagsUniqueNamesGauge = createGauge({ + name: 'unknown_flags_unique_names', + help: 'Number of unique unknown flag names reported in the last 24 hours, if any.', }); // register event listeners @@ -1230,6 +1235,11 @@ export function registerPrometheusMetrics( const unknownFlags = await stores.unknownFlagsStore.count(); unknownFlagsGauge.reset(); unknownFlagsGauge.set(unknownFlags); + + const unknownFlagsUniqueNames = + await stores.unknownFlagsStore.count({ unique: true }); + unknownFlagsUniqueNamesGauge.reset(); + unknownFlagsUniqueNamesGauge.set(unknownFlagsUniqueNames); } catch (e) {} }, };