Merge branch 'metrics-resp' into 'main'

HTTP Response metrics

See merge request soapbox-pub/ditto!410
This commit is contained in:
Alex Gleason 2024-07-04 23:11:12 +00:00
commit a9afe03a37
4 changed files with 31 additions and 15 deletions

View file

@ -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';
@ -151,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,
@ -340,12 +340,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;

11
src/controllers/error.ts Normal file
View file

@ -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);
};

View file

@ -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',

View file

@ -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 });
};