diff --git a/clickhouse-admin/types/src/lib.rs b/clickhouse-admin/types/src/lib.rs index d7ed77e06d..d7d7bee591 100644 --- a/clickhouse-admin/types/src/lib.rs +++ b/clickhouse-admin/types/src/lib.rs @@ -2114,15 +2114,15 @@ snapshot_storage_disk=LocalSnapshotDisk let expected = vec![ SystemTimeSeries { - time: crate::Timestamp::Unix("1732494720".to_string()), + time: "1732494720".to_string(), value: 110220450825.75238, }, SystemTimeSeries { - time: crate::Timestamp::Unix("1732494840".to_string()), + time: "1732494840".to_string(), value: 110339992917.33331, }, SystemTimeSeries { - time: crate::Timestamp::Unix("1732494960".to_string()), + time: "1732494960".to_string(), value: 110421854037.33331, }, ]; @@ -2142,21 +2142,15 @@ snapshot_storage_disk=LocalSnapshotDisk let expected = vec![ SystemTimeSeries { - time: crate::Timestamp::Utc( - "2024-11-25T00:34:00Z".parse::>().unwrap(), - ), + time: "2024-11-25T00:34:00Z".to_string(), value: 110220450825.75238, }, SystemTimeSeries { - time: crate::Timestamp::Utc( - "2024-11-25T00:35:00Z".parse::>().unwrap(), - ), + time: "2024-11-25T00:35:00Z".to_string(), value: 110339992917.33331, }, SystemTimeSeries { - time: crate::Timestamp::Utc( - "2024-11-25T00:36:00Z".parse::>().unwrap(), - ), + time: "2024-11-25T00:36:00Z".to_string(), value: 110421854037.33331, }, ]; @@ -2191,7 +2185,7 @@ snapshot_storage_disk=LocalSnapshotDisk assert_eq!( format!("{}", root_cause), - "data did not match any variant of untagged enum Timestamp at line 1 column 12", + "invalid type: integer `2024`, expected a string at line 1 column 12", ); } } diff --git a/dev-tools/clickana/src/clickana.rs b/dev-tools/clickana/src/clickana.rs index 50702a8238..b94e6b55e3 100644 --- a/dev-tools/clickana/src/clickana.rs +++ b/dev-tools/clickana/src/clickana.rs @@ -22,6 +22,7 @@ use ratatui::{ use slog::{o, Drain, Logger}; use slog_async::Async; use slog_term::{FullFormat, PlainDecorator}; +use std::fmt::Display; use std::net::SocketAddr; use std::time::{Duration, Instant}; use tokio::runtime::Runtime; @@ -29,6 +30,20 @@ use tokio::runtime::Runtime; const GIBIBYTE_F64: f64 = 1073741824.0; const GIBIBYTE_U64: u64 = 1073741824; +enum MetricName { + // TODO: Add other metrics to gather + DiskUsed, +} + +impl Display for MetricName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let s = match self { + MetricName::DiskUsed => "DiskUsed_default", + }; + write!(f, "{s}") + } +} + pub struct Clickana { clickhouse_addr: SocketAddr, log_path: Utf8PathBuf, @@ -58,7 +73,10 @@ impl Clickana { let tick_rate = Duration::from_secs(self.refresh_interval); let mut last_tick = Instant::now(); loop { - let top_left_frame = ChartData::new(self.get_api_data()?)?; + let top_left_frame = ChartData::new( + self.get_api_data(MetricName::DiskUsed)?, + "Disk Usage".to_string(), + )?; let dashboard = Dashboard { top_left_frame, _top_right_frame: None, @@ -91,7 +109,10 @@ impl Clickana { dashboard.top_left_frame.render_line_chart(frame, line_chart); } - fn get_api_data(&self) -> Result> { + fn get_api_data( + &self, + metric: MetricName, + ) -> Result> { let admin_url = format!("http://{}", self.clickhouse_addr); let log = self.new_logger()?; let client = ClickhouseServerClient::new(&admin_url, log.clone()); @@ -101,13 +122,13 @@ impl Clickana { let timeseries = client .system_timeseries_avg( types::SystemTable::AsynchronousMetricLog, - "DiskUsed_default", + &format!("{metric}"), Some(self.sampling_interval), Some(self.time_range), Some(TimestampFormat::UnixEpoch), ) .await - .map(|t| t.into_inner()) //; + .map(|t| t.into_inner()) .map_err(|e| { anyhow!( concat!( @@ -154,6 +175,7 @@ struct Dashboard { #[derive(Debug)] struct ChartData { + title: String, data_points: Vec<(f64, f64)>, avg_time_utc: DateTime, start_time_utc: DateTime, @@ -168,17 +190,21 @@ struct ChartData { } impl ChartData { - fn new(raw_data: Vec) -> Result { + fn new(raw_data: Vec, title: String) -> Result { // These values will be used to render the graph and ratatui // requires them to be f64 let data_points: Vec<(f64, f64)> = raw_data .iter() .map(|ts| { ( - ts.time.trim_matches('"').parse::().expect(&format!( - "could not parse timestamp {} into f64", - ts.time - )), + ts.time.trim_matches('"').parse::().unwrap_or_else( + |_| { + panic!( + "could not parse timestamp {} into f64", + ts.time + ) + }, + ), ts.value, ) }) @@ -227,10 +253,9 @@ impl ChartData { let timestamps: Vec = raw_data .iter() .map(|ts| { - ts.time.trim_matches('"').parse::().expect(&format!( - "could not parse timestamp {} into i64", - ts.time - )) + ts.time.trim_matches('"').parse::().unwrap_or_else(|_| { + panic!("could not parse timestamp {} into i64", ts.time) + }) }) .collect(); @@ -268,6 +293,7 @@ impl ChartData { let end_time_unix = *end_time as f64; Ok(Self { + title, data_points, avg_time_utc, start_time_utc, @@ -291,8 +317,9 @@ impl ChartData { let chart = Chart::new(datasets) .block( - Block::bordered() - .title(Line::from("Disk Usage").cyan().bold().centered()), + Block::bordered().title( + Line::from(self.title.clone()).cyan().bold().centered(), + ), ) .x_axis( Axis::default()