mirror of
https://github.com/zaphar/Heracles.git
synced 2025-07-23 12:39:50 -04:00
feat: allow you to set the axis type
This commit is contained in:
parent
a84326cb67
commit
ae669767c8
@ -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:
|
||||
|
@ -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");
|
||||
|
@ -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)]
|
||||
|
@ -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
|
||||
|
@ -83,7 +83,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef PlotMeta
|
||||
* @typedef PlotConfig
|
||||
* @type {object}
|
||||
* @property {string=} name_format
|
||||
* @property {string=} yaxis
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user