1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-20 00:08:02 +01:00

chore: proxy repository load features metrics (#6314)

## About the changes

- Adds createHistogram
- Adds histogram metrics for proxy-repositorys loading features
This commit is contained in:
David Leek 2024-02-22 14:29:21 +01:00 committed by GitHub
parent 3bfafcf87e
commit adb6f61015
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 55 additions and 3 deletions

View File

@ -4,6 +4,7 @@ const SCHEDULER_JOB_TIME = 'scheduler_job_time';
const FEATURES_CREATED_BY_PROCESSED = 'features_created_by_processed'; const FEATURES_CREATED_BY_PROCESSED = 'features_created_by_processed';
const EVENTS_CREATED_BY_PROCESSED = 'events_created_by_processed'; const EVENTS_CREATED_BY_PROCESSED = 'events_created_by_processed';
const PROXY_REPOSITORY_CREATED = 'proxy_repository_created'; const PROXY_REPOSITORY_CREATED = 'proxy_repository_created';
const PROXY_FEATURES_FOR_TOKEN_TIME = 'proxy_features_for_token_time';
export { export {
REQUEST_TIME, REQUEST_TIME,
@ -12,4 +13,5 @@ export {
FEATURES_CREATED_BY_PROCESSED, FEATURES_CREATED_BY_PROCESSED,
EVENTS_CREATED_BY_PROCESSED, EVENTS_CREATED_BY_PROCESSED,
PROXY_REPOSITORY_CREATED, PROXY_REPOSITORY_CREATED,
PROXY_FEATURES_FOR_TOKEN_TIME,
}; };

View File

@ -25,7 +25,12 @@ import { hoursToMilliseconds, minutesToMilliseconds } from 'date-fns';
import { InstanceStatsService } from './features/instance-stats/instance-stats-service'; import { InstanceStatsService } from './features/instance-stats/instance-stats-service';
import { ValidatedClientMetrics } from './features/metrics/shared/schema'; import { ValidatedClientMetrics } from './features/metrics/shared/schema';
import { IEnvironment } from './types'; import { IEnvironment } from './types';
import { createCounter, createGauge, createSummary } from './util/metrics'; import {
createCounter,
createGauge,
createSummary,
createHistogram,
} from './util/metrics';
import { SchedulerService } from './services'; import { SchedulerService } from './services';
export default class MetricsMonitor { export default class MetricsMonitor {
@ -231,6 +236,10 @@ export default class MetricsMonitor {
name: 'proxy_repositories_created', name: 'proxy_repositories_created',
help: 'Proxy repositories created', help: 'Proxy repositories created',
}); });
const mapFeaturesForClientDuration = createHistogram({
name: 'map_features_for_client_duration',
help: 'Duration of mapFeaturesForClient function',
});
async function collectStaticCounters() { async function collectStaticCounters() {
try { try {
@ -409,6 +418,10 @@ export default class MetricsMonitor {
proxyRepositoriesCreated.inc(); proxyRepositoriesCreated.inc();
}); });
eventBus.on(events.PROXY_FEATURES_FOR_TOKEN_TIME, ({ duration }) => {
mapFeaturesForClientDuration.observe(duration);
});
eventStore.on(FEATURE_CREATED, ({ featureName, project }) => { eventStore.on(FEATURE_CREATED, ({ featureName, project }) => {
featureToggleUpdateTotal.increment({ featureToggleUpdateTotal.increment({
toggle: featureName, toggle: featureName,

View File

@ -17,8 +17,9 @@ import { Logger } from '../logger';
import ConfigurationRevisionService, { import ConfigurationRevisionService, {
UPDATE_REVISION, UPDATE_REVISION,
} from '../features/feature-toggle/configuration-revision-service'; } from '../features/feature-toggle/configuration-revision-service';
import { PROXY_FEATURES_FOR_TOKEN_TIME } from '../metric-events';
type Config = Pick<IUnleashConfig, 'getLogger' | 'frontendApi'>; type Config = Pick<IUnleashConfig, 'getLogger' | 'frontendApi' | 'eventBus'>;
type Stores = Pick<IUnleashStores, 'projectStore' | 'eventStore'>; type Stores = Pick<IUnleashStores, 'projectStore' | 'eventStore'>;
@ -149,12 +150,16 @@ export class ProxyRepository
} }
private async featuresForToken(): Promise<FeatureInterface[]> { private async featuresForToken(): Promise<FeatureInterface[]> {
return mapFeaturesForClient( const start = Date.now();
const mappedFeatures = await mapFeaturesForClient(
await this.services.featureToggleServiceV2.getClientFeatures({ await this.services.featureToggleServiceV2.getClientFeatures({
project: this.token.projects, project: this.token.projects,
environment: this.environmentNameForToken(), 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<Segment[]> { private async segmentsForToken(): Promise<Segment[]> {

View File

@ -0,0 +1,27 @@
import {
Histogram as PromHistogram,
HistogramConfiguration,
} from 'prom-client';
export type Histogram<T extends string = string> = {
histogram: PromHistogram<T>;
labels: (labels: Record<T, string | number>) => PromHistogram.Internal<T>;
observe: (value: number) => void;
};
export const createHistogram = <T extends string>(
options: HistogramConfiguration<T>,
): Histogram<T> => {
const histogram = new PromHistogram(options);
const labels = (labels: Record<T, string | number>) =>
histogram.labels(labels);
const observe = (value: number) => histogram.observe(value);
return {
histogram,
labels,
observe,
};
};

View File

@ -1,3 +1,4 @@
export * from './createCounter'; export * from './createCounter';
export * from './createGauge'; export * from './createGauge';
export * from './createSummary'; export * from './createSummary';
export * from './createHistogram';

View File

@ -915,6 +915,7 @@ test('Should sync proxy for keys on an interval', async () => {
{ {
getLogger, getLogger,
frontendApi: { refreshIntervalInMs: 5000 }, frontendApi: { refreshIntervalInMs: 5000 },
eventBus: <any>{ emit: jest.fn() },
}, },
db.stores, db.stores,
app.services, app.services,
@ -946,6 +947,7 @@ test('Should change fetch interval', async () => {
{ {
getLogger, getLogger,
frontendApi: { refreshIntervalInMs: 1000 }, frontendApi: { refreshIntervalInMs: 1000 },
eventBus: <any>{ emit: jest.fn() },
}, },
db.stores, db.stores,
app.services, app.services,
@ -974,6 +976,7 @@ test('Should not recursively set off timers on events', async () => {
{ {
getLogger, getLogger,
frontendApi: { refreshIntervalInMs: 5000 }, frontendApi: { refreshIntervalInMs: 5000 },
eventBus: <any>{ emit: jest.fn() },
}, },
db.stores, db.stores,
app.services, app.services,
@ -1030,6 +1033,7 @@ test('should terminate data polling when stop is called', async () => {
{ {
getLogger: getDebugLogger, getLogger: getDebugLogger,
frontendApi: { refreshIntervalInMs: 1 }, frontendApi: { refreshIntervalInMs: 1 },
eventBus: <any>{ emit: jest.fn() },
}, },
db.stores, db.stores,
app.services, app.services,