Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 451cd67455 |
4
index.js
4
index.js
|
|
@ -5,6 +5,7 @@ import helmet from "helmet";
|
|||
import morgan from "morgan";
|
||||
import client from "prom-client";
|
||||
import { pool } from "./db.js";
|
||||
import { metricsMiddleware } from "./src/middleware/metrics.js";
|
||||
|
||||
dotenv.config();
|
||||
const app = express();
|
||||
|
|
@ -19,6 +20,9 @@ app.use(helmet());
|
|||
app.use(morgan("tiny"));
|
||||
app.use(express.json());
|
||||
|
||||
// Middleware de métriques HTTP (doit être avant les routes)
|
||||
app.use(metricsMiddleware);
|
||||
|
||||
app.get("/health", (req, res) => {
|
||||
res.status(200).json({ status: "ok" });
|
||||
});
|
||||
|
|
|
|||
108
src/middleware/metrics.js
Normal file
108
src/middleware/metrics.js
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
import client from "prom-client";
|
||||
|
||||
// Compteur de requêtes HTTP totales
|
||||
const httpRequestsTotal = new client.Counter({
|
||||
name: "http_requests_total",
|
||||
help: "Total number of HTTP requests",
|
||||
labelNames: ["method", "route", "status_code"],
|
||||
});
|
||||
|
||||
// Histogramme de durée des requêtes
|
||||
const httpRequestDuration = new client.Histogram({
|
||||
name: "http_request_duration_seconds",
|
||||
help: "Duration of HTTP requests in seconds",
|
||||
labelNames: ["method", "route", "status_code"],
|
||||
buckets: [0.001, 0.005, 0.015, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 1, 2, 5],
|
||||
});
|
||||
|
||||
// Compteur de requêtes en cours
|
||||
const httpRequestsInProgress = new client.Gauge({
|
||||
name: "http_requests_in_progress",
|
||||
help: "Number of HTTP requests currently being processed",
|
||||
labelNames: ["method"],
|
||||
});
|
||||
|
||||
// Compteur d'erreurs HTTP
|
||||
const httpErrorsTotal = new client.Counter({
|
||||
name: "http_errors_total",
|
||||
help: "Total number of HTTP errors (4xx and 5xx)",
|
||||
labelNames: ["method", "route", "status_code"],
|
||||
});
|
||||
|
||||
// Taille des réponses
|
||||
const httpResponseSize = new client.Histogram({
|
||||
name: "http_response_size_bytes",
|
||||
help: "Size of HTTP responses in bytes",
|
||||
labelNames: ["method", "route"],
|
||||
buckets: [100, 500, 1000, 5000, 10000, 50000, 100000, 500000],
|
||||
});
|
||||
|
||||
// Fonction pour normaliser les routes (éviter la cardinalité élevée)
|
||||
const normalizeRoute = (req) => {
|
||||
// Si la route est définie par Express, l'utiliser
|
||||
if (req.route && req.route.path) {
|
||||
return req.baseUrl + req.route.path;
|
||||
}
|
||||
|
||||
// Sinon, normaliser le path en remplaçant les IDs par des placeholders
|
||||
let path = req.path;
|
||||
|
||||
// Remplacer les UUIDs
|
||||
path = path.replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, ":id");
|
||||
|
||||
// Remplacer les nombres (IDs numériques)
|
||||
path = path.replace(/\/\d+/g, "/:id");
|
||||
|
||||
// Remplacer les codes de ticket (format spécifique)
|
||||
path = path.replace(/\/[A-Z0-9]{6,}/g, "/:code");
|
||||
|
||||
return path;
|
||||
};
|
||||
|
||||
// Middleware de métriques
|
||||
export const metricsMiddleware = (req, res, next) => {
|
||||
// Ignorer les endpoints de métriques et health check
|
||||
if (req.path === "/metrics" || req.path === "/health") {
|
||||
return next();
|
||||
}
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
// Incrémenter les requêtes en cours
|
||||
httpRequestsInProgress.inc({ method: req.method });
|
||||
|
||||
// Capturer la fin de la réponse
|
||||
res.on("finish", () => {
|
||||
const duration = (Date.now() - startTime) / 1000; // En secondes
|
||||
const route = normalizeRoute(req);
|
||||
const statusCode = res.statusCode.toString();
|
||||
const labels = {
|
||||
method: req.method,
|
||||
route: route,
|
||||
status_code: statusCode,
|
||||
};
|
||||
|
||||
// Enregistrer les métriques
|
||||
httpRequestsTotal.inc(labels);
|
||||
httpRequestDuration.observe(labels, duration);
|
||||
httpRequestsInProgress.dec({ method: req.method });
|
||||
|
||||
// Compter les erreurs
|
||||
if (res.statusCode >= 400) {
|
||||
httpErrorsTotal.inc(labels);
|
||||
}
|
||||
|
||||
// Taille de la réponse (si disponible)
|
||||
const contentLength = res.get("Content-Length");
|
||||
if (contentLength) {
|
||||
httpResponseSize.observe(
|
||||
{ method: req.method, route: route },
|
||||
parseInt(contentLength, 10)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
next();
|
||||
};
|
||||
|
||||
export default metricsMiddleware;
|
||||
Loading…
Reference in New Issue
Block a user