kratactl/cli/zone/
metrics.rs

1use anyhow::Result;
2use clap::{Parser, ValueEnum};
3use krata::{
4    events::EventStream,
5    v1::{
6        common::ZoneMetricNode,
7        control::{control_service_client::ControlServiceClient, ReadZoneMetricsRequest},
8    },
9};
10
11use tonic::transport::Channel;
12
13use crate::format::{kv2line, metrics_flat, metrics_tree, proto2dynamic};
14
15use crate::cli::resolve_zone;
16
17#[derive(ValueEnum, Clone, Debug, PartialEq, Eq)]
18enum ZoneMetricsFormat {
19    Tree,
20    Json,
21    JsonPretty,
22    Yaml,
23    KeyValue,
24}
25
26#[derive(Parser)]
27#[command(about = "Read metrics from the zone")]
28pub struct ZoneMetricsCommand {
29    #[arg(short, long, default_value = "tree", help = "Output format")]
30    format: ZoneMetricsFormat,
31    #[arg(help = "Zone to read metrics for, either the name or the uuid")]
32    zone: String,
33}
34
35impl ZoneMetricsCommand {
36    pub async fn run(
37        self,
38        mut client: ControlServiceClient<Channel>,
39        _events: EventStream,
40    ) -> Result<()> {
41        let zone_id: String = resolve_zone(&mut client, &self.zone).await?;
42        let root = client
43            .read_zone_metrics(ReadZoneMetricsRequest { zone_id })
44            .await?
45            .into_inner()
46            .root
47            .unwrap_or_default();
48        match self.format {
49            ZoneMetricsFormat::Tree => {
50                self.print_metrics_tree(root)?;
51            }
52
53            ZoneMetricsFormat::Json | ZoneMetricsFormat::JsonPretty | ZoneMetricsFormat::Yaml => {
54                let value = serde_json::to_value(proto2dynamic(root)?)?;
55                let encoded = if self.format == ZoneMetricsFormat::JsonPretty {
56                    serde_json::to_string_pretty(&value)?
57                } else if self.format == ZoneMetricsFormat::Yaml {
58                    serde_yaml::to_string(&value)?
59                } else {
60                    serde_json::to_string(&value)?
61                };
62                println!("{}", encoded.trim());
63            }
64
65            ZoneMetricsFormat::KeyValue => {
66                self.print_key_value(root)?;
67            }
68        }
69
70        Ok(())
71    }
72
73    fn print_metrics_tree(&self, root: ZoneMetricNode) -> Result<()> {
74        print!("{}", metrics_tree(root));
75        Ok(())
76    }
77
78    fn print_key_value(&self, metrics: ZoneMetricNode) -> Result<()> {
79        let kvs = metrics_flat(metrics);
80        println!("{}", kv2line(kvs));
81        Ok(())
82    }
83}