1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use std::time::Duration;
use tikv_jemalloc_ctl::epoch;
use tikv_jemalloc_ctl::epoch_mib;
use tikv_jemalloc_ctl::stats;
use metrics::counter;
use metrics::gauge;
use metrics::register_counter;
use metrics::register_gauge;
use metrics::Unit;
mod error;
pub use error::Error;
pub struct MetricRecorder {
epoch: epoch_mib,
active: stats::active_mib,
allocated: stats::allocated_mib,
mapped: stats::mapped_mib,
metadata: stats::metadata_mib,
resident: stats::resident_mib,
retained: stats::retained_mib,
}
impl MetricRecorder {
pub fn new() -> Result<Self, Error> {
Ok(Self{
epoch: epoch::mib()?,
active: stats::active::mib()?,
allocated: stats::allocated::mib()?,
mapped: stats::mapped::mib()?,
metadata: stats::metadata::mib()?,
resident: stats::resident::mib()?,
retained: stats::retained::mib()?,
})
}
fn _poll(&self) -> Result<(), Error> {
self.epoch.advance()?;
gauge!("jemalloc_active_bytes", self.active.read()? as f64);
counter!("jemalloc_allocated_bytes", self.allocated.read()? as u64);
gauge!("jemalloc_mapped_bytes", self.mapped.read()? as f64);
gauge!("jemalloc_metadata_bytes", self.metadata.read()? as f64);
gauge!("jemalloc_resident_bytes", self.resident.read()? as f64);
gauge!("jemalloc_retained_bytes", self.retained.read()? as f64);
Ok(())
}
#[inline]
pub fn poll(&self) {
if let Err(error) = self._poll() {
tracing::warn!(%error, "Failed to poll jemalloc stats");
}
}
pub fn start(self) -> tokio::task::JoinHandle<()> {
tokio::task::spawn(async move {
let mut interval = tokio::time::interval(Duration::from_secs(10));
loop {
self.poll();
interval.tick().await;
}
})
}
}
pub fn init() -> Result<tokio::task::JoinHandle<()>, Error> {
register_gauge!("jemalloc_active_bytes", Unit::Bytes, "Total number of bytes in active pages allocated by the process");
register_counter!("jemalloc_allocated_bytes", Unit::Bytes, "Total number of bytes allocated by the process");
register_gauge!("jemalloc_mapped_bytes", Unit::Bytes, "Total number of bytes in active extents mapped by the allocator");
register_gauge!("jemalloc_metadata_bytes", Unit::Bytes, "Total number of bytes dedicated to jemalloc metadata");
register_gauge!("jemalloc_resident_bytes", Unit::Bytes, "Total number of bytes in physically resident data pages mapped by the allocator");
register_gauge!("jemalloc_retained_bytes", Unit::Bytes, "Total number of bytes in virtual memory mappings that were retained rather than being returned to the operating system");
Ok(MetricRecorder::new()?.start())
}