mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	fix: add user and project counters
This commit is contained in:
		
							parent
							
								
									14857b01c8
								
							
						
					
					
						commit
						aab4602029
					
				@ -231,6 +231,13 @@ class ProjectStore implements IProjectStore {
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async count(): Promise<number> {
 | 
			
		||||
        return this.db
 | 
			
		||||
            .count('*')
 | 
			
		||||
            .from(TABLE)
 | 
			
		||||
            .then((res) => Number(res[0].count));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 | 
			
		||||
    private getEnvironment(r: any): IEnvironmentOverview {
 | 
			
		||||
        return {
 | 
			
		||||
 | 
			
		||||
@ -176,6 +176,13 @@ class UserStore implements IUserStore {
 | 
			
		||||
        await this.db(TABLE).del();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async count(): Promise<number> {
 | 
			
		||||
        return this.db
 | 
			
		||||
            .count('*')
 | 
			
		||||
            .from(TABLE)
 | 
			
		||||
            .then((res) => Number(res[0].count));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    destroy(): void {}
 | 
			
		||||
 | 
			
		||||
    async exists(id: number): Promise<boolean> {
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@ import { IUnleashConfig } from './types/option';
 | 
			
		||||
import { IUnleashStores } from './types/stores';
 | 
			
		||||
import Timer = NodeJS.Timer;
 | 
			
		||||
 | 
			
		||||
const THREE_HOURS = 3 * 60 * 60 * 1000;
 | 
			
		||||
const TWO_HOURS = 2 * 60 * 60 * 1000;
 | 
			
		||||
const ONE_MINUTE = 60 * 1000;
 | 
			
		||||
 | 
			
		||||
export default class MetricsMonitor {
 | 
			
		||||
@ -37,7 +37,13 @@ export default class MetricsMonitor {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const { eventStore, clientMetricsStore, featureToggleStore } = stores;
 | 
			
		||||
        const {
 | 
			
		||||
            eventStore,
 | 
			
		||||
            clientMetricsStore,
 | 
			
		||||
            featureToggleStore,
 | 
			
		||||
            userStore,
 | 
			
		||||
            projectStore,
 | 
			
		||||
        } = stores;
 | 
			
		||||
 | 
			
		||||
        client.collectDefaultMetrics();
 | 
			
		||||
 | 
			
		||||
@ -68,25 +74,44 @@ export default class MetricsMonitor {
 | 
			
		||||
            help: 'Number of feature toggles',
 | 
			
		||||
            labelNames: ['version'],
 | 
			
		||||
        });
 | 
			
		||||
        const usersTotal = new client.Gauge({
 | 
			
		||||
            name: 'users_total',
 | 
			
		||||
            help: 'Number of users',
 | 
			
		||||
        });
 | 
			
		||||
        const projectsTotal = new client.Gauge({
 | 
			
		||||
            name: 'projects_total',
 | 
			
		||||
            help: 'Number of projects',
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        async function collectFeatureToggleMetrics() {
 | 
			
		||||
            featureTogglesTotal.reset();
 | 
			
		||||
            let togglesCount;
 | 
			
		||||
        async function collectStaticCounters() {
 | 
			
		||||
            let togglesCount: number = 0;
 | 
			
		||||
            let usersCount: number;
 | 
			
		||||
            let projectsCount: number;
 | 
			
		||||
            try {
 | 
			
		||||
                togglesCount = await featureToggleStore.count({
 | 
			
		||||
                    archived: false,
 | 
			
		||||
                });
 | 
			
		||||
                usersCount = await userStore.count();
 | 
			
		||||
                projectsCount = await projectStore.count();
 | 
			
		||||
                // eslint-disable-next-line no-empty
 | 
			
		||||
            } catch (e) {}
 | 
			
		||||
 | 
			
		||||
            togglesCount = togglesCount || 0;
 | 
			
		||||
            featureTogglesTotal.reset();
 | 
			
		||||
            featureTogglesTotal.labels(version).set(togglesCount);
 | 
			
		||||
            if (usersCount) {
 | 
			
		||||
                usersTotal.reset();
 | 
			
		||||
                usersTotal.set(usersCount);
 | 
			
		||||
            }
 | 
			
		||||
            if (projectsCount) {
 | 
			
		||||
                projectsTotal.reset();
 | 
			
		||||
                projectsTotal.set(usersCount);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        collectFeatureToggleMetrics();
 | 
			
		||||
        collectStaticCounters();
 | 
			
		||||
        this.timer = setInterval(
 | 
			
		||||
            () => collectFeatureToggleMetrics(),
 | 
			
		||||
            THREE_HOURS,
 | 
			
		||||
            () => collectStaticCounters(),
 | 
			
		||||
            TWO_HOURS,
 | 
			
		||||
        ).unref();
 | 
			
		||||
 | 
			
		||||
        eventBus.on(
 | 
			
		||||
 | 
			
		||||
@ -31,4 +31,5 @@ export interface IProjectStore extends Store<IProject, string> {
 | 
			
		||||
        projectId: string,
 | 
			
		||||
        archived: boolean,
 | 
			
		||||
    ): Promise<IFeatureOverview[]>;
 | 
			
		||||
    count(): Promise<number>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -37,4 +37,5 @@ export interface IUserStore extends Store<IUser, number> {
 | 
			
		||||
    setPasswordHash(userId: number, passwordHash: string): Promise<void>;
 | 
			
		||||
    incLoginAttempts(user: IUser): Promise<void>;
 | 
			
		||||
    successfullyLogin(user: IUser): Promise<void>;
 | 
			
		||||
    count(): Promise<number>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								src/test/fixtures/fake-project-store.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								src/test/fixtures/fake-project-store.ts
									
									
									
									
										vendored
									
									
								
							@ -64,6 +64,10 @@ export default class FakeProjectStore implements IProjectStore {
 | 
			
		||||
 | 
			
		||||
    destroy(): void {}
 | 
			
		||||
 | 
			
		||||
    async count(): Promise<number> {
 | 
			
		||||
        return this.projects.length;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async exists(key: string): Promise<boolean> {
 | 
			
		||||
        return this.projects.some((p) => p.id === key);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								src/test/fixtures/fake-user-store.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								src/test/fixtures/fake-user-store.ts
									
									
									
									
										vendored
									
									
								
							@ -38,6 +38,10 @@ class UserStoreMock implements IUserStore {
 | 
			
		||||
        return this.data.some((u) => u.id === key);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async count(): Promise<number> {
 | 
			
		||||
        return this.data.length;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async get(key: number): Promise<IUser> {
 | 
			
		||||
        return this.data.find((u) => u.id === key);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user