Skip to content

Commit 659b45a

Browse files
Revert back to Histogram for metrics
1 parent 852af53 commit 659b45a

File tree

2 files changed

+53
-80
lines changed

2 files changed

+53
-80
lines changed

src/shared/discord.ts

Lines changed: 45 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,17 @@ import type {
1212

1313
import { Client, Events, Routes, User } from "discord.js";
1414
import assert from "node:assert";
15-
import { Gauge, Summary } from "prom-client";
15+
import { Gauge, Histogram } from "prom-client";
1616

1717
import loggerFactory from "../logger.factory";
1818

1919
// region Logger and Metrics
2020
const logger = loggerFactory(module);
2121

22-
const interactionRequestDuration = new Summary({
23-
help: "Interaction request duration in milliseconds",
24-
labelNames: ["status", "handler"],
25-
name: "interaction_request_duration_milliseconds",
22+
const interactionRequestDuration = new Histogram({
23+
help: "Interaction request duration in seconds",
24+
labelNames: ["handler", "status"],
25+
name: "interaction_request_duration_seconds",
2626
});
2727

2828
const shardPing = new Gauge({
@@ -181,69 +181,32 @@ const getHandler = (interaction: BaseInteraction, uiid?: string) => {
181181
}
182182
};
183183

184-
const onInteraction = (
185-
status: "error" | "success",
186-
interaction: BaseInteraction,
187-
startRequestTime: number,
188-
uiid?: string,
189-
) => {
190-
const handler = getHandler(interaction, uiid);
191-
const labels = { handler, status };
192-
193-
return (result: unknown) => {
194-
const endRequestTime = performance.now();
195-
const requestDuration = endRequestTime - startRequestTime;
196-
interactionRequestDuration.observe(labels, requestDuration);
197-
198-
const childLogger = logger.child({
199-
interaction,
200-
labels,
201-
requestDuration,
202-
});
203-
204-
if (status === "error") {
205-
childLogger.error(result, "ON_INTERACTION_ERROR");
206-
} else if (requestDuration >= 2500) {
207-
childLogger.warn(result, "ON_INTERACTION_SUCCESS_SLOW");
208-
} else {
209-
childLogger.info(result, "ON_INTERACTION_SUCCESS");
210-
}
211-
212-
return status;
213-
};
184+
const createContext = (status: "error" | "success", uiid?: string) => {
185+
return (result: unknown) => ({ result, status, uiid });
214186
};
215187

216-
const onCommand = (
217-
interaction: CommandInteraction,
218-
startRequestTime: number,
219-
) => {
188+
const onCommand = (interaction: CommandInteraction) => {
220189
for (const [name, { onCommand }] of commands) {
221190
if (name === interaction.commandName) {
222191
return onCommand(interaction)
223-
.then(onInteraction("success", interaction, startRequestTime))
224-
.catch(onInteraction("error", interaction, startRequestTime));
192+
.then(createContext("success"))
193+
.catch(createContext("error"));
225194
}
226195
}
227196
};
228197

229-
const onAutocomplete = (
230-
interaction: AutocompleteInteraction,
231-
startRequestTime: number,
232-
) => {
198+
const onAutocomplete = (interaction: AutocompleteInteraction) => {
233199
for (const [name, { onAutocomplete }] of commands) {
234200
if (name === interaction.commandName) {
235201
assert(onAutocomplete !== undefined);
236202
return onAutocomplete(interaction)
237-
.then(onInteraction("success", interaction, startRequestTime))
238-
.catch(onInteraction("error", interaction, startRequestTime));
203+
.then(createContext("success"))
204+
.catch(createContext("error"));
239205
}
240206
}
241207
};
242208

243-
const onMessageComponent = (
244-
interaction: MessageComponentInteraction,
245-
startRequestTime: number,
246-
) => {
209+
const onMessageComponent = (interaction: MessageComponentInteraction) => {
247210
let { customId } = interaction;
248211
for (const [uiid, onComponent] of components) {
249212
const legacyPrefix = `GLOBAL_${uiid}_`;
@@ -255,42 +218,58 @@ const onMessageComponent = (
255218
if (customId.startsWith(uiid)) {
256219
const id = customId.slice(uiid.length);
257220
return onComponent(interaction, id)
258-
.then(onInteraction("success", interaction, startRequestTime, uiid))
259-
.catch(onInteraction("error", interaction, startRequestTime, uiid));
221+
.then(createContext("success", uiid))
222+
.catch(createContext("error", uiid));
260223
}
261224
}
262225
};
263226

264-
const onModalSubmit = (
265-
interaction: ModalSubmitInteraction,
266-
startRequestTime: number,
267-
) => {
227+
const onModalSubmit = (interaction: ModalSubmitInteraction) => {
268228
const { customId } = interaction;
269229
for (const [uiid, onModal] of modals) {
270230
if (customId.startsWith(uiid)) {
271231
const id = customId.slice(uiid.length);
272232
return onModal(interaction, id)
273-
.then(onInteraction("success", interaction, startRequestTime, uiid))
274-
.catch(onInteraction("error", interaction, startRequestTime, uiid));
233+
.then(createContext("success", uiid))
234+
.catch(createContext("error", uiid));
275235
}
276236
}
277237
};
278238

279239
discord.on(Events.InteractionCreate, async (interaction) => {
280-
const startRequestTime = performance.now();
240+
const observeRequestDuration = interactionRequestDuration.startTimer();
281241

282-
let status;
242+
let context;
283243
if (interaction.isCommand()) {
284-
status = await onCommand(interaction, startRequestTime);
244+
context = await onCommand(interaction);
285245
} else if (interaction.isAutocomplete()) {
286-
status = await onAutocomplete(interaction, startRequestTime);
246+
context = await onAutocomplete(interaction);
287247
} else if (interaction.isMessageComponent()) {
288-
status = await onMessageComponent(interaction, startRequestTime);
248+
context = await onMessageComponent(interaction);
289249
} else if (interaction.isModalSubmit()) {
290-
status = await onModalSubmit(interaction, startRequestTime);
250+
context = await onModalSubmit(interaction);
291251
}
292252

293-
assert(status !== undefined);
253+
assert(context !== undefined);
254+
const { result, status, uiid } = context;
255+
256+
const handler = getHandler(interaction, uiid);
257+
const labels = { handler, status };
258+
const requestDuration = observeRequestDuration(labels);
259+
260+
const childLogger = logger.child({
261+
interaction,
262+
labels,
263+
requestDuration,
264+
});
265+
266+
if (status === "error") {
267+
childLogger.error(result, "ON_INTERACTION_ERROR");
268+
} else if (requestDuration >= 2.5) {
269+
childLogger.warn(result, "ON_INTERACTION_SUCCESS_SLOW");
270+
} else {
271+
childLogger.info(result, "ON_INTERACTION_SUCCESS");
272+
}
294273
});
295274
// endregion
296275
// endregion

src/shared/postgresql.ts

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { PoolClient } from "pg";
22

33
import { Pool } from "pg";
4-
import { Summary } from "prom-client";
4+
import { Histogram } from "prom-client";
55

66
import type { Caller } from "./caller";
77

@@ -15,10 +15,10 @@ type Callback<T> = (client: PoolClient) => Promise<T>;
1515
// region Logger and Metrics
1616
const logger = loggerFactory(module);
1717

18-
const databaseRequestDuration = new Summary({
19-
help: "Database request duration in milliseconds",
20-
labelNames: ["caller", "status", "connected"],
21-
name: "database_request_duration_milliseconds",
18+
const databaseRequestDuration = new Histogram({
19+
help: "Database request duration in seconds",
20+
labelNames: ["caller", "connected", "status"],
21+
name: "database_request_duration_seconds",
2222
});
2323
// endregion
2424

@@ -31,7 +31,7 @@ const postgresql = new Pool({
3131
});
3232

3333
export const useClient = async <T>(caller: Caller, callback: Callback<T>) => {
34-
const startRequestTime = performance.now();
34+
const observeRequestDuration = databaseRequestDuration.startTimer();
3535
const onDatabase =
3636
(status: "error" | "success", client?: PoolClient) => (result: unknown) => {
3737
client?.release(status === "error");
@@ -42,14 +42,8 @@ export const useClient = async <T>(caller: Caller, callback: Callback<T>) => {
4242
status,
4343
};
4444

45-
const endRequestTime = performance.now();
46-
const requestDuration = endRequestTime - startRequestTime;
47-
databaseRequestDuration.observe(labels, requestDuration);
48-
49-
const childLogger = logger.child({
50-
labels,
51-
requestDuration,
52-
});
45+
const requestDuration = observeRequestDuration(labels);
46+
const childLogger = logger.child({ labels, requestDuration });
5347

5448
if (status === "error") {
5549
childLogger.error(result, "ON_DATABASE_ERROR");

0 commit comments

Comments
 (0)