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::describe_counter;
use metrics::describe_gauge;
use metrics::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").set(self.active.read()? as f64);
counter!("jemalloc_allocated_bytes").absolute(self.allocated.read()? as u64);
gauge!("jemalloc_mapped_bytes").set(self.mapped.read()? as f64);
gauge!("jemalloc_metadata_bytes").set(self.metadata.read()? as f64);
gauge!("jemalloc_resident_bytes").set(self.resident.read()? as f64);
gauge!("jemalloc_retained_bytes").set(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> {
describe_gauge!("jemalloc_active_bytes", Unit::Bytes, "Total number of bytes in active pages allocated by the process");
describe_counter!("jemalloc_allocated_bytes", Unit::Bytes, "Total number of bytes allocated by the process");
describe_gauge!("jemalloc_mapped_bytes", Unit::Bytes, "Total number of bytes in active extents mapped by the allocator");
describe_gauge!("jemalloc_metadata_bytes", Unit::Bytes, "Total number of bytes dedicated to jemalloc metadata");
describe_gauge!("jemalloc_resident_bytes", Unit::Bytes, "Total number of bytes in physically resident data pages mapped by the allocator");
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");
Ok(MetricRecorder::new()?.start())
}