Line data Source code
1 : use std::time::Duration;
2 :
3 : use metrics::IntGauge;
4 : use prometheus::{register_int_gauge_with_registry, Registry};
5 : use tikv_jemalloc_ctl::{config, epoch, epoch_mib, stats, version};
6 :
7 : pub struct MetricRecorder {
8 : epoch: epoch_mib,
9 : active: stats::active_mib,
10 : active_gauge: IntGauge,
11 : allocated: stats::allocated_mib,
12 : allocated_gauge: IntGauge,
13 : mapped: stats::mapped_mib,
14 : mapped_gauge: IntGauge,
15 : metadata: stats::metadata_mib,
16 : metadata_gauge: IntGauge,
17 : resident: stats::resident_mib,
18 : resident_gauge: IntGauge,
19 : retained: stats::retained_mib,
20 : retained_gauge: IntGauge,
21 : }
22 :
23 : impl MetricRecorder {
24 23 : pub fn new(registry: &Registry) -> Result<Self, anyhow::Error> {
25 23 : tracing::info!(
26 23 : config = config::malloc_conf::read()?,
27 23 : version = version::read()?,
28 23 : "starting jemalloc recorder"
29 23 : );
30 :
31 : Ok(Self {
32 23 : epoch: epoch::mib()?,
33 23 : active: stats::active::mib()?,
34 23 : active_gauge: register_int_gauge_with_registry!(
35 23 : "jemalloc_active_bytes",
36 23 : "Total number of bytes in active pages allocated by the process",
37 23 : registry
38 23 : )?,
39 23 : allocated: stats::allocated::mib()?,
40 23 : allocated_gauge: register_int_gauge_with_registry!(
41 23 : "jemalloc_allocated_bytes",
42 23 : "Total number of bytes allocated by the process",
43 23 : registry
44 23 : )?,
45 23 : mapped: stats::mapped::mib()?,
46 23 : mapped_gauge: register_int_gauge_with_registry!(
47 23 : "jemalloc_mapped_bytes",
48 23 : "Total number of bytes in active extents mapped by the allocator",
49 23 : registry
50 23 : )?,
51 23 : metadata: stats::metadata::mib()?,
52 23 : metadata_gauge: register_int_gauge_with_registry!(
53 23 : "jemalloc_metadata_bytes",
54 23 : "Total number of bytes dedicated to jemalloc metadata",
55 23 : registry
56 23 : )?,
57 23 : resident: stats::resident::mib()?,
58 23 : resident_gauge: register_int_gauge_with_registry!(
59 23 : "jemalloc_resident_bytes",
60 23 : "Total number of bytes in physically resident data pages mapped by the allocator",
61 23 : registry
62 23 : )?,
63 23 : retained: stats::retained::mib()?,
64 23 : retained_gauge: register_int_gauge_with_registry!(
65 23 : "jemalloc_retained_bytes",
66 23 : "Total number of bytes in virtual memory mappings that were retained rather than being returned to the operating system",
67 23 : registry
68 23 : )?,
69 : })
70 23 : }
71 :
72 47 : fn _poll(&self) -> Result<(), anyhow::Error> {
73 47 : self.epoch.advance()?;
74 47 : self.active_gauge.set(self.active.read()? as i64);
75 47 : self.allocated_gauge.set(self.allocated.read()? as i64);
76 47 : self.mapped_gauge.set(self.mapped.read()? as i64);
77 47 : self.metadata_gauge.set(self.metadata.read()? as i64);
78 47 : self.resident_gauge.set(self.resident.read()? as i64);
79 47 : self.retained_gauge.set(self.retained.read()? as i64);
80 47 : Ok(())
81 47 : }
82 :
83 : #[inline]
84 47 : pub fn poll(&self) {
85 47 : if let Err(error) = self._poll() {
86 0 : tracing::warn!(%error, "Failed to poll jemalloc stats");
87 47 : }
88 47 : }
89 :
90 23 : pub fn start(self) -> tokio::task::JoinHandle<()> {
91 23 : tokio::task::spawn(async move {
92 23 : let mut interval = tokio::time::interval(Duration::from_secs(15));
93 23 : interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip);
94 : loop {
95 47 : self.poll();
96 47 : interval.tick().await;
97 : }
98 23 : })
99 23 : }
100 : }
|