Metrics Monitoring

The HTTPServer library includes a built-in metrics monitoring system to track server performance, load, and health.

Metrics Collection

The Metrics class is a thread-safe singleton that uses atomic counters to aggregate data across all worker threads without significant performance overhead.

Key Metrics Tracked

  • Active Connections: The current number of clients connected to the server.

  • Total Requests: The cumulative number of successfully parsed HTTP requests handled since startup.

  • Response Status Groups:

    • 2xx: Successful responses.

    • 3xx: Redirections (e.g., HTTP to HTTPS).

    • 4xx: Client errors (e.g., Not Found, Bad Request).

    • 5xx: Server errors.

  • Total Bytes Transit:

    • Bytes Received: Total raw bytes read from client sockets.

    • Bytes Sent: Total raw bytes written to client sockets.

  • Request Processing Time: Cumulative time (in milliseconds) spent processing requests from the first byte received to the response being sent.

Integration Points

Metrics are automatically collected at key stages of the request lifecycle:

  1. Connection Tracking: The ConnectionGuard increments the active connection count on entry and decrements it on destruction (RAII).

  2. I/O Tracking: The Server records byte counts every time data is successfully read from or written to a socket.

  3. Request Tracking: Total request count is incremented after a handler finishes processing.

  4. Latency Tracking: The server measures the wall-clock time from the start of request receipt to the completion of the response send.

Accessing Metrics

You can access a point-in-time snapshot of the current metrics using the snapshot() method.

#include <httpserver_impl/monitoring/metrics.h>

void logServerStats() {
    auto stats = Metrics::instance().snapshot();

    std::cout << "Active Connections: " << stats.d_activeConnections << "\n";
    std::cout << "Total Requests: " << stats.d_totalRequests << "\n";
    std::cout << "Total Received: " << stats.d_totalBytesReceived << " bytes\n";

    if (stats.d_totalRequests > 0) {
        double avg_latency = static_cast<double>(stats.d_totalRequestProcessingTimeMs) / stats.d_totalRequests;
        std::cout << "Avg Latency: " << avg_latency << " ms\n";
    }
}