diff --git a/Cargo.lock b/Cargo.lock index dab7a14..a439afc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -455,6 +455,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + [[package]] name = "pin-project-lite" version = "0.2.7" @@ -628,6 +634,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_qs" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7715380eec75f029a4ef7de39a9200e0a63823176b759d055b613f5a87df6a6" +dependencies = [ + "percent-encoding", + "serde", + "thiserror", +] + [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -677,6 +694,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", + "serde_qs", "tokio", ] @@ -714,6 +732,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tokio" version = "1.12.0" diff --git a/Cargo.toml b/Cargo.toml index 03d5666..cd404ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,8 +17,9 @@ clap = "2.33.3" hyper = { version = "0.14.13", features = ["full"] } hyper-tls = "0.5.0" serde = { version = "1.0" } -serde_json = "1.0" +serde_json = "1.0.68" serde_derive = "1.0" +serde_qs = "0.8.5" async-trait = "0.1.51" diff --git a/src/grafana_service/prometheus.rs b/src/grafana_service/prometheus.rs index 6029e04..e52a3d2 100644 --- a/src/grafana_service/prometheus.rs +++ b/src/grafana_service/prometheus.rs @@ -1,4 +1,7 @@ +use std::{collections::HashMap, result}; + use async_trait::async_trait; +use serde_json::Value; use crate::{ metric::{Metric, MetricResult}, @@ -7,6 +10,8 @@ use crate::{ use serde_derive::{Deserialize, Serialize}; +use serde_qs as qs; + use super::GrafanaService; pub struct Prometheus<'a> { @@ -33,6 +38,39 @@ impl<'a> Prometheus<'a> { } } +fn parse_result(value: Value) -> types::Result { + let metric = &value["data"]["result"][0]["metric"]; + let metric_name = metric + .as_object() + .unwrap() + .iter() + .map(|(k, v)| format!("{}=\"{}\"", k, v.as_str().unwrap())) + .collect::>() + .join(","); + + let metric_name = format!("{{{}}}", metric_name); + + let values = &value["data"]["result"][0]["values"] + .as_array() + .unwrap() + .iter() + .map(|e| { + let r = e.as_array().unwrap(); + return ( + r[0].as_u64().unwrap(), + r[1].as_str().unwrap().to_string().parse::().unwrap(), + ); + }) + .collect::>(); + + let mut result = MetricResult::new(); + result.insert(metric_name, values.to_owned()); + + println!("{:?}", result); + + return Ok(result); +} + #[async_trait] impl Metric for Prometheus<'_> { async fn query(&self, from: u64, to: u64) -> types::Result { @@ -44,15 +82,16 @@ impl Metric for Prometheus<'_> { }; let url = "/api/datasources/proxy/1/api/v1/query_range"; // TODO: use serialisatoin from serde - let rq = "query=rate%28go_memstats_alloc_bytes_total%5B5m%5D%29&start=1634672070&end=1634672970&step=15"; + + let rq = qs::to_string(&q)?; let (status_code, value) = self.grafana_service.post_form(&url, &rq).await?; // TODO: return error // if status_code != StatusCode::OK { // return std::error::("Bad status code"); // } - println!("{:?}", value); + // println!("{:?}", value); - return Ok(Vec::new()); + return parse_result(value); } } diff --git a/src/metric.rs b/src/metric.rs index eecbdb9..e4c6816 100644 --- a/src/metric.rs +++ b/src/metric.rs @@ -26,7 +26,7 @@ struct MetricQuery { headers: Option>, } -pub type MetricResult = Vec<(u64, f64)>; +pub type MetricResult = HashMap>; #[async_trait] pub trait Metric {