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 [];
 | 
					        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
 | 
					    // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 | 
				
			||||||
    private getEnvironment(r: any): IEnvironmentOverview {
 | 
					    private getEnvironment(r: any): IEnvironmentOverview {
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
 | 
				
			|||||||
@ -176,6 +176,13 @@ class UserStore implements IUserStore {
 | 
				
			|||||||
        await this.db(TABLE).del();
 | 
					        await this.db(TABLE).del();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async count(): Promise<number> {
 | 
				
			||||||
 | 
					        return this.db
 | 
				
			||||||
 | 
					            .count('*')
 | 
				
			||||||
 | 
					            .from(TABLE)
 | 
				
			||||||
 | 
					            .then((res) => Number(res[0].count));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    destroy(): void {}
 | 
					    destroy(): void {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async exists(id: number): Promise<boolean> {
 | 
					    async exists(id: number): Promise<boolean> {
 | 
				
			||||||
 | 
				
			|||||||
@ -13,7 +13,7 @@ import { IUnleashConfig } from './types/option';
 | 
				
			|||||||
import { IUnleashStores } from './types/stores';
 | 
					import { IUnleashStores } from './types/stores';
 | 
				
			||||||
import Timer = NodeJS.Timer;
 | 
					import Timer = NodeJS.Timer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const THREE_HOURS = 3 * 60 * 60 * 1000;
 | 
					const TWO_HOURS = 2 * 60 * 60 * 1000;
 | 
				
			||||||
const ONE_MINUTE = 60 * 1000;
 | 
					const ONE_MINUTE = 60 * 1000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class MetricsMonitor {
 | 
					export default class MetricsMonitor {
 | 
				
			||||||
@ -37,7 +37,13 @@ export default class MetricsMonitor {
 | 
				
			|||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const { eventStore, clientMetricsStore, featureToggleStore } = stores;
 | 
					        const {
 | 
				
			||||||
 | 
					            eventStore,
 | 
				
			||||||
 | 
					            clientMetricsStore,
 | 
				
			||||||
 | 
					            featureToggleStore,
 | 
				
			||||||
 | 
					            userStore,
 | 
				
			||||||
 | 
					            projectStore,
 | 
				
			||||||
 | 
					        } = stores;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        client.collectDefaultMetrics();
 | 
					        client.collectDefaultMetrics();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -68,25 +74,44 @@ export default class MetricsMonitor {
 | 
				
			|||||||
            help: 'Number of feature toggles',
 | 
					            help: 'Number of feature toggles',
 | 
				
			||||||
            labelNames: ['version'],
 | 
					            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() {
 | 
					        async function collectStaticCounters() {
 | 
				
			||||||
            featureTogglesTotal.reset();
 | 
					            let togglesCount: number = 0;
 | 
				
			||||||
            let togglesCount;
 | 
					            let usersCount: number;
 | 
				
			||||||
 | 
					            let projectsCount: number;
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                togglesCount = await featureToggleStore.count({
 | 
					                togglesCount = await featureToggleStore.count({
 | 
				
			||||||
                    archived: false,
 | 
					                    archived: false,
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
 | 
					                usersCount = await userStore.count();
 | 
				
			||||||
 | 
					                projectsCount = await projectStore.count();
 | 
				
			||||||
                // eslint-disable-next-line no-empty
 | 
					                // eslint-disable-next-line no-empty
 | 
				
			||||||
            } catch (e) {}
 | 
					            } catch (e) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            togglesCount = togglesCount || 0;
 | 
					            featureTogglesTotal.reset();
 | 
				
			||||||
            featureTogglesTotal.labels(version).set(togglesCount);
 | 
					            featureTogglesTotal.labels(version).set(togglesCount);
 | 
				
			||||||
 | 
					            if (usersCount) {
 | 
				
			||||||
 | 
					                usersTotal.reset();
 | 
				
			||||||
 | 
					                usersTotal.set(usersCount);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (projectsCount) {
 | 
				
			||||||
 | 
					                projectsTotal.reset();
 | 
				
			||||||
 | 
					                projectsTotal.set(usersCount);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        collectFeatureToggleMetrics();
 | 
					        collectStaticCounters();
 | 
				
			||||||
        this.timer = setInterval(
 | 
					        this.timer = setInterval(
 | 
				
			||||||
            () => collectFeatureToggleMetrics(),
 | 
					            () => collectStaticCounters(),
 | 
				
			||||||
            THREE_HOURS,
 | 
					            TWO_HOURS,
 | 
				
			||||||
        ).unref();
 | 
					        ).unref();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        eventBus.on(
 | 
					        eventBus.on(
 | 
				
			||||||
 | 
				
			|||||||
@ -31,4 +31,5 @@ export interface IProjectStore extends Store<IProject, string> {
 | 
				
			|||||||
        projectId: string,
 | 
					        projectId: string,
 | 
				
			||||||
        archived: boolean,
 | 
					        archived: boolean,
 | 
				
			||||||
    ): Promise<IFeatureOverview[]>;
 | 
					    ): Promise<IFeatureOverview[]>;
 | 
				
			||||||
 | 
					    count(): Promise<number>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -37,4 +37,5 @@ export interface IUserStore extends Store<IUser, number> {
 | 
				
			|||||||
    setPasswordHash(userId: number, passwordHash: string): Promise<void>;
 | 
					    setPasswordHash(userId: number, passwordHash: string): Promise<void>;
 | 
				
			||||||
    incLoginAttempts(user: IUser): Promise<void>;
 | 
					    incLoginAttempts(user: IUser): Promise<void>;
 | 
				
			||||||
    successfullyLogin(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 {}
 | 
					    destroy(): void {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async count(): Promise<number> {
 | 
				
			||||||
 | 
					        return this.projects.length;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async exists(key: string): Promise<boolean> {
 | 
					    async exists(key: string): Promise<boolean> {
 | 
				
			||||||
        return this.projects.some((p) => p.id === key);
 | 
					        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);
 | 
					        return this.data.some((u) => u.id === key);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async count(): Promise<number> {
 | 
				
			||||||
 | 
					        return this.data.length;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async get(key: number): Promise<IUser> {
 | 
					    async get(key: number): Promise<IUser> {
 | 
				
			||||||
        return this.data.find((u) => u.id === key);
 | 
					        return this.data.find((u) => u.id === key);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user