#![deny(missing_docs)] //! Minimal API for getting time series data from prometheus, and making small plots. //! //! To use it, instantiate one of the request objects, //! e.g. QueryRequest or QueryRangeRequest. When it's helpful a builder is provided. //! //! Then use `PromRequest` trait and call `send` or `send_with_client`. //! This takes the prometheus url, and optionally a reqwest client to use. //! //! On success, the result is `PromData`. One would usually call `into_matrix()?` //! or `into_vector()?` as expected for the request that is made. //! //! In prometheus, metric labels are just a set of key-value pairs. However, //! if you are expecting certain structure, you may use any KV object that implements //! `serde::Deserialize` in the `PromData` that results from the call. //! //! When `plot` feature is active, the plot module can be used to plot the timeseries data. //! This was designed to be used to generate previews in alert messages. pub use reqwest::Client as ReqwestClient; use chrono::{DateTime, Utc}; use serde::{Serialize, de::DeserializeOwned}; use std::fmt::Debug; mod builders; pub use builders::QueryRangeRequestBuilder; mod error; pub use error::Error; mod labels; pub use labels::{ExtractLabels, Labels}; mod messages; use messages::PromResponse; pub use messages::{ AlertInfo, AlertStatus, AlertsResponse, MetricTimeseries, MetricVal, MetricValue, PromData, }; #[cfg(feature = "plot")] pub mod plot; mod traits; pub use traits::PromRequest; /// Query parameters for /api/v1/query prometheus request #[derive(Clone, Debug, Serialize)] pub struct QueryRequest { /// The PromQL query string pub query: String, /// Optional evaluation timestamp (defaults to current time) pub time: Option>, } impl PromRequest for QueryRequest { const PATH: &str = "/api/v1/query"; type Output = PromData; } /// Query parameters for /api/v1/query_range prometheus request /// Use builder to populate it #[derive(Clone, Debug, Serialize)] pub struct QueryRangeRequest { query: String, start: DateTime, end: DateTime, step: f64, } impl QueryRangeRequest { /// Get builder for query range request with given query pub fn builder(query: impl Into) -> QueryRangeRequestBuilder { QueryRangeRequestBuilder::new(query.into()) } } impl PromRequest for QueryRangeRequest { const PATH: &str = "/api/v1/query_range"; type Output = PromData; } /// Query parameters for /api/v1/series prometheus request #[derive(Clone, Debug, Serialize)] #[serde(transparent)] pub struct SeriesRequest { /// Series selector arguments pub matches: MatchList, } impl PromRequest for SeriesRequest { const PATH: &str = "/api/v1/series"; type Output = Vec; } /// Query parameters for /api/v1/labels prometheus request #[derive(Clone, Debug, Serialize)] #[serde(transparent)] pub struct LabelsRequest { /// Series selector arguments to filter which labels are returned pub matches: MatchList, } impl PromRequest for LabelsRequest { const PATH: &str = "/api/v1/labels"; type Output = Vec; } /// Query parameters for /api/v1/alerts prometheus request #[derive(Clone, Debug, Serialize)] pub struct AlertsRequest {} impl PromRequest for AlertsRequest { const PATH: &str = "/api/v1/alerts"; type Output = AlertsResponse; } /// Represents a sequence of match[]=...,match[]=... /// query parameters required by parts of prometheus api #[derive(Clone, Debug)] pub struct MatchList(Vec); impl Serialize for MatchList { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { use serde::ser::SerializeMap; let mut map = serializer.serialize_map(Some(self.0.len()))?; for v in &self.0 { map.serialize_entry("match[]", v)?; } map.end() } } impl From> for MatchList { fn from(src: Vec) -> Self { Self(src) } } impl FromIterator for MatchList { fn from_iter(iter: T) -> Self where T: IntoIterator, { Self(iter.into_iter().collect()) } }