import AppMetrics from "../Utils/Telemetry/AppMetrics";
/**
 * Express middleware that records HTTP server metrics (request count,
 * duration, and in-flight gauge) for every request.
 *
 * Attributes are kept low-cardinality on purpose:
 *   - http.request.method: GET / POST / ...
 *   - http.route:          Express route template (e.g. /api/users/:id)
 *                          or "unmatched" when nothing matched the request.
 *   - http.response.status_code: full status code (bounded set).
 *   - status_class: 2xx / 3xx / 4xx / 5xx — handy for fast queries.
 *
 * High-cardinality identifiers (raw URL, query string, userId, projectId,
 * requestId) intentionally stay on traces and logs.
 */
const HttpMetricsMiddleware = (req, res, next) => {
    const startNs = process.hrtime.bigint();
    const method = (req.method || "UNKNOWN").toUpperCase();
    const inFlight = AppMetrics.getHttpRequestsInFlight();
    inFlight.add(1, { "http.request.method": method });
    let recorded = false;
    const recordOnce = () => {
        if (recorded) {
            return;
        }
        recorded = true;
        const elapsedNs = process.hrtime.bigint() - startNs;
        const durationMs = Number(elapsedNs) / 1e6;
        const statusCode = res.statusCode || 0;
        const statusClass = statusCode >= 100 && statusCode < 600
            ? `${Math.floor(statusCode / 100)}xx`
            : "unknown";
        /*
         * Express populates req.route once the request has matched a route
         * handler. For 404s (no match), record the request under a stable
         * "unmatched" label rather than the raw URL to avoid cardinality blowup.
         */
        const routeWithMethod = req.route;
        const baseUrl = req
            .baseUrl
            ? req.baseUrl
            : "";
        const routeTemplate = routeWithMethod && typeof routeWithMethod.path === "string"
            ? `${baseUrl}${routeWithMethod.path}`
            : "unmatched";
        const attributes = {
            "http.request.method": method,
            "http.route": routeTemplate,
            "http.response.status_code": statusCode,
            status_class: statusClass,
        };
        AppMetrics.getHttpRequestCounter().add(1, attributes);
        AppMetrics.getHttpRequestDuration().record(durationMs, attributes);
        inFlight.add(-1, { "http.request.method": method });
    };
    res.on("finish", recordOnce);
    res.on("close", recordOnce);
    next();
};
export default HttpMetricsMiddleware;
//# sourceMappingURL=HttpMetricsMiddleware.js.map