Skip to content

Commit

Permalink
fix: add user and project counters
Browse files Browse the repository at this point in the history
  • Loading branch information
ivarconr committed Aug 27, 2021
1 parent 14857b0 commit aab4602
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 9 deletions.
7 changes: 7 additions & 0 deletions src/lib/db/project-store.ts
Expand Up @@ -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 {
Expand Down
7 changes: 7 additions & 0 deletions src/lib/db/user-store.ts
Expand Up @@ -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> {
Expand Down
43 changes: 34 additions & 9 deletions src/lib/metrics.ts
Expand Up @@ -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 {
Expand All @@ -37,7 +37,13 @@ export default class MetricsMonitor {
return;
}

const { eventStore, clientMetricsStore, featureToggleStore } = stores;
const {
eventStore,
clientMetricsStore,
featureToggleStore,
userStore,
projectStore,
} = stores;

client.collectDefaultMetrics();

Expand Down Expand Up @@ -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(
Expand Down
1 change: 1 addition & 0 deletions src/lib/types/stores/project-store.ts
Expand Up @@ -31,4 +31,5 @@ export interface IProjectStore extends Store<IProject, string> {
projectId: string,
archived: boolean,
): Promise<IFeatureOverview[]>;
count(): Promise<number>;
}
1 change: 1 addition & 0 deletions src/lib/types/stores/user-store.ts
Expand Up @@ -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 changes: 4 additions & 0 deletions src/test/fixtures/fake-project-store.ts
Expand Up @@ -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);
}
Expand Down
4 changes: 4 additions & 0 deletions src/test/fixtures/fake-user-store.ts
Expand Up @@ -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);
}
Expand Down

0 comments on commit aab4602

Please sign in to comment.