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