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