fix metrics route normalization

This commit is contained in:
Daniel 2026-05-08 20:22:14 +02:00
parent 446a3b33d0
commit ba180d7dde
2 changed files with 23 additions and 3 deletions

View file

@ -29,11 +29,12 @@ const httpRequestsInProgress = new client.Gauge({
registers: [register]
});
function normalizeRoute(req) {
function normalizeRoute(req, statusCode) {
var routePath = req.route && req.route.path;
var baseUrl = req.baseUrl || '';
if (Array.isArray(routePath)) return baseUrl + routePath[0];
if (routePath) return baseUrl + routePath;
if (statusCode === 404) return 'unmatched';
var path = req.path || req.url || 'unknown';
return path
@ -45,13 +46,13 @@ function normalizeRoute(req) {
function metricsMiddleware(req, res, next) {
if (req.path === '/metrics') return next();
var route = normalizeRoute(req);
var route = req.route ? normalizeRoute(req) : 'pending';
var method = req.method;
var endTimer = httpRequestDuration.startTimer({ method, route });
httpRequestsInProgress.inc({ method, route });
res.on('finish', function() {
var finalRoute = normalizeRoute(req);
var finalRoute = normalizeRoute(req, res.statusCode);
var labels = {
method,
route: finalRoute,

View file

@ -43,6 +43,25 @@ test('metrics middleware uses the first path for Express array routes', async ()
assert.doesNotMatch(metrics, /route="\/,\/index\.html"/);
});
test('metrics middleware collapses unmatched 404 routes', async () => {
const req = {
method: 'GET',
path: '/wp-content/plugins/example.php',
url: '/wp-content/plugins/example.php?probe=1',
baseUrl: '',
route: null
};
const res = new EventEmitter();
res.statusCode = 404;
await new Promise((resolve) => metricsMiddleware(req, res, resolve));
res.emit('finish');
const metrics = await register.metrics();
assert.match(metrics, /route="unmatched"/);
assert.doesNotMatch(metrics, /wp-content\/plugins\/example\.php/);
});
test('metrics handler exposes prometheus content type', async () => {
const headers = {};
const res = {