From ae669767c82965e1db334c178f211fa4c4586df6 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Wed, 22 May 2024 13:01:35 -0400 Subject: [PATCH] feat: allow you to set the axis type --- examples/example_dashboards.yaml | 9 +++++---- src/dashboard.rs | 24 +++++++++++++++++++++--- src/query/mod.rs | 6 +++--- src/query/prom.rs | 8 ++++---- static/lib.d.js | 2 +- static/lib.mjs | 32 ++++++++++++++++---------------- 6 files changed, 50 insertions(+), 31 deletions(-) diff --git a/examples/example_dashboards.yaml b/examples/example_dashboards.yaml index de5520e..a2f6d3c 100644 --- a/examples/example_dashboards.yaml +++ b/examples/example_dashboards.yaml @@ -10,10 +10,11 @@ # overlaying: "y" side: left tickformat: "~%" + # type: "log" # The type of axis. plots: # List of pluts to show on the graph - source: http://heimdall:9001 # Prometheus source uri for this plot query: 'sum by (instance)(irate(node_cpu_seconds_total{FILTERS, job="nodestats"}[5m]))' # The PromQL query for this plot - meta: # metadata for this plot + config: # configuration for this plot name_format: "`${labels.instance}`" # javascript template literal to format the trace name fill: tozeroy span: # The span for this range query @@ -40,13 +41,13 @@ # You can use the FILTERS placeholder to indicate where user selected filters should be placed. query: | sum by (instance)(irate(node_cpu_seconds_total{FILTERS mode="system",job="nodestats"}[5m])) / sum by (instance)(irate(node_cpu_seconds_total{FILTERS, job="nodestats"}[5m])) - meta: + config: name_format: "`${labels.instance} system`" yaxis: "y" - source: http://heimdall:9001 query: | sum by (instance)(irate(node_cpu_seconds_total{mode="user",job="nodestats"}[5m])) / sum by (instance)(irate(node_cpu_seconds_total{job="nodestats"}[5m])) - meta: + config: name_format: "`${labels.instance} user`" yaxis: "y2" - title: Node memory @@ -57,7 +58,7 @@ plots: - source: http://heimdall:9001 query: 'node_memory_MemFree_bytes{job="nodestats"}' - meta: + config: name_format: "`${labels.instance}`" - title: Log Test Dashboard 1 span: diff --git a/src/dashboard.rs b/src/dashboard.rs index 5439ca8..98f1701 100644 --- a/src/dashboard.rs +++ b/src/dashboard.rs @@ -27,7 +27,7 @@ use crate::query::{ }; #[derive(Serialize, Deserialize, Debug, Clone)] -pub struct PlotMeta { +pub struct PlotConfig { name_format: Option, fill: Option, yaxis: Option, @@ -57,6 +57,22 @@ pub enum AxisSide { Left, } +#[derive(Serialize, Deserialize, Debug, Clone)] +pub enum AxisType { + #[serde(rename = "-")] + Default, + #[serde(rename = "linear")] + Linear, + #[serde(rename = "log")] + Log, + #[serde(rename = "date")] + Date, + #[serde(rename = "category")] + Category, + #[serde(rename = "multicategory")] + MultiCategory, +} + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct AxisDefinition { anchor: Option, @@ -64,6 +80,8 @@ pub struct AxisDefinition { side: Option, #[serde(rename = "tickformat")] tick_format: Option, + #[serde(rename = "type")] + plot_type: Option, } #[derive(Deserialize, Debug)] @@ -86,7 +104,7 @@ pub struct Dashboard { pub struct SubPlot { pub source: String, pub query: String, - pub meta: PlotMeta, + pub config: PlotConfig, } #[derive(Deserialize, Serialize, Clone)] @@ -222,7 +240,7 @@ impl Graph { &plot.source, &plot.query, self.query_type.clone(), - plot.meta.clone(), + plot.config.clone(), ); if let Some(filters) = filters { debug!(?filters, "query connection with filters"); diff --git a/src/query/mod.rs b/src/query/mod.rs index 6a3e49c..1e399fe 100644 --- a/src/query/mod.rs +++ b/src/query/mod.rs @@ -16,7 +16,7 @@ use std::collections::HashMap; use chrono::prelude::*; use serde::{Deserialize, Serialize}; -use crate::dashboard::PlotMeta; +use crate::dashboard::PlotConfig; mod loki; mod prom; @@ -48,8 +48,8 @@ pub struct LogLine { #[derive(Serialize, Deserialize)] pub enum MetricsQueryResult { - Series(Vec<(HashMap, PlotMeta, Vec)>), - Scalar(Vec<(HashMap, PlotMeta, DataPoint)>), + Series(Vec<(HashMap, PlotConfig, Vec)>), + Scalar(Vec<(HashMap, PlotConfig, DataPoint)>), } #[derive(Serialize, Deserialize)] diff --git a/src/query/prom.rs b/src/query/prom.rs index d8d1b85..b3547df 100644 --- a/src/query/prom.rs +++ b/src/query/prom.rs @@ -20,7 +20,7 @@ use prometheus_http_query::{ }; use tracing::debug; -use crate::dashboard::PlotMeta; +use crate::dashboard::PlotConfig; use super::{DataPoint, MetricsQueryResult, QueryType, TimeSpan}; @@ -35,7 +35,7 @@ pub struct PromQueryConn<'conn> { span: Option, query_type: QueryType, filters: Option<&'conn HashMap<&'conn str, &'conn str>>, - pub meta: PlotMeta, + pub meta: PlotConfig, } impl<'conn> PromQueryConn<'conn> { @@ -43,7 +43,7 @@ impl<'conn> PromQueryConn<'conn> { source: &'a str, query: &'a str, query_type: QueryType, - meta: PlotMeta, + meta: PlotConfig, ) -> Self { Self { source, @@ -159,7 +159,7 @@ impl<'conn> PromQueryConn<'conn> { } } -pub fn prom_to_samples(data: Data, meta: PlotMeta) -> MetricsQueryResult { +pub fn prom_to_samples(data: Data, meta: PlotConfig) -> MetricsQueryResult { match data { Data::Matrix(mut range) => MetricsQueryResult::Series( range diff --git a/static/lib.d.js b/static/lib.d.js index 2a4d11d..721e6a1 100644 --- a/static/lib.d.js +++ b/static/lib.d.js @@ -83,7 +83,7 @@ */ /** - * @typedef PlotMeta + * @typedef PlotConfig * @type {object} * @property {string=} name_format * @property {string=} yaxis diff --git a/static/lib.mjs b/static/lib.mjs index af96fdf..5b4c35e 100644 --- a/static/lib.mjs +++ b/static/lib.mjs @@ -252,13 +252,13 @@ export class GraphPlot extends HTMLElement { /** * Formats the name for the plot trace. - * @param {PlotMeta} meta + * @param {PlotConfig} config * @param {Map} labels * @return string */ - formatName(meta, labels) { + formatName(config, labels) { var name = ""; - const formatter = meta.name_format + const formatter = config.name_format if (formatter) { name = eval(formatter); } else { @@ -435,8 +435,8 @@ export class GraphPlot extends HTMLElement { return null; } } - const meta = /** @type {PlotMeta} */(triple[1]); - var yaxis = meta.yaxis || "y"; + const config = /** @type {PlotConfig} */(triple[1]); + var yaxis = config.yaxis || "y"; // https://plotly.com/javascript/reference/layout/yaxis/ const series = triple[2]; const trace = /** @type GraphTrace */({ @@ -449,10 +449,10 @@ export class GraphPlot extends HTMLElement { yaxis: yaxis, //yhoverformat: yaxis.tickformat, }); - if (meta.fill) { - trace.fill = meta.fill; + if (config.fill) { + trace.fill = config.fill; } - var name = this.formatName(meta, labels); + var name = this.formatName(config, labels); if (name) { trace.name = name; } for (const point of series) { trace.x.push(new Date(point.timestamp * 1000)); @@ -472,15 +472,15 @@ export class GraphPlot extends HTMLElement { return null; } } - const meta = /** @type {PlotMeta} */(triple[1]); + const config = /** @type {PlotConfig} */(triple[1]); const series = triple[2]; const trace = /** @type GraphTrace */({ type: "bar", x: [], y: [], - yhoverformat: meta["d3_tick_format"], + yhoverformat: config["d3_tick_format"], }); - var name = this.formatName(meta, labels); + var name = this.formatName(config, labels); if (name) { trace.name = name; } trace.y.push(series.value); trace.x.push(trace.name); @@ -490,11 +490,11 @@ export class GraphPlot extends HTMLElement { /** * @param {Array} stream * - * @returns {{dates: Array, meta: Array, lines: Array}} + * @returns {{dates: Array, config: Array, lines: Array}} */ buildStreamPlot(stream) { const dateColumn = []; - const metaColumn = []; + const configColumn = []; const logColumn = []; loopStream: for (const pair of stream) { @@ -513,11 +513,11 @@ export class GraphPlot extends HTMLElement { // For streams the timestamps are in nanoseconds let timestamp = new Date(line.timestamp / 1000000); dateColumn.push(timestamp.toISOString()); - metaColumn.push(labelsName); + configColumn.push(labelsName); logColumn.push(ansiToHtml(line.line)); } } - return { dates: dateColumn, meta: metaColumn, lines: logColumn }; + return { dates: dateColumn, config: configColumn, lines: logColumn }; } /** @@ -580,7 +580,7 @@ export class GraphPlot extends HTMLElement { }); const columns = this.buildStreamPlot(logLineList.Stream); trace.cells.values.push(columns.dates); - trace.cells.values.push(columns.meta); + trace.cells.values.push(columns.config); trace.cells.values.push(columns.lines); traces.push(trace); } else if (logLineList.StreamInstant) {