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