summa-server 0.22.6

Fast full-text search server
Documentation
use std::collections::HashMap;
use std::{io, iter};

use opentelemetry::metrics::{Histogram, Meter, Unit};
use opentelemetry::KeyValue;
use summa_core::components::IndexHolder;

#[derive(Clone)]
pub struct IndexMeter {
    documents_count: Histogram<u64>,
    deleted_documents_count: Histogram<u64>,
    deleted_memory_usage: Histogram<u64>,
    store_memory_usage: Histogram<u64>,
    fields_memory_usage: Histogram<u64>,
}
impl IndexMeter {
    pub fn new(meter: Meter) -> IndexMeter {
        IndexMeter {
            documents_count: meter.u64_histogram("documents_count").with_description("Documents count").init(),
            deleted_documents_count: meter
                .u64_histogram("deleted_documents_count")
                .with_description("Deleted documents count")
                .init(),
            deleted_memory_usage: meter
                .u64_histogram("deleted_memory_usage")
                .with_description("Deleted documents memory usage in bytes")
                .with_unit(Unit::new("bytes"))
                .init(),
            store_memory_usage: meter
                .u64_histogram("store_memory_usage")
                .with_description("Store memory usage in bytes")
                .with_unit(Unit::new("bytes"))
                .init(),
            fields_memory_usage: meter
                .u64_histogram("fields_memory_usage")
                .with_description("Memory usage per fields in bytes")
                .with_unit(Unit::new("bytes"))
                .init(),
        }
    }

    pub(crate) fn record_metrics(&self, index_holder: &IndexHolder) -> io::Result<()> {
        let schema = index_holder.schema();
        let searcher = index_holder.index_reader().searcher();
        let segment_readers = searcher.segment_readers();
        let mut per_fields = HashMap::new();
        for segment_reader in segment_readers {
            let segment_id = segment_reader.segment_id().uuid_string();
            let segment_space_usage = segment_reader.space_usage()?;
            for (field, field_usage) in iter::empty()
                .chain(segment_space_usage.fast_fields().fields())
                .chain(segment_space_usage.fieldnorms().fields())
                .chain(segment_space_usage.positions().fields())
                .chain(segment_space_usage.postings().fields())
                .chain(segment_space_usage.termdict().fields())
            {
                let counter = per_fields.entry(schema.get_field_name(*field)).or_insert(0u64);
                *counter += field_usage.total().get_bytes();
            }
            let segment_keys = &[
                KeyValue::new("index_name", index_holder.index_name().to_string()),
                KeyValue::new("segment_id", segment_id.to_string()),
                KeyValue::new("service.name", "summa-server"),
            ];
            self.documents_count.record(segment_reader.num_docs() as u64, segment_keys);
            self.deleted_documents_count.record(segment_reader.num_deleted_docs() as u64, segment_keys);
            self.deleted_memory_usage.record(segment_space_usage.deletes().get_bytes(), segment_keys);
            self.store_memory_usage.record(segment_space_usage.store().total().get_bytes(), segment_keys);
        }
        for (field_name, memory_usage) in &per_fields {
            let field_keys = &[
                KeyValue::new("index_name", index_holder.index_name().to_string()),
                KeyValue::new("field_name", field_name.to_string()),
            ];
            self.fields_memory_usage.record(*memory_usage, field_keys);
        }
        Ok(())
    }
}