diff --git a/src/datasources/grafana.rs b/src/datasources/grafana.rs index 299be63..98c0be1 100644 --- a/src/datasources/grafana.rs +++ b/src/datasources/grafana.rs @@ -1,5 +1,6 @@ use crate::metric::Metric; use crate::{metric::MetricResult, types}; +use async_trait::async_trait; use hyper::{Body, Client, Method, Request, StatusCode}; @@ -12,11 +13,18 @@ use serde_json; pub struct Grafana { url: String, api_key: String, + datasource_url: String, + query: String, } impl Grafana { - pub fn new(url: String, api_key: String) -> Grafana { - Grafana { api_key, url } + pub fn new(url: String, api_key: String, datasource_url: String, query: String) -> Grafana { + Grafana { + api_key, + url, + datasource_url, + query, + } } pub async fn test_connection(&self) -> types::Result<()> { @@ -32,19 +40,17 @@ impl Grafana { Ok(()) } - pub async fn extract_metrics( - &self, - datasource_url: &str, - query: &str, - from: u64, - to: u64, - step: u64, - ) -> types::Result { - let pm = prometheus::Prometheus::new(self, datasource_url, query); - // TODO: split big query to chunks - let r = pm.query(from, to, step).await?; - Ok(r) - } + // pub async fn extract_metrics( + // &self, + // from: u64, + // to: u64, + // step: u64, + // ) -> types::Result { + // let pm = prometheus::Prometheus::new(self, &self.datasource_url, &self.query); + // // TODO: split big query to chunks + // let r = pm.query(from, to, step).await?; + // Ok(r) + // } async fn get(&self, suburl: &str) -> types::Result<(StatusCode, serde_json::Value)> { let req = Request::builder() @@ -113,3 +119,12 @@ impl Grafana { Ok((status, result)) } } + +#[async_trait] +impl Metric for Grafana { + async fn query_chunk(&self, from: u64, to: u64, step: u64) -> types::Result { + let pm = prometheus::Prometheus::new(self, &self.datasource_url, &self.query); + let r = pm.query(from, to, step).await?; + Ok(r) + } +} diff --git a/src/datasources/prometheus.rs b/src/datasources/prometheus.rs index 904d65c..1dbc6d1 100644 --- a/src/datasources/prometheus.rs +++ b/src/datasources/prometheus.rs @@ -1,26 +1,49 @@ -use std::ptr::NonNull; - use async_trait::async_trait; +use hyper::{Body, Client, Method, Request, StatusCode}; use crate::{ metric::{Metric, MetricResult}, types, }; +use bytes::Buf as _; struct Prometheus { - + url: String, + query: String, } impl Prometheus { - pub fn new() -> Prometheus { - Prometheus{} + pub fn new(url: &String, query: &String) -> Prometheus { + Prometheus { + url: url.to_owned(), + query: query.to_owned(), + } + } + + // TODO: move to utils + async fn get(&self, suburl: &str) -> types::Result<(StatusCode, serde_json::Value)> { + let req = Request::builder() + .method(Method::GET) + .uri(self.url.to_owned() + suburl) + .header("Accept", "application/json") + .body(Body::empty()) + .unwrap(); + + let client = Client::new(); + let res = client.request(req).await?; + let status = res.status(); + + let body = hyper::body::aggregate(res).await?; + let reader = body.reader(); + let result: serde_json::Value = serde_json::from_reader(reader)?; + Ok((status, result)) } } #[async_trait] impl Metric for Prometheus { async fn query_chunk(&self, from: u64, to: u64, step: u64) -> types::Result { - return None; + return Ok(Default::default()); } -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index 884d8ee..622c18d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use subbeat::datasources::grafana; +use subbeat::{datasources::grafana, metric::Metric}; mod cli; mod types; @@ -10,15 +10,12 @@ async fn main() -> types::Result<()> { let gs = grafana::Grafana::new( cli.query_config.url.to_string(), cli.query_config.key.to_string(), + cli.query_config.datasource_url.to_string(), + cli.query_config.query.to_string(), ); - // gs.test_connection().await?; - // gs.get_datasources().await?; - // "http://localhost:3000/d/YeBxHjzWz/starter-app-stats?editPanel=2&orgId=1" let r = gs - .extract_metrics( - &cli.query_config.datasource_url, - &cli.query_config.query, + .query( cli.query_config.from, cli.query_config.to, cli.query_config.step,