akas 2.4.18

AKAS: API Key Authorization Server
use actix_web_prom::{PrometheusMetrics, PrometheusMetricsBuilder};
use prometheus::{opts, IntCounterVec, Opts};
use std::sync::Arc;

/// Returns the Prometheus `Opts` for the `auth_requests_total` counter.
///
/// This function centralizes the definition of options for the `auth_requests_total`
/// metric, ensuring consistency when creating and retrieving this counter
/// from the Prometheus registry.
///
/// # Metrics Details
///
/// - **Name**: `akas_requests_total`
/// - **Help**: "Total number of requests for auth with custom labels"
/// - **Namespace**: `auth`
///
/// # Returns
///
/// An `Opts` struct containing the configuration for the `akas_requests_total` metric.
///
pub fn get_metrics_counter_opts() -> Opts {
    opts!(
        "akas_requests_total",
        "Total number of requests for auth with custom labels"
    )
    .namespace("auth")
}

/// Creates and configures the Prometheus metrics middleware and the custom auth counter.
///
/// # Returns
///
/// A tuple containing:
/// - `PrometheusMetrics`: The Actix-Web middleware for exposing Prometheus metrics.
/// - `Arc<IntCounterVec>`: An atomically reference-counted pointer to the
///   `akas_requests_total` counter, ready to be shared and used for incrementing.
///
pub fn initialize_metrics(enable_metrics: bool) -> (Option<PrometheusMetrics>, Arc<IntCounterVec>) {
    let prometheus = if enable_metrics {
        Some(
            PrometheusMetricsBuilder::new("akas")
                .endpoint("/metrics")
                .exclude("/health")
                .exclude("/metrics")
                //convert all /<nonexistent-path> into UNKNOWN
                .mask_unmatched_patterns("UNKNOWN")
                .build()
                .unwrap(),
        )
    } else {
        None
    };

    let counter_opts = get_metrics_counter_opts();

    let counter = IntCounterVec::new(
        counter_opts,
        &[
            "endpoint",
            "method",
            "status",
            "x_original_host",
            "metadata",
        ],
    )
    .unwrap();

    // Clone the counter into an Arc for registration
    let counter_arc = Arc::new(counter.clone());
    if let Some(ref prom) = prometheus {
        prom.registry.register(Box::new(counter)).unwrap();
    }

    (prometheus, counter_arc)
}