1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-09-10 17:53:36 +02:00

chore: add a class to handle aggreggation queries

This commit is contained in:
Gastón Fournier 2024-10-14 16:13:42 +02:00
parent 5d61b3903b
commit 3cbbefff1d
No known key found for this signature in database
GPG Key ID: AF45428626E17A8E
2 changed files with 64 additions and 9 deletions

50
src/lib/metrics-gauge.ts Normal file
View File

@ -0,0 +1,50 @@
import { createGauge, type Gauge } from './util/metrics';
type RestrictedRecord<T extends string[]> = Record<T[number], string>;
type Query<R> = () => Promise<R | undefined | null>;
type MapResult<R> = (result: R) => {
count: number;
labels: RestrictedRecord<GaugeDefinition<R>['labelNames']>;
};
type GaugeDefinition<T> = {
name: string;
help: string;
labelNames: string[];
query: Query<T>;
map: MapResult<T>;
};
export class DbMetricsMonitor {
private tasks: (() => Promise<void>)[] = [];
private gauges: Record<string, Gauge<string>> = {};
constructor() {}
registerGaugeDbMetric<T>(definition: GaugeDefinition<T>) {
const gauge = createGauge(definition);
this.gauges[definition.name] = gauge;
this.tasks.push(async () => {
const result = await definition.query();
if (result) {
const { count, labels } = definition.map(result);
gauge.reset();
gauge.labels(labels).set(count);
}
});
}
refreshDbMetrics = async () => {
for (const task of this.tasks) {
await task();
}
};
async getLastValue(name: string): Promise<number | undefined> {
try {
return (await this.gauges[name].gauge.get()).values[0].value;
} catch (e) {
return undefined;
}
}
}

View File

@ -37,6 +37,7 @@ import {
} from './util/metrics';
import type { SchedulerService } from './services';
import type { IClientMetricsEnv } from './features/metrics/client-metrics/client-metrics-store-v2-type';
import { DbMetricsMonitor } from './metrics-gauge';
export default class MetricsMonitor {
constructor() {}
@ -56,6 +57,7 @@ export default class MetricsMonitor {
const { eventStore, environmentStore } = stores;
const { flagResolver } = config;
const dbMetrics = new DbMetricsMonitor();
const cachedEnvironments: () => Promise<IEnvironment[]> = memoizee(
async () => environmentStore.getAll(),
@ -125,11 +127,19 @@ export default class MetricsMonitor {
help: 'Maximum number of environment strategies in one feature',
labelNames: ['feature', 'environment'],
});
const maxFeatureStrategies = createGauge({
dbMetrics.registerGaugeDbMetric({
name: 'max_feature_strategies',
help: 'Maximum number of strategies in one feature',
labelNames: ['feature'],
query: () =>
stores.featureStrategiesReadModel.getMaxFeatureStrategies(),
map: (result) => ({
count: result.count,
labels: { feature: result.feature },
}),
});
const maxConstraintValues = createGauge({
name: 'max_constraint_values',
help: 'Maximum number of constraint values used in a single constraint',
@ -394,9 +404,10 @@ export default class MetricsMonitor {
async function collectStaticCounters() {
try {
dbMetrics.refreshDbMetrics();
const stats = await instanceStatsService.getStats();
const [
maxStrategies,
maxEnvironmentStrategies,
maxConstraintValuesResult,
maxConstraintsPerStrategyResult,
@ -408,7 +419,6 @@ export default class MetricsMonitor {
instanceOnboardingMetrics,
projectsOnboardingMetrics,
] = await Promise.all([
stores.featureStrategiesReadModel.getMaxFeatureStrategies(),
stores.featureStrategiesReadModel.getMaxFeatureEnvironmentStrategies(),
stores.featureStrategiesReadModel.getMaxConstraintValues(),
stores.featureStrategiesReadModel.getMaxConstraintsPerStrategy(),
@ -511,12 +521,7 @@ export default class MetricsMonitor {
})
.set(maxEnvironmentStrategies.count);
}
if (maxStrategies) {
maxFeatureStrategies.reset();
maxFeatureStrategies
.labels({ feature: maxStrategies.feature })
.set(maxStrategies.count);
}
if (maxConstraintValuesResult) {
maxConstraintValues.reset();
maxConstraintValues