ruvector_metrics/
lib.rs

1use lazy_static::lazy_static;
2use prometheus::{
3    register_counter, register_counter_vec, register_gauge, register_gauge_vec,
4    register_histogram_vec, Counter, CounterVec, Encoder, Gauge, GaugeVec, HistogramVec, Opts,
5    Registry, TextEncoder,
6};
7
8pub mod health;
9pub mod recorder;
10
11pub use health::{
12    CollectionHealth, HealthChecker, HealthResponse, HealthStatus, ReadinessResponse,
13};
14pub use recorder::MetricsRecorder;
15
16lazy_static! {
17    pub static ref REGISTRY: Registry = Registry::new();
18
19    // Search metrics
20    pub static ref SEARCH_REQUESTS_TOTAL: CounterVec = register_counter_vec!(
21        Opts::new("ruvector_search_requests_total", "Total search requests"),
22        &["collection", "status"]
23    ).unwrap();
24
25    pub static ref SEARCH_LATENCY_SECONDS: HistogramVec = register_histogram_vec!(
26        "ruvector_search_latency_seconds",
27        "Search latency in seconds",
28        &["collection"],
29        vec![0.0001, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0]
30    ).unwrap();
31
32    // Insert metrics
33    pub static ref INSERT_REQUESTS_TOTAL: CounterVec = register_counter_vec!(
34        Opts::new("ruvector_insert_requests_total", "Total insert requests"),
35        &["collection", "status"]
36    ).unwrap();
37
38    pub static ref INSERT_LATENCY_SECONDS: HistogramVec = register_histogram_vec!(
39        "ruvector_insert_latency_seconds",
40        "Insert latency in seconds",
41        &["collection"],
42        vec![0.0001, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0]
43    ).unwrap();
44
45    pub static ref VECTORS_INSERTED_TOTAL: CounterVec = register_counter_vec!(
46        Opts::new("ruvector_vectors_inserted_total", "Total vectors inserted"),
47        &["collection"]
48    ).unwrap();
49
50    // Delete metrics
51    pub static ref DELETE_REQUESTS_TOTAL: CounterVec = register_counter_vec!(
52        Opts::new("ruvector_delete_requests_total", "Total delete requests"),
53        &["collection", "status"]
54    ).unwrap();
55
56    // Collection metrics
57    pub static ref VECTORS_TOTAL: GaugeVec = register_gauge_vec!(
58        Opts::new("ruvector_vectors_total", "Total vectors stored"),
59        &["collection"]
60    ).unwrap();
61
62    pub static ref COLLECTIONS_TOTAL: Gauge = register_gauge!(
63        Opts::new("ruvector_collections_total", "Total number of collections")
64    ).unwrap();
65
66    // System metrics
67    pub static ref MEMORY_USAGE_BYTES: Gauge = register_gauge!(
68        Opts::new("ruvector_memory_usage_bytes", "Memory usage in bytes")
69    ).unwrap();
70
71    pub static ref UPTIME_SECONDS: Counter = register_counter!(
72        Opts::new("ruvector_uptime_seconds", "Uptime in seconds")
73    ).unwrap();
74}
75
76/// Gather all metrics in Prometheus text format
77pub fn gather_metrics() -> String {
78    let encoder = TextEncoder::new();
79    let metric_families = prometheus::gather();
80    let mut buffer = Vec::new();
81    encoder.encode(&metric_families, &mut buffer).unwrap();
82    String::from_utf8(buffer).unwrap()
83}
84
85#[cfg(test)]
86mod tests {
87    use super::*;
88
89    #[test]
90    fn test_gather_metrics() {
91        let metrics = gather_metrics();
92        assert!(metrics.contains("ruvector"));
93    }
94
95    #[test]
96    fn test_record_search() {
97        SEARCH_REQUESTS_TOTAL
98            .with_label_values(&["test", "success"])
99            .inc();
100
101        SEARCH_LATENCY_SECONDS
102            .with_label_values(&["test"])
103            .observe(0.001);
104    }
105}