allow reading arbitrary value
This commit is contained in:
parent
da931f031b
commit
bb41643e49
|
|
@ -17,14 +17,86 @@ pub struct GraphConfig {
|
|||
pub series: Vec<SeriesConfig>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Deserialize)]
|
||||
pub struct MetricSpecification {
|
||||
pub name: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum MetricInput {
|
||||
String(String),
|
||||
Struct { name: String, value: String },
|
||||
}
|
||||
|
||||
impl MetricInput {
|
||||
fn into_metric(self) -> MetricSpecification {
|
||||
match self {
|
||||
MetricInput::String(name) => MetricSpecification {
|
||||
name,
|
||||
value: "value".to_string(),
|
||||
},
|
||||
MetricInput::Struct { name, value } => MetricSpecification { name, value },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_metrics<'de, D>(deserializer: D) -> Result<Vec<MetricSpecification>, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let inputs = Vec::<MetricInput>::deserialize(deserializer)?;
|
||||
Ok(inputs.into_iter().map(|m| m.into_metric()).collect())
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Deserialize)]
|
||||
pub struct SeriesConfig {
|
||||
pub name: String,
|
||||
pub color: (u8, u8, u8),
|
||||
pub metrics: Vec<String>,
|
||||
|
||||
#[serde(deserialize_with = "deserialize_metrics")]
|
||||
pub metrics: Vec<MetricSpecification>,
|
||||
}
|
||||
|
||||
pub fn parse(path: &str) -> Config {
|
||||
let file = fs::read_to_string(path).expect("Could not open configuration file");
|
||||
toml::from_str(&file).expect("Could not parse configuration file")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_metrics() {
|
||||
let parsed: SeriesConfig = toml::from_str(
|
||||
"name = 'hello world'
|
||||
color = [0, 0, 0]
|
||||
metrics = [
|
||||
'm1',
|
||||
{ name = 'm2', value = 'modified'},
|
||||
|
||||
]",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let expected_metrics = vec![
|
||||
MetricSpecification {
|
||||
name: "m1".to_string(),
|
||||
value: "value".to_string(),
|
||||
},
|
||||
MetricSpecification {
|
||||
name: "m2".to_string(),
|
||||
value: "modified".to_string(),
|
||||
},
|
||||
];
|
||||
let expected = SeriesConfig {
|
||||
name: "hello world".to_string(),
|
||||
color: (0, 0, 0),
|
||||
metrics: expected_metrics,
|
||||
};
|
||||
|
||||
assert_eq!(parsed, expected);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,51 @@
|
|||
use protocol::{Protocol, ProtocolError};
|
||||
use regex::Regex;
|
||||
|
||||
use crate::config::MetricSpecification;
|
||||
|
||||
pub struct Observable {
|
||||
pub name: String,
|
||||
metrics: Vec<String>,
|
||||
metrics: Vec<Metric>,
|
||||
}
|
||||
|
||||
struct MetricRegex {
|
||||
pub name_regex: Regex,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
struct Metric {
|
||||
pub metric_name: String,
|
||||
pub value_name: String,
|
||||
}
|
||||
|
||||
impl Observable {
|
||||
pub fn discover(
|
||||
proto: &mut Protocol,
|
||||
name: &str,
|
||||
includes: &Vec<Regex>,
|
||||
includes: &Vec<MetricSpecification>,
|
||||
) -> Result<Observable, ProtocolError> {
|
||||
let all_values = proto.list()?;
|
||||
let regexes: Vec<MetricRegex> = includes
|
||||
.iter()
|
||||
.map(|i| MetricRegex {
|
||||
name_regex: Regex::new(&i.name).unwrap(),
|
||||
value: i.value.to_string(),
|
||||
})
|
||||
.collect();
|
||||
let filtered_values = all_values
|
||||
.into_iter()
|
||||
.filter(|v| includes.iter().any(|i| i.is_match(v)))
|
||||
.filter_map(|v| {
|
||||
for r in regexes.iter() {
|
||||
if r.name_regex.is_match(&v) {
|
||||
return Some(Metric {
|
||||
metric_name: v,
|
||||
value_name: r.value.to_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(Observable {
|
||||
|
|
@ -28,7 +58,7 @@ impl Observable {
|
|||
let results = self
|
||||
.metrics
|
||||
.iter()
|
||||
.map(|f| proto.get(f.into(), "value".to_string()))
|
||||
.map(|f| proto.get(f.metric_name.to_string(), f.value_name.to_string()))
|
||||
.collect::<Result<Vec<f32>, ProtocolError>>()?;
|
||||
|
||||
Ok(results.into_iter().sum::<f32>())
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ use core::fmt;
|
|||
|
||||
use draw::{StackedConfig, StackedSeries, StackedSeriesConfig, stacked};
|
||||
use protocol::{Protocol, ProtocolError};
|
||||
use regex::Regex;
|
||||
|
||||
use crate::{
|
||||
config::GraphConfig,
|
||||
|
|
@ -33,13 +32,7 @@ impl Graph {
|
|||
config
|
||||
.series
|
||||
.iter()
|
||||
.map(|s| {
|
||||
Observable::discover(
|
||||
proto,
|
||||
&s.name,
|
||||
&s.metrics.iter().map(|m| Regex::new(&m).unwrap()).collect(),
|
||||
)
|
||||
})
|
||||
.map(|s| Observable::discover(proto, &s.name, &s.metrics))
|
||||
.collect::<Result<Vec<Observable>, ProtocolError>>()
|
||||
.expect("Could not discover required metrics"),
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue