Skip to content

Commit 1697a76

Browse files
Copilotd-gubert
andcommitted
add Prometheus best-practices metric duplicates (Histograms + _total counters)"
Co-authored-by: d-gubert <1810309+d-gubert@users.noreply.github.com>
1 parent edb0ad4 commit 1697a76

21 files changed

Lines changed: 147 additions & 11 deletions

File tree

apps/meteor/app/api/server/api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ export const startRestAPI = () => {
105105
.use(remoteAddressMiddleware)
106106
.use(cors(settings))
107107
.use(loggerMiddleware(logger))
108-
.use(metricsMiddleware({ basePathRegex: new RegExp(/^\/api\/v1\//), api: API.v1, settings, summary: metrics.rocketchatRestApi }))
108+
.use(metricsMiddleware({ basePathRegex: new RegExp(/^\/api\/v1\//), api: API.v1, settings, summary: metrics.rocketchatRestApi, histogram: metrics.rocketchatRestApiSeconds }))
109109
.use(tracerSpanMiddleware)
110110
.use(API.v1.router)
111111
.use(API.default.router).router,

apps/meteor/app/api/server/middlewares/metrics.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { MiddlewareHandler } from 'hono';
2-
import type { Summary } from 'prom-client';
2+
import type { Histogram, Summary } from 'prom-client';
33

44
import type { CachedSettings } from '../../../settings/server/CachedSettings';
55
import type { APIClass } from '../ApiClass';
@@ -10,14 +10,17 @@ export const metricsMiddleware =
1010
api,
1111
settings,
1212
summary,
13+
histogram,
1314
}: {
1415
basePathRegex?: RegExp;
1516
api: APIClass;
1617
settings: CachedSettings;
1718
summary: Summary;
19+
histogram?: Histogram;
1820
}): MiddlewareHandler =>
1921
async (c, next) => {
2022
const rocketchatRestApiEnd = summary.startTimer();
23+
const rocketchatRestApiHistEnd = histogram?.startTimer();
2124

2225
await next();
2326

@@ -26,11 +29,14 @@ export const metricsMiddleware =
2629
// get rid of the base path (i.e.: /api/v1/)
2730
const entrypoint = basePathRegex ? routePath.replace(basePathRegex, '') : routePath;
2831

29-
rocketchatRestApiEnd({
32+
const labels = {
3033
status: c.res.status,
3134
method: method.toLowerCase(),
3235
version: api.version,
3336
...(settings.get('Prometheus_API_User_Agent') && { user_agent: c.req.header('user-agent') }),
3437
entrypoint: basePathRegex && entrypoint.startsWith('method.call') ? decodeURIComponent(path.replace(basePathRegex, '')) : entrypoint,
35-
});
38+
};
39+
40+
rocketchatRestApiEnd(labels);
41+
rocketchatRestApiHistEnd?.(labels);
3642
};

apps/meteor/app/integrations/server/api/api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ const Api = new WebHookAPI({
428428

429429
Api.router
430430
.use(loggerMiddleware(integrationLogger))
431-
.use(metricsMiddleware({ basePathRegex: new RegExp(/^\/hooks\//), api: Api, settings, summary: metrics.rocketchatRestApi }))
431+
.use(metricsMiddleware({ basePathRegex: new RegExp(/^\/hooks\//), api: Api, settings, summary: metrics.rocketchatRestApi, histogram: metrics.rocketchatRestApiSeconds }))
432432
.use(tracerSpanMiddleware);
433433

434434
Api.addRoute(

apps/meteor/app/lib/server/functions/notifications/desktop.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export async function notifyDesktopUser({
6767
};
6868

6969
metrics.notificationsSent.inc({ notification_type: 'desktop' });
70+
metrics.notificationsSentTotal.inc({ notification_type: 'desktop' });
7071

7172
void api.broadcast('notify.desktop', userId, payload);
7273
}

apps/meteor/app/lib/server/functions/notifications/email.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,11 +184,13 @@ export async function getEmailData({ message, receiver, sender, subscription, ro
184184
}
185185

186186
metrics.notificationsSent.inc({ notification_type: 'email' });
187+
metrics.notificationsSentTotal.inc({ notification_type: 'email' });
187188
return email;
188189
}
189190

190191
export function sendEmailFromData(data) {
191192
metrics.notificationsSent.inc({ notification_type: 'email' });
193+
metrics.notificationsSentTotal.inc({ notification_type: 'email' });
192194
return Mailer.send(data);
193195
}
194196

apps/meteor/app/lib/server/lib/debug.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,14 @@ const wrapMethods = function (name, originalHandler, methodsMap) {
5757

5858
const method = name === 'stream' ? `${name}:${originalArgs[0]}` : name;
5959

60-
const end = metrics.meteorMethods.startTimer({
60+
const meteorMethodLabels = {
6161
method,
6262
has_connection: this.connection != null,
6363
has_user: this.userId != null,
64-
});
64+
};
65+
66+
const end = metrics.meteorMethods.startTimer(meteorMethodLabels);
67+
const endHistogram = metrics.meteorMethodsSeconds.startTimer(meteorMethodLabels);
6568

6669
logger.method({
6770
method,
@@ -84,6 +87,7 @@ const wrapMethods = function (name, originalHandler, methodsMap) {
8487
async () => {
8588
const result = await originalHandler.apply(this, originalArgs);
8689
end();
90+
endHistogram();
8791
return result;
8892
},
8993
);
@@ -115,10 +119,12 @@ Meteor.publish = function (name, func) {
115119
});
116120

117121
const end = metrics.meteorSubscriptions.startTimer({ subscription: name });
122+
const endHistogram = metrics.meteorSubscriptionsSeconds.startTimer({ subscription: name });
118123

119124
const originalReady = this.ready;
120125
this.ready = function () {
121126
end();
127+
endHistogram();
122128
return originalReady.apply(this, args);
123129
};
124130

apps/meteor/app/lib/server/lib/deprecationWarningLogger.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export const apiDeprecationLogger = ((logger) => {
4040
writeDeprecationHeader(res, 'endpoint-deprecation', message, version);
4141

4242
metrics.deprecations.inc({ type: 'deprecation', kind: 'endpoint', name: endpoint });
43+
metrics.deprecationsTotal.inc({ type: 'deprecation', kind: 'endpoint', name: endpoint });
4344

4445
logger.warn({ msg: message, endpoint, version, info });
4546
},
@@ -63,6 +64,7 @@ export const apiDeprecationLogger = ((logger) => {
6364
}
6465

6566
metrics.deprecations.inc({ type: 'parameter-deprecation', kind: 'endpoint', name: endpoint, params: parameter });
67+
metrics.deprecationsTotal.inc({ type: 'parameter-deprecation', kind: 'endpoint', name: endpoint, params: parameter });
6668

6769
writeDeprecationHeader(res, 'parameter-deprecation', message, version);
6870

@@ -92,6 +94,7 @@ export const apiDeprecationLogger = ((logger) => {
9294
compareVersions(version, message);
9395

9496
metrics.deprecations.inc({ type: 'invalid-usage', kind: 'endpoint', name: endpoint, params: parameter });
97+
metrics.deprecationsTotal.inc({ type: 'invalid-usage', kind: 'endpoint', name: endpoint, params: parameter });
9598

9699
writeDeprecationHeader(res, 'invalid-usage', message, version);
97100

@@ -114,6 +117,7 @@ export const methodDeprecationLogger = ((logger) => {
114117
}
115118
compareVersions(version, message);
116119
metrics.deprecations.inc({ type: 'deprecation', name: method, kind: 'method' });
120+
metrics.deprecationsTotal.inc({ type: 'deprecation', name: method, kind: 'method' });
117121
logger.warn({ msg: message, method, version, replacement });
118122
},
119123
parameter: (method: string, parameter: string, version: DeprecationLoggerNextPlannedVersion) => {
@@ -123,6 +127,7 @@ export const methodDeprecationLogger = ((logger) => {
123127
}
124128

125129
metrics.deprecations.inc({ type: 'parameter-deprecation', name: method, params: parameter });
130+
metrics.deprecationsTotal.inc({ type: 'parameter-deprecation', name: method, params: parameter });
126131

127132
compareVersions(version, message);
128133
logger.warn({ msg: message, method, parameter, version });
@@ -149,6 +154,7 @@ export const methodDeprecationLogger = ((logger) => {
149154
compareVersions(version, message);
150155

151156
metrics.deprecations.inc({ type: 'invalid-usage', name: method, params: parameter, kind: 'method' });
157+
metrics.deprecationsTotal.inc({ type: 'invalid-usage', name: method, params: parameter, kind: 'method' });
152158

153159
logger.warn({ msg: message, method, parameter, version });
154160
},

apps/meteor/app/lib/server/lib/processDirectEmail.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ export const processDirectEmail = async function (email: ParsedMail): Promise<vo
110110
}
111111

112112
metrics.messagesSent.inc(); // TODO This line needs to be moved to it's proper place. See the comments on: https://github.com/RocketChat/Rocket.Chat/pull/5736
113+
metrics.messagesSentTotal.inc();
113114

114115
const message: Pick<IMessage, 'ts' | 'msg' | 'groupable' | 'rid' | 'sentByEmail' | 'tmid'> = {
115116
ts: tsDiff < 10000 ? ts : new Date(),

apps/meteor/app/lib/server/methods/sendMessage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ export async function executeSendMessage(
106106
}
107107

108108
metrics.messagesSent.inc(); // TODO This line needs to be moved to it's proper place. See the comments on: https://github.com/RocketChat/Rocket.Chat/pull/5736
109+
metrics.messagesSentTotal.inc();
109110
return await sendMessage(user, message, room, { previewUrls: extraInfo?.previewUrls });
110111
} catch (err: any) {
111112
SystemLogger.error({ msg: 'Error sending message:', err });

apps/meteor/app/lib/server/startup/rateLimiter.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,14 @@ const callback = (msg, name) => async (reply, input) => {
134134
name: input.name,
135135
connection_id: input.connectionId,
136136
});
137+
metrics.ddpRateLimitExceededTotal.inc({
138+
limit_name: name,
139+
user_id: input.userId,
140+
client_address: input.clientAddress,
141+
type: input.type,
142+
name: input.name,
143+
connection_id: input.connectionId,
144+
});
137145
// sleep before sending the error to slow down next requests
138146
if (slowDownRate > 0 && reply.numInvocationsExceeded) {
139147
await sleep(slowDownRate * reply.numInvocationsExceeded);

0 commit comments

Comments
 (0)