Browse Source

parse prometheus result

main
Alexey Velikiy 3 years ago
parent
commit
c6926b6f87
  1. 38
      Cargo.lock
  2. 3
      Cargo.toml
  3. 45
      src/grafana_service/prometheus.rs
  4. 2
      src/metric.rs

38
Cargo.lock generated

@ -455,6 +455,12 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.7" version = "0.2.7"
@ -628,6 +634,17 @@ dependencies = [
"serde", "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]] [[package]]
name = "signal-hook-registry" name = "signal-hook-registry"
version = "1.4.0" version = "1.4.0"
@ -677,6 +694,7 @@ dependencies = [
"serde", "serde",
"serde_derive", "serde_derive",
"serde_json", "serde_json",
"serde_qs",
"tokio", "tokio",
] ]
@ -714,6 +732,26 @@ dependencies = [
"unicode-width", "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]] [[package]]
name = "tokio" name = "tokio"
version = "1.12.0" version = "1.12.0"

3
Cargo.toml

@ -17,8 +17,9 @@ clap = "2.33.3"
hyper = { version = "0.14.13", features = ["full"] } hyper = { version = "0.14.13", features = ["full"] }
hyper-tls = "0.5.0" hyper-tls = "0.5.0"
serde = { version = "1.0" } serde = { version = "1.0" }
serde_json = "1.0" serde_json = "1.0.68"
serde_derive = "1.0" serde_derive = "1.0"
serde_qs = "0.8.5"
async-trait = "0.1.51" async-trait = "0.1.51"

45
src/grafana_service/prometheus.rs

@ -1,4 +1,7 @@
use std::{collections::HashMap, result};
use async_trait::async_trait; use async_trait::async_trait;
use serde_json::Value;
use crate::{ use crate::{
metric::{Metric, MetricResult}, metric::{Metric, MetricResult},
@ -7,6 +10,8 @@ use crate::{
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use serde_qs as qs;
use super::GrafanaService; use super::GrafanaService;
pub struct Prometheus<'a> { pub struct Prometheus<'a> {
@ -33,6 +38,39 @@ impl<'a> Prometheus<'a> {
} }
} }
fn parse_result(value: Value) -> types::Result<MetricResult> {
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::<Vec<String>>()
.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::<f64>().unwrap(),
);
})
.collect::<Vec<(u64, f64)>>();
let mut result = MetricResult::new();
result.insert(metric_name, values.to_owned());
println!("{:?}", result);
return Ok(result);
}
#[async_trait] #[async_trait]
impl Metric for Prometheus<'_> { impl Metric for Prometheus<'_> {
async fn query(&self, from: u64, to: u64) -> types::Result<MetricResult> { async fn query(&self, from: u64, to: u64) -> types::Result<MetricResult> {
@ -44,15 +82,16 @@ impl Metric for Prometheus<'_> {
}; };
let url = "/api/datasources/proxy/1/api/v1/query_range"; let url = "/api/datasources/proxy/1/api/v1/query_range";
// TODO: use serialisatoin from serde // 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?; let (status_code, value) = self.grafana_service.post_form(&url, &rq).await?;
// TODO: return error // TODO: return error
// if status_code != StatusCode::OK { // if status_code != StatusCode::OK {
// return std::error::("Bad status code"); // return std::error::("Bad status code");
// } // }
println!("{:?}", value); // println!("{:?}", value);
return Ok(Vec::new()); return parse_result(value);
} }
} }

2
src/metric.rs

@ -26,7 +26,7 @@ struct MetricQuery {
headers: Option<HashMap<String, String>>, headers: Option<HashMap<String, String>>,
} }
pub type MetricResult = Vec<(u64, f64)>; pub type MetricResult = HashMap<String, Vec<(u64, f64)>>;
#[async_trait] #[async_trait]
pub trait Metric { pub trait Metric {

Loading…
Cancel
Save