prom_remote_api/
types.rs

1//! This module provides Rust-binding to [prometheus remote storage protocol buffer definitions][proto].
2//!
3//! Go to [docs.rs][docs] to see those binding types.
4//!
5//! [proto]: https://github.com/prometheus/prometheus/blob/main/prompb/remote.proto
6//! [docs]: https://docs.rs/prom-remote-api/latest/prom_remote_api/types/index.html
7
8use async_trait::async_trait;
9use std::{fmt::Display, result::Result as StdResult, sync::Arc};
10
11mod prometheus {
12    include!(concat!(env!("OUT_DIR"), "/prometheus.rs"));
13}
14pub use prometheus::*;
15
16#[derive(Debug)]
17pub enum Error {
18    SnappyEncode(snap::Error),
19    SnappyDecode(snap::Error),
20    ProtoDecode(prost::DecodeError),
21}
22
23pub type Result<T> = StdResult<T, Error>;
24
25impl Display for Error {
26    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27        match self {
28            Self::SnappyEncode(_) => f.write_str("SnappyEncode"),
29            Self::SnappyDecode(_) => f.write_str("SnappyDecode"),
30            Self::ProtoDecode(_) => f.write_str("ProtoDecode"),
31        }
32    }
33}
34
35impl std::error::Error for Error {
36    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
37        match self {
38            Self::SnappyEncode(e) => Some(e),
39            Self::SnappyDecode(e) => Some(e),
40            Self::ProtoDecode(e) => Some(e),
41        }
42    }
43}
44
45/// Remote storage is Prometheus's solution for long-term storage.
46///
47/// Third-party storage can be integrated with Prometheus by implement this trait.
48/// <https://prometheus.io/docs/prometheus/latest/storage/#remote-storage-integrations>
49#[async_trait]
50pub trait RemoteStorage: Sync {
51    /// The type of failures yielded when write and read.
52    type Err: Send;
53
54    /// The type of request-scoped values provided for write and read.
55    type Context: Send + Sync;
56
57    /// Write samples to remote storage.
58    async fn write(&self, ctx: Self::Context, req: WriteRequest) -> StdResult<(), Self::Err>;
59
60    /// Process one query within [ReadRequest](crate::types::ReadRequest).
61    ///
62    /// Note: Prometheus remote protocol sends multiple queries by default,
63    /// use [read](crate::types::RemoteStorage::read) to serve ReadRequest.
64    async fn process_query(
65        &self,
66        ctx: &Self::Context,
67        q: Query,
68    ) -> StdResult<QueryResult, Self::Err>;
69
70    /// Read samples from remote storage.
71    ///
72    /// [ReadRequest](crate::types::ReadRequest) may contain more than one sub [queries](crate::types::Query).
73    async fn read(
74        &self,
75        ctx: Self::Context,
76        req: ReadRequest,
77    ) -> StdResult<ReadResponse, Self::Err> {
78        let results = futures::future::join_all(
79            req.queries
80                .into_iter()
81                .map(|q| async { self.process_query(&ctx, q).await }),
82        )
83        .await
84        .into_iter()
85        .collect::<StdResult<Vec<_>, Self::Err>>()?;
86
87        Ok(ReadResponse { results })
88    }
89}
90
91pub type RemoteStorageRef<C, E> = Arc<dyn RemoteStorage<Err = E, Context = C> + Send + Sync>;