cat_gateway/metrics/
memory.rs

1//! Metrics related to memory analytics.
2
3use std::alloc::System;
4
5use memory_stats::{memory_stats, MemoryStats};
6use stats_alloc::{Region, StatsAlloc, INSTRUMENTED_SYSTEM};
7
8use crate::settings::Settings;
9
10/// Use the instrumented allocator for gathering allocation statistics.
11/// Note: This wraps the global allocator.
12/// All structs that use the global allocator can be tracked.
13#[global_allocator]
14static GLOBAL: &StatsAlloc<System> = &INSTRUMENTED_SYSTEM;
15
16/// Updates memory metrics to current values.
17pub(crate) fn update() {
18    let stats = Region::new(GLOBAL);
19    let api_host_names = Settings::api_host_names().join(",");
20    let service_id = Settings::service_id();
21
22    let allocator_stats = stats.change();
23    let mem_stats = memory_stats().unwrap_or({
24        MemoryStats {
25            physical_mem: 0,
26            virtual_mem: 0,
27        }
28    });
29
30    reporter::MEMORY_PHYSICAL_USAGE
31        .with_label_values(&[&api_host_names, service_id])
32        .set(i64::try_from(mem_stats.physical_mem).unwrap_or(-1));
33    reporter::MEMORY_VIRTUAL_USAGE
34        .with_label_values(&[&api_host_names, service_id])
35        .set(i64::try_from(mem_stats.virtual_mem).unwrap_or(-1));
36    reporter::MEMORY_ALLOCATION_COUNT
37        .with_label_values(&[&api_host_names, service_id])
38        .set(i64::try_from(allocator_stats.allocations).unwrap_or(-1));
39    reporter::MEMORY_DEALLOCATION_COUNT
40        .with_label_values(&[&api_host_names, service_id])
41        .set(i64::try_from(allocator_stats.deallocations).unwrap_or(-1));
42    reporter::MEMORY_REALLOCATION_COUNT
43        .with_label_values(&[&api_host_names, service_id])
44        .set(i64::try_from(allocator_stats.reallocations).unwrap_or(-1));
45    reporter::MEMORY_BYTES_ALLOCATED
46        .with_label_values(&[&api_host_names, service_id])
47        .set(i64::try_from(allocator_stats.bytes_allocated).unwrap_or(-1));
48    reporter::MEMORY_BYTES_DEALLOCATED
49        .with_label_values(&[&api_host_names, service_id])
50        .set(i64::try_from(allocator_stats.bytes_deallocated).unwrap_or(-1));
51    reporter::MEMORY_BYTES_REALLOCATED
52        .with_label_values(&[&api_host_names, service_id])
53        .set(i64::try_from(allocator_stats.bytes_reallocated).unwrap_or(-1));
54}
55
56/// All the related memory reporting metrics to the Prometheus service are inside this
57/// module.
58mod reporter {
59    use std::sync::LazyLock;
60
61    use prometheus::{register_int_gauge_vec, IntGaugeVec};
62
63    /// Labels for the memory metrics
64    const MEMORY_METRIC_LABELS: [&str; 2] = ["api_host_names", "service_id"];
65
66    /// The "physical" memory used by this process, in bytes.
67    pub(super) static MEMORY_PHYSICAL_USAGE: LazyLock<IntGaugeVec> = LazyLock::new(|| {
68        register_int_gauge_vec!(
69            "memory_physical_usage",
70            "Amount of physical memory usage in bytes",
71            &MEMORY_METRIC_LABELS
72        )
73        .unwrap()
74    });
75
76    /// The "virtual" memory used by this process, in bytes.
77    pub(super) static MEMORY_VIRTUAL_USAGE: LazyLock<IntGaugeVec> = LazyLock::new(|| {
78        register_int_gauge_vec!(
79            "memory_virtual_usage",
80            "Amount of physical virtual usage in bytes",
81            &MEMORY_METRIC_LABELS
82        )
83        .unwrap()
84    });
85
86    /// The number of allocation count in the heap.
87    pub(super) static MEMORY_ALLOCATION_COUNT: LazyLock<IntGaugeVec> = LazyLock::new(|| {
88        register_int_gauge_vec!(
89            "memory_allocation_count",
90            "Number of allocation count in the heap",
91            &MEMORY_METRIC_LABELS
92        )
93        .unwrap()
94    });
95
96    /// The number of deallocation count in the heap.
97    pub(super) static MEMORY_DEALLOCATION_COUNT: LazyLock<IntGaugeVec> = LazyLock::new(|| {
98        register_int_gauge_vec!(
99            "memory_deallocation_count",
100            "Number of deallocation count in the heap",
101            &MEMORY_METRIC_LABELS
102        )
103        .unwrap()
104    });
105
106    /// The number of reallocation count in the heap.
107    pub(super) static MEMORY_REALLOCATION_COUNT: LazyLock<IntGaugeVec> = LazyLock::new(|| {
108        register_int_gauge_vec!(
109            "memory_reallocation_count",
110            "Number of reallocation count in the heap",
111            &MEMORY_METRIC_LABELS
112        )
113        .unwrap()
114    });
115
116    /// The amount of accumulative allocated bytes in the heap.
117    pub(super) static MEMORY_BYTES_ALLOCATED: LazyLock<IntGaugeVec> = LazyLock::new(|| {
118        register_int_gauge_vec!(
119            "memory_bytes_allocated",
120            "Amount of accumulative allocated bytes in the heap",
121            &MEMORY_METRIC_LABELS
122        )
123        .unwrap()
124    });
125
126    /// The amount of accumulative deallocated bytes in the heap.
127    pub(super) static MEMORY_BYTES_DEALLOCATED: LazyLock<IntGaugeVec> = LazyLock::new(|| {
128        register_int_gauge_vec!(
129            "memory_bytes_deallocated",
130            "Amount of accumulative deallocated bytes in the heap",
131            &MEMORY_METRIC_LABELS
132        )
133        .unwrap()
134    });
135
136    /// The amount of accumulative reallocated bytes in the heap.
137    pub(super) static MEMORY_BYTES_REALLOCATED: LazyLock<IntGaugeVec> = LazyLock::new(|| {
138        register_int_gauge_vec!(
139            "memory_bytes_reallocated",
140            "Amount of accumulative reallocated bytes in the heap",
141            &MEMORY_METRIC_LABELS
142        )
143        .unwrap()
144    });
145}