mirror of
https://github.com/Unleash/unleash.git
synced 2025-09-19 17:52:45 +02:00
chore: add release plans/templates count to instance stats (#10540)
This commit is contained in:
parent
e355506bb9
commit
7fb523e348
@ -63,6 +63,8 @@ export const InstanceStats: FC = () => {
|
||||
title: 'Highest number of values used for a single constraint',
|
||||
value: stats?.maxConstraintValues,
|
||||
},
|
||||
{ title: 'Release templates', value: stats?.releaseTemplates },
|
||||
{ title: 'Release plans', value: stats?.releasePlans },
|
||||
];
|
||||
|
||||
if (stats?.versionEnterprise) {
|
||||
|
@ -82,6 +82,16 @@ export interface InstanceAdminStatsSchema {
|
||||
* @minimum 0
|
||||
*/
|
||||
projects?: number;
|
||||
/**
|
||||
* The number of release plans in this instance
|
||||
* @minimum 0
|
||||
*/
|
||||
releasePlans?: number;
|
||||
/**
|
||||
* The number of release templates in this instance
|
||||
* @minimum 0
|
||||
*/
|
||||
releaseTemplates?: number;
|
||||
/**
|
||||
* The number of roles defined in this instance
|
||||
* @minimum 0
|
||||
|
@ -48,6 +48,8 @@ import {
|
||||
createFakeGetLicensedUsers,
|
||||
createGetLicensedUsers,
|
||||
} from './getLicensedUsers.js';
|
||||
import { ReleasePlanStore } from '../release-plans/release-plan-store.js';
|
||||
import { ReleasePlanTemplateStore } from '../release-plans/release-plan-template-store.js';
|
||||
|
||||
export const createInstanceStatsService = (db: Db, config: IUnleashConfig) => {
|
||||
const { eventBus, getLogger, flagResolver } = config;
|
||||
@ -104,6 +106,9 @@ export const createInstanceStatsService = (db: Db, config: IUnleashConfig) => {
|
||||
getLogger,
|
||||
flagResolver,
|
||||
);
|
||||
|
||||
const releasePlanTemplateStore = new ReleasePlanTemplateStore(db, config);
|
||||
const releasePlanStore = new ReleasePlanStore(db, config);
|
||||
const instanceStatsServiceStores = {
|
||||
featureToggleStore,
|
||||
userStore,
|
||||
@ -122,6 +127,8 @@ export const createInstanceStatsService = (db: Db, config: IUnleashConfig) => {
|
||||
featureStrategiesReadModel,
|
||||
featureStrategiesStore,
|
||||
trafficDataUsageStore,
|
||||
releasePlanTemplateStore,
|
||||
releasePlanStore,
|
||||
};
|
||||
const versionServiceStores = { settingStore };
|
||||
const getActiveUsers = createGetActiveUsers(db);
|
||||
@ -160,6 +167,12 @@ export const createFakeInstanceStatsService = (config: IUnleashConfig) => {
|
||||
const featureStrategiesReadModel = new FakeFeatureStrategiesReadModel();
|
||||
const trafficDataUsageStore = new FakeTrafficDataUsageStore();
|
||||
const featureStrategiesStore = new FakeFeatureStrategiesStore();
|
||||
const releasePlanTemplateStore = {
|
||||
count: () => Promise.resolve(0),
|
||||
} as ReleasePlanTemplateStore;
|
||||
const releasePlanStore = {
|
||||
count: () => Promise.resolve(0),
|
||||
} as ReleasePlanStore;
|
||||
const instanceStatsServiceStores = {
|
||||
featureToggleStore,
|
||||
userStore,
|
||||
@ -178,6 +191,8 @@ export const createFakeInstanceStatsService = (config: IUnleashConfig) => {
|
||||
featureStrategiesReadModel,
|
||||
featureStrategiesStore,
|
||||
trafficDataUsageStore,
|
||||
releasePlanTemplateStore,
|
||||
releasePlanStore,
|
||||
};
|
||||
|
||||
const versionServiceStores = { settingStore };
|
||||
|
@ -31,6 +31,8 @@ import { format, minutesToMilliseconds } from 'date-fns';
|
||||
import memoizee from 'memoizee';
|
||||
import type { GetLicensedUsers } from './getLicensedUsers.js';
|
||||
import type { IFeatureUsageInfo } from '../../services/version-service.js';
|
||||
import type { ReleasePlanTemplateStore } from '../release-plans/release-plan-template-store.js';
|
||||
import type { ReleasePlanStore } from '../release-plans/release-plan-store.js';
|
||||
|
||||
export type TimeRange = 'allTime' | '30d' | '7d';
|
||||
|
||||
@ -70,6 +72,8 @@ export interface InstanceStats {
|
||||
maxEnvironmentStrategies: number;
|
||||
maxConstraints: number;
|
||||
maxConstraintValues: number;
|
||||
releaseTemplates?: number;
|
||||
releasePlans?: number;
|
||||
}
|
||||
|
||||
export type InstanceStatsSigned = Omit<InstanceStats, 'projects'> & {
|
||||
@ -126,6 +130,10 @@ export class InstanceStatsService {
|
||||
|
||||
private trafficDataUsageStore: ITrafficDataUsageStore;
|
||||
|
||||
private releasePlanTemplateStore: ReleasePlanTemplateStore;
|
||||
|
||||
private releasePlanStore: ReleasePlanStore;
|
||||
|
||||
constructor(
|
||||
{
|
||||
featureToggleStore,
|
||||
@ -145,6 +153,8 @@ export class InstanceStatsService {
|
||||
featureStrategiesReadModel,
|
||||
featureStrategiesStore,
|
||||
trafficDataUsageStore,
|
||||
releasePlanTemplateStore,
|
||||
releasePlanStore,
|
||||
}: Pick<
|
||||
IUnleashStores,
|
||||
| 'featureToggleStore'
|
||||
@ -164,6 +174,8 @@ export class InstanceStatsService {
|
||||
| 'featureStrategiesReadModel'
|
||||
| 'featureStrategiesStore'
|
||||
| 'trafficDataUsageStore'
|
||||
| 'releasePlanTemplateStore'
|
||||
| 'releasePlanStore'
|
||||
>,
|
||||
{
|
||||
getLogger,
|
||||
@ -203,6 +215,8 @@ export class InstanceStatsService {
|
||||
this.featureStrategiesReadModel = featureStrategiesReadModel;
|
||||
this.featureStrategiesStore = featureStrategiesStore;
|
||||
this.trafficDataUsageStore = trafficDataUsageStore;
|
||||
this.releasePlanTemplateStore = releasePlanTemplateStore;
|
||||
this.releasePlanStore = releasePlanStore;
|
||||
}
|
||||
|
||||
memory = new Map<string, () => Promise<any>>();
|
||||
@ -295,6 +309,20 @@ export class InstanceStatsService {
|
||||
});
|
||||
}
|
||||
|
||||
async getReleaseTemplates(): Promise<number> {
|
||||
return this.memorize('getReleaseTemplates', async () => {
|
||||
const count = await this.releasePlanTemplateStore.count();
|
||||
return count;
|
||||
});
|
||||
}
|
||||
|
||||
async getReleasePlans(): Promise<number> {
|
||||
return this.memorize('getReleasePlans', async () => {
|
||||
const count = await this.releasePlanStore.count();
|
||||
return count;
|
||||
});
|
||||
}
|
||||
|
||||
async getStats(): Promise<InstanceStats> {
|
||||
const versionInfo = await this.versionService.getVersionInfo();
|
||||
const [
|
||||
@ -326,6 +354,8 @@ export class InstanceStatsService {
|
||||
maxEnvironmentStrategies,
|
||||
maxConstraintValues,
|
||||
maxConstraints,
|
||||
releaseTemplates,
|
||||
releasePlans,
|
||||
] = await Promise.all([
|
||||
this.getToggleCount(),
|
||||
this.getArchivedToggleCount(),
|
||||
@ -370,6 +400,8 @@ export class InstanceStatsService {
|
||||
this.featureStrategiesReadModel,
|
||||
),
|
||||
),
|
||||
this.getReleaseTemplates(),
|
||||
this.getReleasePlans(),
|
||||
]);
|
||||
|
||||
return {
|
||||
@ -408,6 +440,8 @@ export class InstanceStatsService {
|
||||
maxEnvironmentStrategies: maxEnvironmentStrategies?.count ?? 0,
|
||||
maxConstraintValues: maxConstraintValues?.count ?? 0,
|
||||
maxConstraints: maxConstraints?.count ?? 0,
|
||||
releaseTemplates,
|
||||
releasePlans,
|
||||
};
|
||||
}
|
||||
|
||||
@ -435,6 +469,8 @@ export class InstanceStatsService {
|
||||
postgresVersion,
|
||||
licenseType,
|
||||
hostedBy,
|
||||
releaseTemplates,
|
||||
releasePlans,
|
||||
] = await Promise.all([
|
||||
this.getToggleCount(),
|
||||
this.getRegisteredUsers(),
|
||||
@ -458,6 +494,8 @@ export class InstanceStatsService {
|
||||
this.postgresVersion(),
|
||||
this.getLicenseType(),
|
||||
this.getHostedBy(),
|
||||
this.getReleaseTemplates(),
|
||||
this.getReleasePlans(),
|
||||
]);
|
||||
const versionInfo = await this.versionService.getVersionInfo();
|
||||
|
||||
@ -493,6 +531,8 @@ export class InstanceStatsService {
|
||||
postgresVersion,
|
||||
licenseType,
|
||||
hostedBy,
|
||||
releaseTemplates,
|
||||
releasePlans,
|
||||
};
|
||||
return featureInfo;
|
||||
}
|
||||
@ -663,7 +703,7 @@ export class InstanceStatsService {
|
||||
.reduce((a, b) => a + b, 0);
|
||||
|
||||
const sum = sha256(
|
||||
`${instanceStats.instanceId}${instanceStats.users}${instanceStats.featureToggles}${totalProjects}${instanceStats.roles}${instanceStats.groups}${instanceStats.environments}${instanceStats.segments}`,
|
||||
`${instanceStats.instanceId}${instanceStats.users}${instanceStats.featureToggles}${totalProjects}${instanceStats.roles}${instanceStats.groups}${instanceStats.environments}${instanceStats.segments}${instanceStats.releaseTemplates}${instanceStats.releasePlans}`,
|
||||
);
|
||||
return { ...instanceStats, sum, projects: totalProjects };
|
||||
}
|
||||
|
@ -272,6 +272,18 @@ export const instanceAdminStatsSchema = {
|
||||
description:
|
||||
'The highest number of constraint values used on a single constraint.',
|
||||
},
|
||||
releaseTemplates: {
|
||||
type: 'integer',
|
||||
minimum: 0,
|
||||
example: 2,
|
||||
description: 'The number of release templates in this instance',
|
||||
},
|
||||
releasePlans: {
|
||||
type: 'integer',
|
||||
minimum: 0,
|
||||
example: 1,
|
||||
description: 'The number of release plans in this instance',
|
||||
},
|
||||
sum: {
|
||||
type: 'string',
|
||||
description:
|
||||
|
@ -131,6 +131,8 @@ class InstanceAdminController extends Controller {
|
||||
maxEnvironmentStrategies: 20,
|
||||
maxConstraints: 17,
|
||||
maxConstraintValues: 123,
|
||||
releaseTemplates: 3,
|
||||
releasePlans: 5,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,8 @@ const fakeTelemetryData = {
|
||||
postgresVersion: '17.1 (Debian 17.1-1.pgdg120+1)',
|
||||
licenseType: 'test',
|
||||
hostedBy: 'self-hosted',
|
||||
releaseTemplates: 2,
|
||||
releasePlans: 4,
|
||||
};
|
||||
|
||||
test('yields current versions', async () => {
|
||||
|
@ -52,6 +52,8 @@ export interface IFeatureUsageInfo {
|
||||
postgresVersion: string;
|
||||
licenseType: string;
|
||||
hostedBy: string;
|
||||
releaseTemplates: number;
|
||||
releasePlans: number;
|
||||
}
|
||||
|
||||
export default class VersionService {
|
||||
|
@ -124,7 +124,7 @@ test('should return signed instance statistics', async () => {
|
||||
.expect((res) => {
|
||||
expect(res.body.instanceId).toBe('test-static');
|
||||
expect(res.body.sum).toBe(
|
||||
'd9bac94bba7afa20d98f0a9d54a84b79a6668f8103b8f89db85d05d38e84f519',
|
||||
'a5fd70e5ba5dfa02644404d4d075cb7f783487f607fbc00e8e4bc0aef41fd81a',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
12
src/test/fixtures/store.ts
vendored
12
src/test/fixtures/store.ts
vendored
@ -137,9 +137,15 @@ const createStores: () => IUnleashStores = () => {
|
||||
uniqueConnectionReadModel: new UniqueConnectionReadModel(
|
||||
uniqueConnectionStore,
|
||||
),
|
||||
releasePlanStore: {} as ReleasePlanStore,
|
||||
releasePlanMilestoneStore: {} as ReleasePlanMilestoneStore,
|
||||
releasePlanTemplateStore: {} as ReleasePlanTemplateStore,
|
||||
releasePlanStore: {
|
||||
count: () => Promise.resolve(0),
|
||||
} as ReleasePlanStore,
|
||||
releasePlanMilestoneStore: {
|
||||
count: () => Promise.resolve(0),
|
||||
} as ReleasePlanMilestoneStore,
|
||||
releasePlanTemplateStore: {
|
||||
count: () => Promise.resolve(0),
|
||||
} as ReleasePlanTemplateStore,
|
||||
releasePlanMilestoneStrategyStore:
|
||||
{} as ReleasePlanMilestoneStrategyStore,
|
||||
featureLinkStore: new FakeFeatureLinkStore(),
|
||||
|
Loading…
Reference in New Issue
Block a user