Line data Source code
1 : use std::marker::PhantomData;
2 :
3 : use measured::{
4 : label::NoLabels,
5 : metric::{
6 : gauge::GaugeState, group::Encoding, name::MetricNameEncoder, MetricEncoding,
7 : MetricFamilyEncoding, MetricType,
8 : },
9 : text::TextEncoder,
10 : LabelGroup, MetricGroup,
11 : };
12 : use tikv_jemalloc_ctl::{config, epoch, epoch_mib, stats, version};
13 :
14 : pub struct MetricRecorder {
15 : epoch: epoch_mib,
16 : inner: Metrics,
17 : }
18 :
19 : #[derive(MetricGroup)]
20 : struct Metrics {
21 : active_bytes: JemallocGaugeFamily<stats::active_mib>,
22 : allocated_bytes: JemallocGaugeFamily<stats::allocated_mib>,
23 : mapped_bytes: JemallocGaugeFamily<stats::mapped_mib>,
24 : metadata_bytes: JemallocGaugeFamily<stats::metadata_mib>,
25 : resident_bytes: JemallocGaugeFamily<stats::resident_mib>,
26 : retained_bytes: JemallocGaugeFamily<stats::retained_mib>,
27 : }
28 :
29 : impl<Enc: Encoding> MetricGroup<Enc> for MetricRecorder
30 : where
31 : Metrics: MetricGroup<Enc>,
32 : {
33 0 : fn collect_group_into(&self, enc: &mut Enc) -> Result<(), Enc::Err> {
34 0 : if self.epoch.advance().is_ok() {
35 0 : self.inner.collect_group_into(enc)?;
36 0 : }
37 0 : Ok(())
38 0 : }
39 : }
40 :
41 : impl MetricRecorder {
42 0 : pub fn new() -> Result<Self, anyhow::Error> {
43 0 : tracing::info!(
44 0 : config = config::malloc_conf::read()?,
45 0 : version = version::read()?,
46 0 : "starting jemalloc recorder"
47 : );
48 :
49 : Ok(Self {
50 0 : epoch: epoch::mib()?,
51 : inner: Metrics {
52 0 : active_bytes: JemallocGaugeFamily(stats::active::mib()?),
53 0 : allocated_bytes: JemallocGaugeFamily(stats::allocated::mib()?),
54 0 : mapped_bytes: JemallocGaugeFamily(stats::mapped::mib()?),
55 0 : metadata_bytes: JemallocGaugeFamily(stats::metadata::mib()?),
56 0 : resident_bytes: JemallocGaugeFamily(stats::resident::mib()?),
57 0 : retained_bytes: JemallocGaugeFamily(stats::retained::mib()?),
58 : },
59 : })
60 0 : }
61 : }
62 :
63 : struct JemallocGauge<T>(PhantomData<T>);
64 :
65 : impl<T> Default for JemallocGauge<T> {
66 0 : fn default() -> Self {
67 0 : JemallocGauge(PhantomData)
68 0 : }
69 : }
70 : impl<T> MetricType for JemallocGauge<T> {
71 : type Metadata = T;
72 : }
73 :
74 : struct JemallocGaugeFamily<T>(T);
75 : impl<M, T: Encoding> MetricFamilyEncoding<T> for JemallocGaugeFamily<M>
76 : where
77 : JemallocGauge<M>: MetricEncoding<T, Metadata = M>,
78 : {
79 0 : fn collect_family_into(&self, name: impl MetricNameEncoder, enc: &mut T) -> Result<(), T::Err> {
80 0 : JemallocGauge::write_type(&name, enc)?;
81 0 : JemallocGauge(PhantomData).collect_into(&self.0, NoLabels, name, enc)
82 0 : }
83 : }
84 :
85 : macro_rules! jemalloc_gauge {
86 : ($stat:ident, $mib:ident) => {
87 : impl<W: std::io::Write> MetricEncoding<TextEncoder<W>> for JemallocGauge<stats::$mib> {
88 0 : fn write_type(
89 0 : name: impl MetricNameEncoder,
90 0 : enc: &mut TextEncoder<W>,
91 0 : ) -> Result<(), std::io::Error> {
92 0 : GaugeState::write_type(name, enc)
93 0 : }
94 :
95 0 : fn collect_into(
96 0 : &self,
97 0 : mib: &stats::$mib,
98 0 : labels: impl LabelGroup,
99 0 : name: impl MetricNameEncoder,
100 0 : enc: &mut TextEncoder<W>,
101 0 : ) -> Result<(), std::io::Error> {
102 0 : if let Ok(v) = mib.read() {
103 0 : GaugeState::new(v as i64).collect_into(&(), labels, name, enc)?;
104 0 : }
105 0 : Ok(())
106 0 : }
107 : }
108 : };
109 : }
110 :
111 : jemalloc_gauge!(active, active_mib);
112 : jemalloc_gauge!(allocated, allocated_mib);
113 : jemalloc_gauge!(mapped, mapped_mib);
114 : jemalloc_gauge!(metadata, metadata_mib);
115 : jemalloc_gauge!(resident, resident_mib);
116 : jemalloc_gauge!(retained, retained_mib);
|