Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Count daily and monthly peaks of concurrent connections #30573

Merged
merged 18 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/perfect-pianos-yawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/presence': minor
---

Add peak connections monitoring and methods to get and reset the counter
7 changes: 7 additions & 0 deletions .changeset/slow-coats-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@rocket.chat/meteor": minor
---

Add the daily and monthly peaks of concurrent connections to statistics
- Added `dailyPeakConnections` statistic for monitoring the daily peak of concurrent connections in a workspace;
- Added `maxMonthlyPeakConnections` statistic for monitoring the last 30 days peak of concurrent connections in a workspace;
7 changes: 6 additions & 1 deletion apps/meteor/app/statistics/server/lib/statistics.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { log } from 'console';
import os from 'os';

import { Analytics, Team, VideoConf } from '@rocket.chat/core-services';
import { Analytics, Team, VideoConf, Presence } from '@rocket.chat/core-services';
import type { IRoom, IStats } from '@rocket.chat/core-typings';
import { UserStatus } from '@rocket.chat/core-typings';
import {
Expand Down Expand Up @@ -579,6 +579,11 @@ export const statistics = {
const defaultLoggedInCustomScript = (await Settings.findOneById('Custom_Script_Logged_In'))?.packageValue;
statistics.loggedInCustomScriptChanged = settings.get('Custom_Script_Logged_In') !== defaultLoggedInCustomScript;

statistics.dailyPeakConnections = await Presence.getPeakConnections(true);

const peak = await Statistics.findMonthlyPeakConnections();
statistics.maxMonthlyPeakConnections = Math.max(statistics.dailyPeakConnections, peak?.dailyPeakConnections || 0);

statistics.matrixFederation = await getMatrixFederationStatistics();

// Omnichannel call stats
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ export default {
totalWebRTCCalls: 0,
uncaughtExceptionsCount: 0,
push: 0,
dailyPeakConnections: 0,
maxMonthlyPeakConnections: 0,
matrixFederation: {
enabled: false,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,8 @@ export default {
totalWebRTCCalls: 0,
uncaughtExceptionsCount: 0,
push: 0,
dailyPeakConnections: 0,
maxMonthlyPeakConnections: 0,
matrixFederation: {
enabled: false,
},
Expand Down
2 changes: 2 additions & 0 deletions apps/meteor/client/views/admin/info/UsageCard.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@ export default {
totalWebRTCCalls: 0,
uncaughtExceptionsCount: 0,
push: 0,
dailyPeakConnections: 0,
maxMonthlyPeakConnections: 0,
matrixFederation: {
enabled: false,
},
Expand Down
4 changes: 3 additions & 1 deletion apps/meteor/server/cron/statistics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,7 @@ export async function statsCron(logger: Logger): Promise<void> {

const now = new Date();

await cronJobs.add(name, `12 ${now.getHours()} * * *`, async () => generateStatistics(logger));
await cronJobs.add(name, `12 ${now.getHours()} * * *`, async () => {
await generateStatistics(logger);
});
}
21 changes: 21 additions & 0 deletions apps/meteor/server/models/raw/Statistics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,25 @@ export class StatisticsRaw extends BaseRaw<IStats> implements IStatisticsModel {
).toArray();
return records?.[0];
}

async findMonthlyPeakConnections() {
const oneMonthAgo = new Date();
oneMonthAgo.setDate(oneMonthAgo.getDate() - 30);
oneMonthAgo.setHours(0, 0, 0, 0);

return this.findOne<Pick<IStats, 'dailyPeakConnections' | 'createdAt'>>(
{
createdAt: { $gte: oneMonthAgo },
},
{
sort: {
dailyPeakConnections: -1,
},
projection: {
dailyPeakConnections: 1,
createdAt: 1,
},
},
);
}
}
15 changes: 15 additions & 0 deletions ee/packages/presence/src/Presence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export class Presence extends ServiceClass implements IPresence {

private connsPerInstance = new Map<string, number>();

private peakConnections = 0;

constructor() {
super();

Expand All @@ -35,6 +37,7 @@ export class Presence extends ServiceClass implements IPresence {
if (diff?.hasOwnProperty('extraInformation.conns')) {
this.connsPerInstance.set(id, diff['extraInformation.conns']);

this.peakConnections = Math.max(this.peakConnections, this.getTotalConnections());
this.validateAvailability();
}
});
Expand Down Expand Up @@ -251,4 +254,16 @@ export class Presence extends ServiceClass implements IPresence {
private getTotalConnections(): number {
return Array.from(this.connsPerInstance.values()).reduce((acc, conns) => acc + conns, 0);
}

getPeakConnections(reset = false): number {
const peak = this.peakConnections;
if (reset) {
this.resetPeakConnections();
}
return peak;
}

resetPeakConnections(): void {
this.peakConnections = 0;
}
}
2 changes: 2 additions & 0 deletions packages/core-services/src/types/IPresence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ export interface IPresence extends IServiceClass {
updateUserPresence(uid: string): Promise<void>;
toggleBroadcast(enabled: boolean): void;
getConnectionCount(): { current: number; max: number };
getPeakConnections(reset?: boolean): number;
resetPeakConnections(): void;
}
2 changes: 2 additions & 0 deletions packages/core-typings/src/IStats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ export interface IStats {
totalWebRTCCalls: number;
uncaughtExceptionsCount: number;
push: number;
dailyPeakConnections: number;
maxMonthlyPeakConnections: number;
matrixFederation: {
enabled: boolean;
};
Expand Down
1 change: 1 addition & 0 deletions packages/model-typings/src/models/IStatisticsModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ import type { IBaseModel } from './IBaseModel';

export interface IStatisticsModel extends IBaseModel<IStats> {
findLast(): Promise<IStats>;
findMonthlyPeakConnections(): Promise<Pick<IStats, 'dailyPeakConnections' | 'createdAt'> | null>;
}
Loading