servers/metrics/
jemalloc.rs1use common_telemetry::error;
16use lazy_static::lazy_static;
17use once_cell::sync::Lazy;
18use prometheus::*;
19use snafu::ResultExt;
20use tikv_jemalloc_ctl::stats::{allocated_mib, resident_mib};
21use tikv_jemalloc_ctl::{epoch, epoch_mib, stats};
22
23use crate::error::UpdateJemallocMetricsSnafu;
24
25lazy_static! {
26 pub static ref SYS_JEMALLOC_RESIDEN: IntGauge = register_int_gauge!(
27 "sys_jemalloc_resident",
28 "Total number of bytes allocated by the application."
29 )
30 .unwrap();
31 pub static ref SYS_JEMALLOC_ALLOCATED: IntGauge = register_int_gauge!(
32 "sys_jemalloc_allocated",
33 "Total number of bytes in physically resident data pages mapped by the allocator."
34 )
35 .unwrap();
36}
37
38pub(crate) static JEMALLOC_COLLECTOR: Lazy<Option<JemallocCollector>> = Lazy::new(|| {
39 let collector = JemallocCollector::try_new()
40 .map_err(|e| {
41 error!(e; "Failed to retrieve jemalloc metrics");
42 e
43 })
44 .ok();
45 collector.inspect(|c| {
46 if let Err(e) = c.update() {
47 error!(e; "Failed to update jemalloc metrics");
48 };
49 })
50});
51
52pub(crate) struct JemallocCollector {
53 epoch: epoch_mib,
54 allocated: allocated_mib,
55 resident: resident_mib,
56}
57
58impl JemallocCollector {
59 pub(crate) fn try_new() -> crate::error::Result<Self> {
60 let e = epoch::mib().context(UpdateJemallocMetricsSnafu)?;
61 let allocated = stats::allocated::mib().context(UpdateJemallocMetricsSnafu)?;
62 let resident = stats::resident::mib().context(UpdateJemallocMetricsSnafu)?;
63 Ok(Self {
64 epoch: e,
65 allocated,
66 resident,
67 })
68 }
69
70 pub(crate) fn update(&self) -> crate::error::Result<()> {
71 let _ = self.epoch.advance().context(UpdateJemallocMetricsSnafu)?;
72 let allocated = self.allocated.read().context(UpdateJemallocMetricsSnafu)?;
73 let resident = self.resident.read().context(UpdateJemallocMetricsSnafu)?;
74 SYS_JEMALLOC_RESIDEN.set(allocated as i64);
75 SYS_JEMALLOC_ALLOCATED.set(resident as i64);
76 Ok(())
77 }
78}