From adb6f61015ad3de3cd8fe2e65bfea94599e8c7ac Mon Sep 17 00:00:00 2001 From: David Leek Date: Thu, 22 Feb 2024 14:29:21 +0100 Subject: [PATCH] chore: proxy repository load features metrics (#6314) ## About the changes - Adds createHistogram - Adds histogram metrics for proxy-repositorys loading features --- src/lib/metric-events.ts | 2 ++ src/lib/metrics.ts | 15 ++++++++++++- src/lib/proxy/proxy-repository.ts | 9 ++++++-- src/lib/util/metrics/createHistogram.ts | 27 ++++++++++++++++++++++++ src/lib/util/metrics/index.ts | 1 + src/test/e2e/api/proxy/proxy.e2e.test.ts | 4 ++++ 6 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 src/lib/util/metrics/createHistogram.ts diff --git a/src/lib/metric-events.ts b/src/lib/metric-events.ts index f74a163e2e..fa8f9da344 100644 --- a/src/lib/metric-events.ts +++ b/src/lib/metric-events.ts @@ -4,6 +4,7 @@ const SCHEDULER_JOB_TIME = 'scheduler_job_time'; const FEATURES_CREATED_BY_PROCESSED = 'features_created_by_processed'; const EVENTS_CREATED_BY_PROCESSED = 'events_created_by_processed'; const PROXY_REPOSITORY_CREATED = 'proxy_repository_created'; +const PROXY_FEATURES_FOR_TOKEN_TIME = 'proxy_features_for_token_time'; export { REQUEST_TIME, @@ -12,4 +13,5 @@ export { FEATURES_CREATED_BY_PROCESSED, EVENTS_CREATED_BY_PROCESSED, PROXY_REPOSITORY_CREATED, + PROXY_FEATURES_FOR_TOKEN_TIME, }; diff --git a/src/lib/metrics.ts b/src/lib/metrics.ts index 27331a56e1..e68d68f95b 100644 --- a/src/lib/metrics.ts +++ b/src/lib/metrics.ts @@ -25,7 +25,12 @@ import { hoursToMilliseconds, minutesToMilliseconds } from 'date-fns'; import { InstanceStatsService } from './features/instance-stats/instance-stats-service'; import { ValidatedClientMetrics } from './features/metrics/shared/schema'; import { IEnvironment } from './types'; -import { createCounter, createGauge, createSummary } from './util/metrics'; +import { + createCounter, + createGauge, + createSummary, + createHistogram, +} from './util/metrics'; import { SchedulerService } from './services'; export default class MetricsMonitor { @@ -231,6 +236,10 @@ export default class MetricsMonitor { name: 'proxy_repositories_created', help: 'Proxy repositories created', }); + const mapFeaturesForClientDuration = createHistogram({ + name: 'map_features_for_client_duration', + help: 'Duration of mapFeaturesForClient function', + }); async function collectStaticCounters() { try { @@ -409,6 +418,10 @@ export default class MetricsMonitor { proxyRepositoriesCreated.inc(); }); + eventBus.on(events.PROXY_FEATURES_FOR_TOKEN_TIME, ({ duration }) => { + mapFeaturesForClientDuration.observe(duration); + }); + eventStore.on(FEATURE_CREATED, ({ featureName, project }) => { featureToggleUpdateTotal.increment({ toggle: featureName, diff --git a/src/lib/proxy/proxy-repository.ts b/src/lib/proxy/proxy-repository.ts index e80863750b..742b6e4951 100644 --- a/src/lib/proxy/proxy-repository.ts +++ b/src/lib/proxy/proxy-repository.ts @@ -17,8 +17,9 @@ import { Logger } from '../logger'; import ConfigurationRevisionService, { UPDATE_REVISION, } from '../features/feature-toggle/configuration-revision-service'; +import { PROXY_FEATURES_FOR_TOKEN_TIME } from '../metric-events'; -type Config = Pick; +type Config = Pick; type Stores = Pick; @@ -149,12 +150,16 @@ export class ProxyRepository } private async featuresForToken(): Promise { - return mapFeaturesForClient( + const start = Date.now(); + const mappedFeatures = await mapFeaturesForClient( await this.services.featureToggleServiceV2.getClientFeatures({ project: this.token.projects, environment: this.environmentNameForToken(), }), ); + const duration = (Date.now() - start) / 1000; + this.config.eventBus.emit(PROXY_FEATURES_FOR_TOKEN_TIME, { duration }); + return mappedFeatures; } private async segmentsForToken(): Promise { diff --git a/src/lib/util/metrics/createHistogram.ts b/src/lib/util/metrics/createHistogram.ts new file mode 100644 index 0000000000..9af122f5f0 --- /dev/null +++ b/src/lib/util/metrics/createHistogram.ts @@ -0,0 +1,27 @@ +import { + Histogram as PromHistogram, + HistogramConfiguration, +} from 'prom-client'; + +export type Histogram = { + histogram: PromHistogram; + labels: (labels: Record) => PromHistogram.Internal; + observe: (value: number) => void; +}; + +export const createHistogram = ( + options: HistogramConfiguration, +): Histogram => { + const histogram = new PromHistogram(options); + + const labels = (labels: Record) => + histogram.labels(labels); + + const observe = (value: number) => histogram.observe(value); + + return { + histogram, + labels, + observe, + }; +}; diff --git a/src/lib/util/metrics/index.ts b/src/lib/util/metrics/index.ts index 7d14224864..60cf1b00b6 100644 --- a/src/lib/util/metrics/index.ts +++ b/src/lib/util/metrics/index.ts @@ -1,3 +1,4 @@ export * from './createCounter'; export * from './createGauge'; export * from './createSummary'; +export * from './createHistogram'; diff --git a/src/test/e2e/api/proxy/proxy.e2e.test.ts b/src/test/e2e/api/proxy/proxy.e2e.test.ts index 0e8400a3a3..9af9f759a6 100644 --- a/src/test/e2e/api/proxy/proxy.e2e.test.ts +++ b/src/test/e2e/api/proxy/proxy.e2e.test.ts @@ -915,6 +915,7 @@ test('Should sync proxy for keys on an interval', async () => { { getLogger, frontendApi: { refreshIntervalInMs: 5000 }, + eventBus: { emit: jest.fn() }, }, db.stores, app.services, @@ -946,6 +947,7 @@ test('Should change fetch interval', async () => { { getLogger, frontendApi: { refreshIntervalInMs: 1000 }, + eventBus: { emit: jest.fn() }, }, db.stores, app.services, @@ -974,6 +976,7 @@ test('Should not recursively set off timers on events', async () => { { getLogger, frontendApi: { refreshIntervalInMs: 5000 }, + eventBus: { emit: jest.fn() }, }, db.stores, app.services, @@ -1030,6 +1033,7 @@ test('should terminate data polling when stop is called', async () => { { getLogger: getDebugLogger, frontendApi: { refreshIntervalInMs: 1 }, + eventBus: { emit: jest.fn() }, }, db.stores, app.services,