datafusion_physical_expr_common/metrics/
builder.rs1use std::{borrow::Cow, sync::Arc};
21
22use crate::metrics::{
23 MetricCategory, MetricType,
24 value::{PruningMetrics, RatioMergeStrategy, RatioMetrics},
25};
26
27use super::{
28 Count, ExecutionPlanMetricsSet, Gauge, Label, LabelValue, Metric, MetricValue, Time,
29 Timestamp,
30};
31
32#[derive(Clone)]
53pub struct MetricBuilder<'a> {
54 metrics: &'a ExecutionPlanMetricsSet,
56
57 partition: Option<usize>,
59
60 labels: Vec<Label>,
62
63 metric_type: MetricType,
66
67 metric_category: Option<MetricCategory>,
70}
71
72impl<'a> MetricBuilder<'a> {
73 pub fn new(metrics: &'a ExecutionPlanMetricsSet) -> Self {
78 Self {
79 metrics,
80 partition: None,
81 labels: vec![],
82 metric_type: MetricType::Dev,
83 metric_category: None,
84 }
85 }
86
87 pub fn with_label(mut self, label: Label) -> Self {
89 self.labels.push(label);
90 self
91 }
92
93 pub fn with_type(mut self, metric_type: MetricType) -> Self {
95 self.metric_type = metric_type;
96 self
97 }
98
99 pub fn with_category(mut self, category: MetricCategory) -> Self {
104 self.metric_category = Some(category);
105 self
106 }
107
108 pub fn with_new_label(
110 self,
111 name: impl Into<Cow<'static, str>>,
112 value: impl Into<Cow<'static, str>>,
113 ) -> Self {
114 self.with_label(Label::new(
115 LabelValue::from(name.into()),
116 LabelValue::from(value.into()),
117 ))
118 }
119
120 pub fn with_partition(mut self, partition: usize) -> Self {
122 self.partition = Some(partition);
123 self
124 }
125
126 pub fn build(self, value: MetricValue) {
129 let Self {
130 labels,
131 partition,
132 metrics,
133 metric_type,
134 metric_category,
135 } = self;
136 let mut metric =
137 Metric::new_with_labels(value, partition, labels).with_type(metric_type);
138 if let Some(category) = metric_category {
139 metric = metric.with_category(category);
140 }
141 metrics.register(Arc::new(metric));
142 }
143
144 pub fn output_rows(self, partition: usize) -> Count {
146 let count = Count::new();
147 self.with_category(MetricCategory::Rows)
148 .with_partition(partition)
149 .build(MetricValue::OutputRows(count.clone()));
150 count
151 }
152
153 pub fn spill_count(self, partition: usize) -> Count {
156 let count = Count::new();
157 self.with_category(MetricCategory::Rows)
158 .with_partition(partition)
159 .build(MetricValue::SpillCount(count.clone()));
160 count
161 }
162
163 pub fn spilled_bytes(self, partition: usize) -> Count {
166 let count = Count::new();
167 self.with_category(MetricCategory::Bytes)
168 .with_partition(partition)
169 .build(MetricValue::SpilledBytes(count.clone()));
170 count
171 }
172
173 pub fn spilled_rows(self, partition: usize) -> Count {
176 let count = Count::new();
177 self.with_category(MetricCategory::Rows)
178 .with_partition(partition)
179 .build(MetricValue::SpilledRows(count.clone()));
180 count
181 }
182
183 pub fn output_bytes(self, partition: usize) -> Count {
185 let count = Count::new();
186 self.with_category(MetricCategory::Bytes)
187 .with_partition(partition)
188 .build(MetricValue::OutputBytes(count.clone()));
189 count
190 }
191
192 pub fn output_batches(self, partition: usize) -> Count {
194 let count = Count::new();
195 self.with_category(MetricCategory::Rows)
196 .with_partition(partition)
197 .build(MetricValue::OutputBatches(count.clone()));
198 count
199 }
200
201 pub fn mem_used(self, partition: usize) -> Gauge {
203 let gauge = Gauge::new();
204 self.with_category(MetricCategory::Bytes)
205 .with_partition(partition)
206 .build(MetricValue::CurrentMemoryUsage(gauge.clone()));
207 gauge
208 }
209
210 pub fn counter(
213 self,
214 counter_name: impl Into<Cow<'static, str>>,
215 partition: usize,
216 ) -> Count {
217 self.with_partition(partition).global_counter(counter_name)
218 }
219
220 pub fn gauge(
223 self,
224 gauge_name: impl Into<Cow<'static, str>>,
225 partition: usize,
226 ) -> Gauge {
227 self.with_partition(partition).global_gauge(gauge_name)
228 }
229
230 pub fn global_counter(self, counter_name: impl Into<Cow<'static, str>>) -> Count {
233 let count = Count::new();
234 self.build(MetricValue::Count {
235 name: counter_name.into(),
236 count: count.clone(),
237 });
238 count
239 }
240
241 pub fn global_gauge(self, gauge_name: impl Into<Cow<'static, str>>) -> Gauge {
244 let gauge = Gauge::new();
245 self.build(MetricValue::Gauge {
246 name: gauge_name.into(),
247 gauge: gauge.clone(),
248 });
249 gauge
250 }
251
252 pub fn peak_memory_usage(
255 self,
256 gauge_name: impl Into<Cow<'static, str>>,
257 partition: usize,
258 ) -> Gauge {
259 let gauge = Gauge::new();
260 self.with_category(MetricCategory::Bytes)
261 .with_partition(partition)
262 .build(MetricValue::PeakMemoryUsage {
263 name: gauge_name.into(),
264 gauge: gauge.clone(),
265 });
266 gauge
267 }
268
269 pub fn elapsed_compute(self, partition: usize) -> Time {
272 let time = Time::new();
273 self.with_category(MetricCategory::Timing)
274 .with_partition(partition)
275 .build(MetricValue::ElapsedCompute(time.clone()));
276 time
277 }
278
279 pub fn subset_time(
282 self,
283 subset_name: impl Into<Cow<'static, str>>,
284 partition: usize,
285 ) -> Time {
286 let time = Time::new();
287 self.with_category(MetricCategory::Timing)
288 .with_partition(partition)
289 .build(MetricValue::Time {
290 name: subset_name.into(),
291 time: time.clone(),
292 });
293 time
294 }
295
296 pub fn start_timestamp(self, partition: usize) -> Timestamp {
299 let timestamp = Timestamp::new();
300 self.with_category(MetricCategory::Timing)
301 .with_partition(partition)
302 .build(MetricValue::StartTimestamp(timestamp.clone()));
303 timestamp
304 }
305
306 pub fn end_timestamp(self, partition: usize) -> Timestamp {
309 let timestamp = Timestamp::new();
310 self.with_category(MetricCategory::Timing)
311 .with_partition(partition)
312 .build(MetricValue::EndTimestamp(timestamp.clone()));
313 timestamp
314 }
315
316 pub fn pruning_metrics(
318 self,
319 name: impl Into<Cow<'static, str>>,
320 partition: usize,
321 ) -> PruningMetrics {
322 let pruning_metrics = PruningMetrics::new();
323 self.with_category(MetricCategory::Rows)
324 .with_partition(partition)
325 .build(MetricValue::PruningMetrics {
326 name: name.into(),
327 pruning_metrics: pruning_metrics.clone(),
329 });
330 pruning_metrics
331 }
332
333 pub fn ratio_metrics(
335 self,
336 name: impl Into<Cow<'static, str>>,
337 partition: usize,
338 ) -> RatioMetrics {
339 self.ratio_metrics_with_strategy(name, partition, RatioMergeStrategy::default())
340 }
341
342 pub fn ratio_metrics_with_strategy(
344 self,
345 name: impl Into<Cow<'static, str>>,
346 partition: usize,
347 merge_strategy: RatioMergeStrategy,
348 ) -> RatioMetrics {
349 let ratio_metrics = RatioMetrics::new().with_merge_strategy(merge_strategy);
350 self.with_category(MetricCategory::Rows)
351 .with_partition(partition)
352 .build(MetricValue::Ratio {
353 name: name.into(),
354 ratio_metrics: ratio_metrics.clone(),
355 });
356 ratio_metrics
357 }
358}