@@ -12,17 +12,17 @@ import type {
1212
1313import { Client , Events , Routes , User } from "discord.js" ;
1414import assert from "node:assert" ;
15- import { Gauge , Summary } from "prom-client" ;
15+ import { Gauge , Histogram } from "prom-client" ;
1616
1717import loggerFactory from "../logger.factory" ;
1818
1919// region Logger and Metrics
2020const 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
2828const 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
279239discord . 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
0 commit comments