feat: allow you to set the axis type

This commit is contained in:
Jeremy Wall 2024-05-22 13:01:35 -04:00
parent a84326cb67
commit ae669767c8
6 changed files with 50 additions and 31 deletions

View File

@ -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:

View File

@ -27,7 +27,7 @@ use crate::query::{
};
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct PlotMeta {
pub struct PlotConfig {
name_format: Option<String>,
fill: Option<FillTypes>,
yaxis: Option<String>,
@ -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<String>,
@ -64,6 +80,8 @@ pub struct AxisDefinition {
side: Option<AxisSide>,
#[serde(rename = "tickformat")]
tick_format: Option<String>,
#[serde(rename = "type")]
plot_type: Option<AxisType>,
}
#[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");

View File

@ -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<String, String>, PlotMeta, Vec<DataPoint>)>),
Scalar(Vec<(HashMap<String, String>, PlotMeta, DataPoint)>),
Series(Vec<(HashMap<String, String>, PlotConfig, Vec<DataPoint>)>),
Scalar(Vec<(HashMap<String, String>, PlotConfig, DataPoint)>),
}
#[derive(Serialize, Deserialize)]

View File

@ -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<TimeSpan>,
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

View File

@ -83,7 +83,7 @@
*/
/**
* @typedef PlotMeta
* @typedef PlotConfig
* @type {object}
* @property {string=} name_format
* @property {string=} yaxis

View File

@ -252,13 +252,13 @@ export class GraphPlot extends HTMLElement {
/**
* Formats the name for the plot trace.
* @param {PlotMeta} meta
* @param {PlotConfig} config
* @param {Map<string, string>} 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<string>, meta: Array<string>, lines: Array<string>}}
* @returns {{dates: Array<string>, config: Array<string>, lines: Array<string>}}
*/
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) {