Repository: qdrant/qdrant
File: src/common/metrics.rs (Rust)

Code before:
        }

        metrics.push(metric_family(
            "optimizer_running_processes",
            "number of currently running optimization processes",
            MetricType::GAUGE,
            vec![gauge(total_optimizations_running as f64, &[])],
        ));

        metrics.push(metric_family(
            "collection_points",
            "approximate amount of points per collection",
            MetricType::GAUGE,
            points_per_collection,
        ));

        metrics.push(metric_family(
            "collection_vectors",
            "approximate amount of vectors per collection",
            MetricType::GAUGE,
            vectors_per_collection,
        ));

        metrics.push(metric_family(
            "dead_shards_total",
            "total amount of dead shards",
            MetricType::GAUGE,
            vec![gauge(total_dead_shards as f64, &[])],
        ));
    }
}

impl MetricsProvider for ClusterTelemetry {
    fn add_metrics(&self, metrics: &mut Vec<MetricFamily>) {
        let ClusterTelemetry {
            enabled,
            status,
            config: _,
            peers: _,
            peer_metadata: _,
            metadata: _,
        } = self;

        metrics.push(metric_family(
            "cluster_enabled",
            "is cluster support enabled",
            MetricType::GAUGE,
            vec![gauge(if *enabled { 1.0 } else { 0.0 }, &[])],
        ));

        if let Some(status) = status {

Review comment (suggestion):
```suggestion
            "total amount of shard replicas in non-active state",
```

Code after:
                        .count()
                })
                .minmax();

            let min_max_active_replicas = match min_max_active_replicas {
                itertools::MinMaxResult::NoElements => None,
                itertools::MinMaxResult::OneElement(one) => Some((one, one)),
                itertools::MinMaxResult::MinMax(min, max) => Some((min, max)),
            };

            if let Some((min, max)) = min_max_active_replicas {
                total_min_active_replicas = total_min_active_replicas.min(min);
                total_max_active_replicas = total_max_active_replicas.max(max);
            }

            points_per_collection.push(gauge(
                collection.count_points() as f64,
                &[("id", &collection.id)],
            ));

            vectors_per_collection.push(gauge(
                collection.count_vectors() as f64,
                &[("id", &collection.id)],
            ));

            let points_excluded_from_index_only = collection
                .shards
                .iter()
                .flatten()
                .filter_map(|shard| shard.local.as_ref())
                .filter_map(|local| local.indexed_only_excluded_vectors.as_ref())
                .flatten()
                .fold(
                    HashMap::<&str, usize>::default(),
                    |mut acc, (name, vector_size)| {
                        *acc.entry(name).or_insert(0) += vector_size;
                        acc
                    },
                );

            for (name, vector_size) in points_excluded_from_index_only {
                indexed_only_excluded.push(gauge(
                    vector_size as f64,
                    &[("id", &collection.id), ("vector", name)],
                ))
            }

            total_dead_shards += collection
                .shards
                .iter()
                .flatten()