feat: Dashboard level timespans

This commit is contained in:
Jeremy Wall 2024-02-13 16:15:19 -06:00
parent 7ef0af2b43
commit 710f73332d
3 changed files with 46 additions and 29 deletions

View File

@ -11,6 +11,10 @@
step_duration: 1min
name_label: instance
- title: Test Dasbboard 2
span:
start: 2024-02-10T00:00:00.00Z
duration: 2d
step_duration: 1min
graphs:
- title: Node cpu
source: http://heimdall:9001

View File

@ -14,18 +14,13 @@
use std::path::Path;
use chrono::prelude::*;
use chrono::Duration;
use serde::Deserialize;
use serde_yaml;
use tracing::{debug, error};
use crate::query::{QueryConn, QueryType};
#[derive(Deserialize)]
pub struct Dashboard {
pub title: String,
pub graphs: Vec<Graph>,
}
#[derive(Deserialize)]
pub struct GraphSpan {
pub start: DateTime<Utc>,
@ -33,6 +28,13 @@ pub struct GraphSpan {
pub step_duration: String,
}
#[derive(Deserialize)]
pub struct Dashboard {
pub title: String,
pub graphs: Vec<Graph>,
pub span: Option<GraphSpan>
}
#[derive(Deserialize)]
pub struct Graph {
pub title: String,
@ -44,9 +46,9 @@ pub struct Graph {
pub query_type: QueryType,
}
fn duration_from_string(duration: &str) -> Option<chrono::Duration> {
fn duration_from_string(duration: &str) -> Option<Duration> {
match parse_duration::parse(duration) {
Ok(d) => match chrono::Duration::from_std(d) {
Ok(d) => match Duration::from_std(d) {
Ok(d) => Some(d),
Err(e) => {
error!(err = ?e, "specified Duration is out of bounds");
@ -63,30 +65,40 @@ fn duration_from_string(duration: &str) -> Option<chrono::Duration> {
}
}
fn graph_span_to_tuple(span: &Option<GraphSpan>) -> Option<(DateTime<Utc>, Duration, Duration)> {
if span.is_none() {
return None;
}
let span = span.as_ref().unwrap();
let duration = match duration_from_string(&span.duration) {
Some(d) => d,
None => {
error!("Invalid query duration not assigning span to to graph query");
return None;
}
};
let step_duration = match duration_from_string(&span.step_duration) {
Some(d) => d,
None => {
error!("Invalid query step resolution not assigning span to to graph query");
return None;
}
};
Some((span.start.clone(), duration, step_duration))
}
impl Graph {
pub fn get_query_connection<'conn, 'graph: 'conn>(&'graph self) -> QueryConn<'conn> {
pub fn get_query_connection<'conn, 'graph: 'conn>(&'graph self, graph_span: &'graph Option<GraphSpan>) -> QueryConn<'conn> {
debug!(
query = self.query,
source = self.source,
"Getting query connection for graph"
);
let mut conn = QueryConn::new(&self.source, &self.query, self.query_type.clone());
if let Some(span) = &self.span {
let duration = match duration_from_string(&span.duration) {
Some(d) => d,
None => {
error!("Invalid query duration not assigning span to to graph query");
return conn;
}
};
let step_duration = match duration_from_string(&span.step_duration) {
Some(d) => d,
None => {
error!("Invalid query step resolution not assigning span to to graph query");
return conn;
}
};
conn = conn.with_span(span.start.clone(), duration, step_duration);
if let Some((start, duration, step_duration)) = graph_span_to_tuple(&self.span) {
conn = conn.with_span(start, duration, step_duration);
} else if let Some((start, duration, step_duration)) = graph_span_to_tuple(graph_span) {
conn = conn.with_span(start, duration, step_duration);
}
conn
}

View File

@ -34,15 +34,15 @@ pub async fn graph_query(
Path((dash_idx, graph_idx)): Path<(usize, usize)>,
) -> Json<QueryResult> {
debug!("Getting data for query");
let graph = config
let dash = config
.get(dash_idx)
.expect("No such dashboard index")
.graphs
.expect("No such dashboard index");
let graph = dash.graphs
.get(graph_idx)
.expect(&format!("No such graph in dasboard {}", dash_idx));
let data = to_samples(
graph
.get_query_connection()
.get_query_connection(&dash.span)
.get_results()
.await
.expect("Unable to get query results")
@ -54,6 +54,7 @@ pub async fn graph_query(
pub fn mk_api_routes(config: Arc<Vec<Dashboard>>) -> Router<Config> {
// Query routes
// TODO(zaphar): Allow passing the timespan in via query
Router::new().route(
"/dash/:dash_idx/graph/:graph_idx",
get(graph_query).with_state(config),