From d4713cae012d7d05ed9264d6cbba2c3d1935c7c6 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Thu, 4 Jul 2024 23:53:20 +0100 Subject: [PATCH 1/2] Move errorHandler to a separate file --- src/app.ts | 8 ++------ src/controllers/error.ts | 11 +++++++++++ 2 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 src/controllers/error.ts diff --git a/src/app.ts b/src/app.ts index 4c0ffc7e..f7f4f29a 100644 --- a/src/app.ts +++ b/src/app.ts @@ -108,6 +108,7 @@ import { trendingStatusesController, trendingTagsController, } from '@/controllers/api/trends.ts'; +import { errorHandler } from '@/controllers/error.ts'; import { metricsController } from '@/controllers/metrics.ts'; import { indexController } from '@/controllers/site.ts'; import { nodeInfoController, nodeInfoSchemaController } from '@/controllers/well-known/nodeinfo.ts'; @@ -340,12 +341,7 @@ app.get('/', frontendController, indexController); // Fallback app.get('*', publicFiles, staticFiles, frontendController); -app.onError((err, c) => { - if (err.message === 'canceling statement due to statement timeout') { - return c.json({ error: 'The server was unable to respond in a timely manner' }, 500); - } - return c.json({ error: 'Something went wrong' }, 500); -}); +app.onError(errorHandler); export default app; diff --git a/src/controllers/error.ts b/src/controllers/error.ts new file mode 100644 index 00000000..fa5e4d32 --- /dev/null +++ b/src/controllers/error.ts @@ -0,0 +1,11 @@ +import { ErrorHandler } from '@hono/hono'; + +export const errorHandler: ErrorHandler = (err, c) => { + console.error(err); + + if (err.message === 'canceling statement due to statement timeout') { + return c.json({ error: 'The server was unable to respond in a timely manner' }, 500); + } + + return c.json({ error: 'Something went wrong' }, 500); +}; From 96a8ccb2e637ffdf1fec979007377d46d321750f Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Fri, 5 Jul 2024 00:00:57 +0100 Subject: [PATCH 2/2] HTTP Response metrics --- src/app.ts | 15 +++++++-------- src/metrics.ts | 6 ++++++ src/middleware/metricsMiddleware.ts | 6 +++++- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/app.ts b/src/app.ts index f7f4f29a..1cb3746b 100644 --- a/src/app.ts +++ b/src/app.ts @@ -152,18 +152,17 @@ if (Conf.cronEnabled) { app.use('*', rateLimitMiddleware(300, Time.minutes(5))); -app.use('/api/*', logger(debug)); -app.use('/.well-known/*', logger(debug)); -app.use('/users/*', logger(debug)); -app.use('/nodeinfo/*', logger(debug)); -app.use('/oauth/*', logger(debug)); +app.use('/api/*', metricsMiddleware, logger(debug)); +app.use('/.well-known/*', metricsMiddleware, logger(debug)); +app.use('/users/*', metricsMiddleware, logger(debug)); +app.use('/nodeinfo/*', metricsMiddleware, logger(debug)); +app.use('/oauth/*', metricsMiddleware, logger(debug)); -app.get('/api/v1/streaming', streamingController); -app.get('/relay', relayController); +app.get('/api/v1/streaming', metricsMiddleware, streamingController); +app.get('/relay', metricsMiddleware, relayController); app.use( '*', - metricsMiddleware, cspMiddleware(), cors({ origin: '*', exposeHeaders: ['link'] }), signerMiddleware, diff --git a/src/metrics.ts b/src/metrics.ts index 96d91599..67da3f49 100644 --- a/src/metrics.ts +++ b/src/metrics.ts @@ -6,6 +6,12 @@ export const httpRequestCounter = new Counter({ labelNames: ['method'], }); +export const httpResponseCounter = new Counter({ + name: 'http_responses_total', + help: 'Total number of HTTP responses', + labelNames: ['status', 'path'], +}); + export const streamingConnectionsGauge = new Gauge({ name: 'streaming_connections', help: 'Number of active connections to the streaming API', diff --git a/src/middleware/metricsMiddleware.ts b/src/middleware/metricsMiddleware.ts index 1a491186..d7ac43d5 100644 --- a/src/middleware/metricsMiddleware.ts +++ b/src/middleware/metricsMiddleware.ts @@ -1,10 +1,14 @@ import { MiddlewareHandler } from '@hono/hono'; -import { httpRequestCounter } from '@/metrics.ts'; +import { httpRequestCounter, httpResponseCounter } from '@/metrics.ts'; export const metricsMiddleware: MiddlewareHandler = async (c, next) => { const { method } = c.req; httpRequestCounter.inc({ method }); await next(); + + const { status } = c.res; + const path = c.req.matchedRoutes.find((r) => r.method !== 'ALL')?.path ?? c.req.routePath; + httpResponseCounter.inc({ status, path }); };