|
|
@ -2,13 +2,13 @@ use std::collections::HashMap; |
|
|
|
|
|
|
|
|
|
|
|
use async_trait::async_trait; |
|
|
|
use async_trait::async_trait; |
|
|
|
|
|
|
|
|
|
|
|
use bytes::{Buf, buf::Reader}; |
|
|
|
use bytes::{buf::Reader, Buf}; |
|
|
|
use serde_derive::{Deserialize, Serialize}; |
|
|
|
|
|
|
|
use serde_json::Value; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use crate::{metric::{Metric, MetricResult}, types::{self, InfluxConfig}, utils::{self, normalize_url}}; |
|
|
|
use crate::{ |
|
|
|
|
|
|
|
metric::{Metric, MetricResult}, |
|
|
|
use serde_qs as qs; |
|
|
|
types::{self, InfluxConfig}, |
|
|
|
|
|
|
|
utils::{self, normalize_url}, |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone)] |
|
|
|
#[derive(Clone)] |
|
|
|
pub struct Influx { |
|
|
|
pub struct Influx { |
|
|
@ -18,9 +18,14 @@ pub struct Influx { |
|
|
|
token: String, |
|
|
|
token: String, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl Influx { |
|
|
|
impl Influx { |
|
|
|
pub fn new(cfg: &InfluxConfig) -> Influx { |
|
|
|
pub fn new(cfg: &InfluxConfig) -> Influx { |
|
|
|
|
|
|
|
if !cfg.query.contains("$range") { |
|
|
|
|
|
|
|
panic!( |
|
|
|
|
|
|
|
"Bad query: missing $range variable. Example: \n from(bucket:\"main-backet\") |> $range |> filter(fn:(r) => r._measurement == \"cpu\")" |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Influx { |
|
|
|
Influx { |
|
|
|
url: cfg.url.to_owned(), |
|
|
|
url: cfg.url.to_owned(), |
|
|
|
org_id: cfg.org_id.to_owned(), |
|
|
|
org_id: cfg.org_id.to_owned(), |
|
|
@ -46,7 +51,6 @@ pub fn parse_result(reader: Reader<impl Buf>) -> types::Result<MetricResult> { |
|
|
|
#[async_trait] |
|
|
|
#[async_trait] |
|
|
|
impl Metric for Influx { |
|
|
|
impl Metric for Influx { |
|
|
|
async fn query_chunk(&self, from: u64, to: u64, step: u64) -> types::Result<MetricResult> { |
|
|
|
async fn query_chunk(&self, from: u64, to: u64, step: u64) -> types::Result<MetricResult> { |
|
|
|
|
|
|
|
|
|
|
|
let url = format!( |
|
|
|
let url = format!( |
|
|
|
"{}/api/v2/query?orgID={}", |
|
|
|
"{}/api/v2/query?orgID={}", |
|
|
|
normalize_url(self.url.to_owned()), |
|
|
|
normalize_url(self.url.to_owned()), |
|
|
@ -55,15 +59,25 @@ impl Metric for Influx { |
|
|
|
|
|
|
|
|
|
|
|
let mut headers = HashMap::new(); |
|
|
|
let mut headers = HashMap::new(); |
|
|
|
headers.insert("Accept".to_string(), "application/csv".to_owned()); |
|
|
|
headers.insert("Accept".to_string(), "application/csv".to_owned()); |
|
|
|
headers.insert("Authorization".to_string(), format!("Token {}", self.token).to_owned()); |
|
|
|
headers.insert( |
|
|
|
headers.insert("Content-type".to_string(), "application/vnd.flux".to_owned()); |
|
|
|
"Authorization".to_string(), |
|
|
|
let (_status_code, value) = utils::post_with_headers(&url, headers).await?; |
|
|
|
format!("Token {}", self.token).to_owned(), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
headers.insert( |
|
|
|
|
|
|
|
"Content-type".to_string(), |
|
|
|
|
|
|
|
"application/vnd.flux".to_owned(), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let range_str = format!("range(start:{},stop:{})", from, to); |
|
|
|
|
|
|
|
let query = self.query.replace("$range", range_str.as_str()); |
|
|
|
|
|
|
|
let body = hyper::Body::from(query); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let (_status_code, value) = utils::post_with_headers(&url, &headers, body).await?; |
|
|
|
|
|
|
|
|
|
|
|
return parse_result(value); |
|
|
|
return parse_result(value); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// curl -XPOST "localhost:8086/api/v2/query?orgID=5abe4759f7360f1c" -sS \
|
|
|
|
// curl -XPOST "localhost:8086/api/v2/query?orgID=5abe4759f7360f1c" -sS \
|
|
|
|
// -H 'Accept:application/csv' \
|
|
|
|
// -H 'Accept:application/csv' \
|
|
|
|
// -H 'Authorization: Token sCAB2MVo8TJxhUH8UDJZIeCPwf-cykBtO0jhr207qCQSZ9d43JXObCYK_uAml2BL26JBYFauz95yIeC51kxQog==' \
|
|
|
|
// -H 'Authorization: Token sCAB2MVo8TJxhUH8UDJZIeCPwf-cykBtO0jhr207qCQSZ9d43JXObCYK_uAml2BL26JBYFauz95yIeC51kxQog==' \
|
|
|
|