78 lines
2.1 KiB
JavaScript
78 lines
2.1 KiB
JavaScript
const client = require('prom-client');
|
|
|
|
const register = new client.Registry();
|
|
|
|
client.collectDefaultMetrics({
|
|
prefix: 'ped_ai_',
|
|
register
|
|
});
|
|
|
|
const httpRequestsTotal = new client.Counter({
|
|
name: 'ped_ai_http_requests_total',
|
|
help: 'Total HTTP requests received by Ped-AI',
|
|
labelNames: ['method', 'route', 'status_code'],
|
|
registers: [register]
|
|
});
|
|
|
|
const httpRequestDuration = new client.Histogram({
|
|
name: 'ped_ai_http_request_duration_seconds',
|
|
help: 'HTTP request duration in seconds',
|
|
labelNames: ['method', 'route', 'status_code'],
|
|
buckets: [0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10],
|
|
registers: [register]
|
|
});
|
|
|
|
const httpRequestsInProgress = new client.Gauge({
|
|
name: 'ped_ai_http_requests_in_progress',
|
|
help: 'Number of Ped-AI HTTP requests currently in progress',
|
|
labelNames: ['method', 'route'],
|
|
registers: [register]
|
|
});
|
|
|
|
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
|
|
.replace(/\b[0-9a-f]{8,}\b/gi, ':id')
|
|
.replace(/\b\d+\b/g, ':id')
|
|
.replace(/\?.*$/, '');
|
|
}
|
|
|
|
function metricsMiddleware(req, res, next) {
|
|
if (req.path === '/metrics') return next();
|
|
|
|
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, res.statusCode);
|
|
var labels = {
|
|
method,
|
|
route: finalRoute,
|
|
status_code: String(res.statusCode)
|
|
};
|
|
httpRequestsTotal.inc(labels);
|
|
endTimer({ route: finalRoute, status_code: String(res.statusCode) });
|
|
httpRequestsInProgress.dec({ method, route });
|
|
});
|
|
|
|
next();
|
|
}
|
|
|
|
async function metricsHandler(req, res) {
|
|
res.setHeader('Content-Type', register.contentType);
|
|
res.end(await register.metrics());
|
|
}
|
|
|
|
module.exports = {
|
|
metricsHandler,
|
|
metricsMiddleware,
|
|
register
|
|
};
|