mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
feat: Prometheus last day metrics (#5878)
This commit is contained in:
parent
6cfb7b4fb8
commit
65eb8956e1
@ -216,7 +216,7 @@ test('count previous day metrics', async () => {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const result = await clientMetricsStore.countPreviousDayMetrics();
|
const result = await clientMetricsStore.countPreviousDayMetricsBuckets();
|
||||||
|
|
||||||
expect(result).toMatchObject({ enabledCount: 2, variantCount: 4 });
|
expect(result).toMatchObject({ enabledCount: 2, variantCount: 4 });
|
||||||
});
|
});
|
||||||
|
@ -339,7 +339,7 @@ export class ClientMetricsStoreV2 implements IClientMetricsStoreV2 {
|
|||||||
.del();
|
.del();
|
||||||
}
|
}
|
||||||
|
|
||||||
async countPreviousDayMetrics(): Promise<{
|
async countPreviousDayMetricsBuckets(): Promise<{
|
||||||
enabledCount: number;
|
enabledCount: number;
|
||||||
variantCount: number;
|
variantCount: number;
|
||||||
}> {
|
}> {
|
||||||
|
@ -3,6 +3,7 @@ import { Logger } from '../../logger';
|
|||||||
import { IUnleashConfig } from '../../types/option';
|
import { IUnleashConfig } from '../../types/option';
|
||||||
import {
|
import {
|
||||||
IClientInstanceStore,
|
IClientInstanceStore,
|
||||||
|
IClientMetricsStoreV2,
|
||||||
IEventStore,
|
IEventStore,
|
||||||
IUnleashStores,
|
IUnleashStores,
|
||||||
} from '../../types/stores';
|
} from '../../types/stores';
|
||||||
@ -54,6 +55,10 @@ export interface InstanceStats {
|
|||||||
clientApps: { range: TimeRange; count: number }[];
|
clientApps: { range: TimeRange; count: number }[];
|
||||||
activeUsers: Awaited<ReturnType<GetActiveUsers>>;
|
activeUsers: Awaited<ReturnType<GetActiveUsers>>;
|
||||||
productionChanges: Awaited<ReturnType<GetProductionChanges>>;
|
productionChanges: Awaited<ReturnType<GetProductionChanges>>;
|
||||||
|
previousDayMetricsBucketsCount: {
|
||||||
|
enabledCount: number;
|
||||||
|
variantCount: number;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export type InstanceStatsSigned = Omit<InstanceStats, 'projects'> & {
|
export type InstanceStatsSigned = Omit<InstanceStats, 'projects'> & {
|
||||||
@ -92,6 +97,8 @@ export class InstanceStatsService {
|
|||||||
|
|
||||||
private clientInstanceStore: IClientInstanceStore;
|
private clientInstanceStore: IClientInstanceStore;
|
||||||
|
|
||||||
|
private clientMetricsStore: IClientMetricsStoreV2;
|
||||||
|
|
||||||
private snapshot?: InstanceStats;
|
private snapshot?: InstanceStats;
|
||||||
|
|
||||||
private appCount?: Partial<{ [key in TimeRange]: number }>;
|
private appCount?: Partial<{ [key in TimeRange]: number }>;
|
||||||
@ -115,6 +122,7 @@ export class InstanceStatsService {
|
|||||||
clientInstanceStore,
|
clientInstanceStore,
|
||||||
eventStore,
|
eventStore,
|
||||||
apiTokenStore,
|
apiTokenStore,
|
||||||
|
clientMetricsStoreV2,
|
||||||
}: Pick<
|
}: Pick<
|
||||||
IUnleashStores,
|
IUnleashStores,
|
||||||
| 'featureToggleStore'
|
| 'featureToggleStore'
|
||||||
@ -130,6 +138,7 @@ export class InstanceStatsService {
|
|||||||
| 'clientInstanceStore'
|
| 'clientInstanceStore'
|
||||||
| 'eventStore'
|
| 'eventStore'
|
||||||
| 'apiTokenStore'
|
| 'apiTokenStore'
|
||||||
|
| 'clientMetricsStoreV2'
|
||||||
>,
|
>,
|
||||||
{ getLogger }: Pick<IUnleashConfig, 'getLogger'>,
|
{ getLogger }: Pick<IUnleashConfig, 'getLogger'>,
|
||||||
versionService: VersionService,
|
versionService: VersionService,
|
||||||
@ -153,6 +162,7 @@ export class InstanceStatsService {
|
|||||||
this.getActiveUsers = getActiveUsers;
|
this.getActiveUsers = getActiveUsers;
|
||||||
this.getProductionChanges = getProductionChanges;
|
this.getProductionChanges = getProductionChanges;
|
||||||
this.apiTokenStore = apiTokenStore;
|
this.apiTokenStore = apiTokenStore;
|
||||||
|
this.clientMetricsStore = clientMetricsStoreV2;
|
||||||
}
|
}
|
||||||
|
|
||||||
async refreshStatsSnapshot(): Promise<void> {
|
async refreshStatsSnapshot(): Promise<void> {
|
||||||
@ -223,6 +233,7 @@ export class InstanceStatsService {
|
|||||||
featureExports,
|
featureExports,
|
||||||
featureImports,
|
featureImports,
|
||||||
productionChanges,
|
productionChanges,
|
||||||
|
previousDayMetricsBucketsCount,
|
||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
this.getToggleCount(),
|
this.getToggleCount(),
|
||||||
this.userStore.count(),
|
this.userStore.count(),
|
||||||
@ -244,6 +255,7 @@ export class InstanceStatsService {
|
|||||||
this.eventStore.filteredCount({ type: FEATURES_EXPORTED }),
|
this.eventStore.filteredCount({ type: FEATURES_EXPORTED }),
|
||||||
this.eventStore.filteredCount({ type: FEATURES_IMPORTED }),
|
this.eventStore.filteredCount({ type: FEATURES_IMPORTED }),
|
||||||
this.getProductionChanges(),
|
this.getProductionChanges(),
|
||||||
|
this.clientMetricsStore.countPreviousDayMetricsBuckets(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -271,6 +283,7 @@ export class InstanceStatsService {
|
|||||||
featureExports,
|
featureExports,
|
||||||
featureImports,
|
featureImports,
|
||||||
productionChanges,
|
productionChanges,
|
||||||
|
previousDayMetricsBucketsCount,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,6 +112,14 @@ export default class MetricsMonitor {
|
|||||||
help: 'Number of API tokens',
|
help: 'Number of API tokens',
|
||||||
labelNames: ['type'],
|
labelNames: ['type'],
|
||||||
});
|
});
|
||||||
|
const enabledMetricsBucketsPreviousDay = new client.Gauge({
|
||||||
|
name: 'enabled_metrics_buckets_previous_day',
|
||||||
|
help: 'Number of hourly enabled/disabled metric buckets in the previous day',
|
||||||
|
});
|
||||||
|
const variantMetricsBucketsPreviousDay = new client.Gauge({
|
||||||
|
name: 'variant_metrics_buckets_previous_day',
|
||||||
|
help: 'Number of hourly variant metric buckets in the previous day',
|
||||||
|
});
|
||||||
const usersActive7days = new client.Gauge({
|
const usersActive7days = new client.Gauge({
|
||||||
name: 'users_active_7',
|
name: 'users_active_7',
|
||||||
help: 'Number of users active in the last 7 days',
|
help: 'Number of users active in the last 7 days',
|
||||||
@ -235,6 +243,15 @@ export default class MetricsMonitor {
|
|||||||
apiTokens.labels(type).set(value);
|
apiTokens.labels(type).set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enabledMetricsBucketsPreviousDay.reset();
|
||||||
|
enabledMetricsBucketsPreviousDay.set(
|
||||||
|
stats.previousDayMetricsBucketsCount.enabledCount,
|
||||||
|
);
|
||||||
|
variantMetricsBucketsPreviousDay.reset();
|
||||||
|
variantMetricsBucketsPreviousDay.set(
|
||||||
|
stats.previousDayMetricsBucketsCount.variantCount,
|
||||||
|
);
|
||||||
|
|
||||||
usersActive7days.reset();
|
usersActive7days.reset();
|
||||||
usersActive7days.set(stats.activeUsers.last7);
|
usersActive7days.set(stats.activeUsers.last7);
|
||||||
usersActive30days.reset();
|
usersActive30days.reset();
|
||||||
|
@ -39,6 +39,27 @@ export const instanceAdminStatsSchema = {
|
|||||||
example: 8,
|
example: 8,
|
||||||
minimum: 0,
|
minimum: 0,
|
||||||
},
|
},
|
||||||
|
previousDayMetricsBucketsCount: {
|
||||||
|
type: 'object',
|
||||||
|
description:
|
||||||
|
'The number client metrics buckets records recorded in the previous day. # features * # apps * # envs * # hours with metrics',
|
||||||
|
properties: {
|
||||||
|
enabledCount: {
|
||||||
|
type: 'number',
|
||||||
|
description:
|
||||||
|
'The number of enabled/disabled metrics buckets recorded in the previous day',
|
||||||
|
example: 10,
|
||||||
|
minimum: 0,
|
||||||
|
},
|
||||||
|
variantCount: {
|
||||||
|
type: 'number',
|
||||||
|
description:
|
||||||
|
'The number of variant metrics buckets recorded in the previous day',
|
||||||
|
example: 10,
|
||||||
|
minimum: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
activeUsers: {
|
activeUsers: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
description:
|
description:
|
||||||
|
@ -120,6 +120,10 @@ class InstanceAdminController extends Controller {
|
|||||||
last60: 200,
|
last60: 200,
|
||||||
last90: 200,
|
last90: 200,
|
||||||
},
|
},
|
||||||
|
previousDayMetricsBucketsCount: {
|
||||||
|
variantCount: 100,
|
||||||
|
enabledCount: 200,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ test('aggregate previous day metrics when metrics count is below limit', async (
|
|||||||
aggregationCalled = true;
|
aggregationCalled = true;
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
},
|
},
|
||||||
countPreviousDayMetrics() {
|
countPreviousDayMetricsBuckets() {
|
||||||
return { enabledCount, variantCount };
|
return { enabledCount, variantCount };
|
||||||
},
|
},
|
||||||
} as unknown as IClientMetricsStoreV2;
|
} as unknown as IClientMetricsStoreV2;
|
||||||
|
@ -62,7 +62,7 @@ export default class ClientMetricsServiceV2 {
|
|||||||
async aggregateDailyMetrics() {
|
async aggregateDailyMetrics() {
|
||||||
if (this.flagResolver.isEnabled('extendedUsageMetrics')) {
|
if (this.flagResolver.isEnabled('extendedUsageMetrics')) {
|
||||||
const { enabledCount, variantCount } =
|
const { enabledCount, variantCount } =
|
||||||
await this.clientMetricsStoreV2.countPreviousDayMetrics();
|
await this.clientMetricsStoreV2.countPreviousDayMetricsBuckets();
|
||||||
const { payload } = this.flagResolver.getVariant(
|
const { payload } = this.flagResolver.getVariant(
|
||||||
'extendedUsageMetrics',
|
'extendedUsageMetrics',
|
||||||
);
|
);
|
||||||
|
@ -39,7 +39,7 @@ export interface IClientMetricsStoreV2
|
|||||||
): Promise<string[]>;
|
): Promise<string[]>;
|
||||||
clearMetrics(hoursAgo: number): Promise<void>;
|
clearMetrics(hoursAgo: number): Promise<void>;
|
||||||
clearDailyMetrics(daysAgo: number): Promise<void>;
|
clearDailyMetrics(daysAgo: number): Promise<void>;
|
||||||
countPreviousDayMetrics(): Promise<{
|
countPreviousDayMetricsBuckets(): Promise<{
|
||||||
enabledCount: number;
|
enabledCount: number;
|
||||||
variantCount: number;
|
variantCount: number;
|
||||||
}>;
|
}>;
|
||||||
|
@ -29,7 +29,7 @@ export default class FakeClientMetricsStoreV2
|
|||||||
clearDailyMetrics(daysBack: number): Promise<void> {
|
clearDailyMetrics(daysBack: number): Promise<void> {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
countPreviousDayMetrics(): Promise<{
|
countPreviousDayMetricsBuckets(): Promise<{
|
||||||
enabledCount: number;
|
enabledCount: number;
|
||||||
variantCount: number;
|
variantCount: number;
|
||||||
}> {
|
}> {
|
||||||
|
Loading…
Reference in New Issue
Block a user