cat_gateway/metrics/
memory.rsuse std::{
alloc::System,
sync::atomic::{AtomicBool, Ordering},
thread,
};
use memory_stats::{memory_stats, MemoryStats};
use stats_alloc::{Region, StatsAlloc, INSTRUMENTED_SYSTEM};
use crate::settings::Settings;
#[global_allocator]
static GLOBAL: &StatsAlloc<System> = &INSTRUMENTED_SYSTEM;
static IS_INITIALIZED: AtomicBool = AtomicBool::new(false);
pub(crate) fn init_metrics_reporter() {
if IS_INITIALIZED.swap(true, Ordering::SeqCst) {
return;
}
let stats = Region::new(GLOBAL);
let api_host_names = Settings::api_host_names().join(",");
let service_id = Settings::service_id();
thread::spawn(move || {
loop {
{
let allocator_stats = stats.change();
let mem_stats = memory_stats().unwrap_or({
MemoryStats {
physical_mem: 0,
virtual_mem: 0,
}
});
reporter::MEMORY_PHYSICAL_USAGE
.with_label_values(&[&api_host_names, service_id])
.set(i64::try_from(mem_stats.physical_mem).unwrap_or(-1));
reporter::MEMORY_VIRTUAL_USAGE
.with_label_values(&[&api_host_names, service_id])
.set(i64::try_from(mem_stats.virtual_mem).unwrap_or(-1));
reporter::MEMORY_ALLOCATION_COUNT
.with_label_values(&[&api_host_names, service_id])
.set(i64::try_from(allocator_stats.allocations).unwrap_or(-1));
reporter::MEMORY_DEALLOCATION_COUNT
.with_label_values(&[&api_host_names, service_id])
.set(i64::try_from(allocator_stats.deallocations).unwrap_or(-1));
reporter::MEMORY_REALLOCATION_COUNT
.with_label_values(&[&api_host_names, service_id])
.set(i64::try_from(allocator_stats.reallocations).unwrap_or(-1));
reporter::MEMORY_BYTES_ALLOCATED
.with_label_values(&[&api_host_names, service_id])
.set(i64::try_from(allocator_stats.bytes_allocated).unwrap_or(-1));
reporter::MEMORY_BYTES_DEALLOCATED
.with_label_values(&[&api_host_names, service_id])
.set(i64::try_from(allocator_stats.bytes_deallocated).unwrap_or(-1));
reporter::MEMORY_BYTES_REALLOCATED
.with_label_values(&[&api_host_names, service_id])
.set(i64::try_from(allocator_stats.bytes_reallocated).unwrap_or(-1));
}
thread::sleep(Settings::metrics_memory_interval());
}
});
}
mod reporter {
use std::sync::LazyLock;
use prometheus::{register_int_gauge_vec, IntGaugeVec};
const MEMORY_METRIC_LABELS: [&str; 2] = ["api_host_names", "service_id"];
pub(super) static MEMORY_PHYSICAL_USAGE: LazyLock<IntGaugeVec> = LazyLock::new(|| {
register_int_gauge_vec!(
"memory_physical_usage",
"Amount of physical memory usage in bytes",
&MEMORY_METRIC_LABELS
)
.unwrap()
});
pub(super) static MEMORY_VIRTUAL_USAGE: LazyLock<IntGaugeVec> = LazyLock::new(|| {
register_int_gauge_vec!(
"memory_virtual_usage",
"Amount of physical virtual usage in bytes",
&MEMORY_METRIC_LABELS
)
.unwrap()
});
pub(super) static MEMORY_ALLOCATION_COUNT: LazyLock<IntGaugeVec> = LazyLock::new(|| {
register_int_gauge_vec!(
"memory_allocation_count",
"Number of allocation count in the heap",
&MEMORY_METRIC_LABELS
)
.unwrap()
});
pub(super) static MEMORY_DEALLOCATION_COUNT: LazyLock<IntGaugeVec> = LazyLock::new(|| {
register_int_gauge_vec!(
"memory_deallocation_count",
"Number of deallocation count in the heap",
&MEMORY_METRIC_LABELS
)
.unwrap()
});
pub(super) static MEMORY_REALLOCATION_COUNT: LazyLock<IntGaugeVec> = LazyLock::new(|| {
register_int_gauge_vec!(
"memory_reallocation_count",
"Number of reallocation count in the heap",
&MEMORY_METRIC_LABELS
)
.unwrap()
});
pub(super) static MEMORY_BYTES_ALLOCATED: LazyLock<IntGaugeVec> = LazyLock::new(|| {
register_int_gauge_vec!(
"memory_bytes_allocated",
"Amount of accumulative allocated bytes in the heap",
&MEMORY_METRIC_LABELS
)
.unwrap()
});
pub(super) static MEMORY_BYTES_DEALLOCATED: LazyLock<IntGaugeVec> = LazyLock::new(|| {
register_int_gauge_vec!(
"memory_bytes_deallocated",
"Amount of accumulative deallocated bytes in the heap",
&MEMORY_METRIC_LABELS
)
.unwrap()
});
pub(super) static MEMORY_BYTES_REALLOCATED: LazyLock<IntGaugeVec> = LazyLock::new(|| {
register_int_gauge_vec!(
"memory_bytes_reallocated",
"Amount of accumulative reallocated bytes in the heap",
&MEMORY_METRIC_LABELS
)
.unwrap()
});
}