Skip to main content

s2_api/v1/
metrics.rs

1use compact_str::CompactString;
2use serde::{Deserialize, Serialize};
3
4#[rustfmt::skip]
5#[derive(Debug, Clone, Serialize, Deserialize)]
6#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
7#[serde(rename_all = "kebab-case")]
8pub enum TimeseriesInterval {
9    Minute,
10    Hour,
11    Day,
12}
13
14impl From<TimeseriesInterval> for s2_common::metrics::TimeseriesInterval {
15    fn from(value: TimeseriesInterval) -> Self {
16        match value {
17            TimeseriesInterval::Minute => s2_common::metrics::TimeseriesInterval::Minute,
18            TimeseriesInterval::Hour => s2_common::metrics::TimeseriesInterval::Hour,
19            TimeseriesInterval::Day => s2_common::metrics::TimeseriesInterval::Day,
20        }
21    }
22}
23
24impl From<s2_common::metrics::TimeseriesInterval> for TimeseriesInterval {
25    fn from(value: s2_common::metrics::TimeseriesInterval) -> Self {
26        match value {
27            s2_common::metrics::TimeseriesInterval::Minute => Self::Minute,
28            s2_common::metrics::TimeseriesInterval::Hour => Self::Hour,
29            s2_common::metrics::TimeseriesInterval::Day => Self::Day,
30        }
31    }
32}
33
34#[rustfmt::skip]
35#[derive(Debug, Clone, Serialize, Deserialize)]
36#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema, utoipa::IntoParams))]
37#[cfg_attr(feature = "utoipa", into_params(parameter_in = Query))]
38pub struct AccountMetricSetRequest {
39    /// Metric set to return.
40    pub set: AccountMetricSet,
41    /// Start timestamp as Unix epoch seconds, if applicable for the metric set.
42    pub start: Option<u32>,
43    /// End timestamp as Unix epoch seconds, if applicable for the metric set.
44    pub end: Option<u32>,
45    /// Interval to aggregate over for timeseries metric sets.
46    pub interval: Option<TimeseriesInterval>,
47}
48
49impl From<AccountMetricSetRequest> for s2_common::metrics::AccountMetricsRequest {
50    fn from(value: AccountMetricSetRequest) -> Self {
51        Self {
52            set: match value.set {
53                AccountMetricSet::ActiveBasins => {
54                    s2_common::metrics::AccountMetricSet::ActiveBasins
55                }
56                AccountMetricSet::AccountOps => s2_common::metrics::AccountMetricSet::AccountOps,
57            },
58            start: value.start,
59            end: value.end,
60            interval: value.interval.map(Into::into),
61        }
62    }
63}
64
65#[rustfmt::skip]
66#[derive(Debug, Clone, Serialize, Deserialize)]
67#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
68#[serde(rename_all = "kebab-case")]
69pub enum AccountMetricSet {
70    /// Set of all basins that had at least one stream during the specified period.
71    ActiveBasins,
72    /// Count of append RPC operations, per interval.
73    AccountOps,
74}
75
76#[rustfmt::skip]
77#[derive(Debug, Clone, Serialize, Deserialize)]
78#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema, utoipa::IntoParams))]
79#[cfg_attr(feature = "utoipa", into_params(parameter_in = Query))]
80pub struct BasinMetricSetRequest {
81    /// Metric set to return.
82    pub set: BasinMetricSet,
83    /// Start timestamp as Unix epoch seconds, if applicable for the metric set.
84    pub start: Option<u32>,
85    /// End timestamp as Unix epoch seconds, if applicable for the metric set.
86    pub end: Option<u32>,
87    /// Interval to aggregate over for timeseries metric sets.
88    pub interval: Option<TimeseriesInterval>,
89}
90
91impl From<BasinMetricSetRequest> for s2_common::metrics::BasinMetricsRequest {
92    fn from(value: BasinMetricSetRequest) -> Self {
93        Self {
94            set: match value.set {
95                BasinMetricSet::AppendOps => s2_common::metrics::BasinMetricSet::AppendOps,
96                BasinMetricSet::AppendThroughput => {
97                    s2_common::metrics::BasinMetricSet::AppendThroughput
98                }
99                BasinMetricSet::BasinOps => s2_common::metrics::BasinMetricSet::BasinOps,
100                BasinMetricSet::ReadOps => s2_common::metrics::BasinMetricSet::ReadOps,
101                BasinMetricSet::ReadThroughput => {
102                    s2_common::metrics::BasinMetricSet::ReadThroughput
103                }
104                BasinMetricSet::Storage => s2_common::metrics::BasinMetricSet::Storage,
105            },
106            start: value.start,
107            end: value.end,
108            interval: value.interval.map(Into::into),
109        }
110    }
111}
112
113#[rustfmt::skip]
114#[derive(Debug, Clone, Serialize, Deserialize)]
115#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
116#[serde(rename_all = "kebab-case")]
117pub enum BasinMetricSet {
118    /// Amount of stored data, per hour, aggregated over all streams in a basin.
119    Storage,
120    /// Append operations, per interval.
121    AppendOps,
122    /// Read operations, per interval.
123    ReadOps,
124    /// Read bytes, per interval.
125    ReadThroughput,
126    /// Appended bytes, per interval.
127    AppendThroughput,
128    /// Count of basin RPC operations, per interval.
129    BasinOps,
130}
131
132#[rustfmt::skip]
133#[derive(Debug, Clone, Serialize, Deserialize)]
134#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema, utoipa::IntoParams))]
135#[cfg_attr(feature = "utoipa", into_params(parameter_in = Query))]
136pub struct StreamMetricSetRequest {
137    /// Metric set to return.
138    pub set: StreamMetricSet,
139    /// Start timestamp as Unix epoch seconds, if applicable for the metric set.
140    pub start: Option<u32>,
141    /// End timestamp as Unix epoch seconds, if applicable for metric set.
142    pub end: Option<u32>,
143    /// Interval to aggregate over for timeseries metric sets.
144    pub interval: Option<TimeseriesInterval>,
145}
146
147impl From<StreamMetricSetRequest> for s2_common::metrics::StreamMetricsRequest {
148    fn from(value: StreamMetricSetRequest) -> Self {
149        Self {
150            set: match value.set {
151                StreamMetricSet::Storage => s2_common::metrics::StreamMetricSet::Storage,
152            },
153            start: value.start,
154            end: value.end,
155            interval: value.interval.map(Into::into),
156        }
157    }
158}
159
160#[rustfmt::skip]
161#[derive(Debug, Clone, Serialize, Deserialize)]
162#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
163#[serde(rename_all = "kebab-case")]
164pub enum StreamMetricSet {
165    /// Amount of stored data, per minute, for a specific stream.
166    Storage,
167}
168
169#[rustfmt::skip]
170#[derive(Clone, Debug, Serialize, Deserialize)]
171#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
172#[serde(rename_all = "kebab-case")]
173pub enum MetricUnit {
174    Bytes,
175    Operations,
176}
177
178impl From<s2_common::metrics::MetricUnit> for MetricUnit {
179    fn from(value: s2_common::metrics::MetricUnit) -> Self {
180        match value {
181            s2_common::metrics::MetricUnit::Bytes => MetricUnit::Bytes,
182            s2_common::metrics::MetricUnit::Operations => MetricUnit::Operations,
183        }
184    }
185}
186
187#[rustfmt::skip]
188#[derive(Debug, Clone, Serialize, Deserialize)]
189#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
190pub struct ScalarMetric {
191    /// Metric name.
192    #[cfg_attr(feature = "utoipa", schema(value_type = String))]
193    pub name: CompactString,
194    /// Unit of the metric.
195    pub unit: MetricUnit,
196    /// Metric value.
197    pub value: f64,
198}
199
200impl From<s2_common::metrics::ScalarMetric> for ScalarMetric {
201    fn from(value: s2_common::metrics::ScalarMetric) -> Self {
202        Self {
203            name: value.name,
204            unit: value.unit.into(),
205            value: value.value,
206        }
207    }
208}
209
210#[rustfmt::skip]
211#[derive(Debug, Clone, Serialize, Deserialize)]
212#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
213pub struct AccumulationMetric {
214    /// Timeseries name.
215    #[cfg_attr(feature = "utoipa", schema(value_type = String))]
216    pub name: CompactString,
217    /// Unit of the metric.
218    pub unit: MetricUnit,
219    /// The interval at which data points are accumulated.
220    pub interval: TimeseriesInterval,
221    /// Timeseries values.
222    /// Each element is a tuple of a timestamp in Unix epoch seconds and a data point.
223    /// The data point represents the accumulated value for the time period starting at the timestamp, spanning one `interval`.
224    pub values: Vec<(u32, f64)>,
225}
226
227impl From<s2_common::metrics::AccumulationMetric> for AccumulationMetric {
228    fn from(value: s2_common::metrics::AccumulationMetric) -> Self {
229        Self {
230            name: value.name,
231            unit: value.unit.into(),
232            interval: value.interval.into(),
233            values: value.values,
234        }
235    }
236}
237
238#[rustfmt::skip]
239#[derive(Debug, Clone, Serialize, Deserialize)]
240#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
241pub struct GaugeMetric {
242    /// Timeseries name.
243    #[cfg_attr(feature = "utoipa", schema(value_type = String))]
244    pub name: CompactString,
245    /// Unit of the metric.
246    pub unit: MetricUnit,
247    /// Timeseries values.
248    /// Each element is a tuple of a timestamp in Unix epoch seconds and a data point.
249    /// The data point represents the value at the instant of the timestamp.
250    pub values: Vec<(u32, f64)>,
251}
252
253impl From<s2_common::metrics::GaugeMetric> for GaugeMetric {
254    fn from(value: s2_common::metrics::GaugeMetric) -> Self {
255        Self {
256            name: value.name,
257            unit: value.unit.into(),
258            values: value.values,
259        }
260    }
261}
262
263#[rustfmt::skip]
264#[derive(Debug, Clone, Serialize, Deserialize)]
265#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
266pub struct LabelMetric {
267    /// Label name.
268    #[cfg_attr(feature = "utoipa", schema(value_type = String))]
269    pub name: CompactString,
270    /// Label values.
271    pub values: Vec<String>,
272}
273
274impl From<s2_common::metrics::LabelMetric> for LabelMetric {
275    fn from(value: s2_common::metrics::LabelMetric) -> Self {
276        Self {
277            name: value.name,
278            values: value.values,
279        }
280    }
281}
282
283#[rustfmt::skip]
284#[derive(Debug, Clone, Serialize, Deserialize)]
285#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
286#[serde(rename_all = "kebab-case")]
287pub enum Metric {
288    /// Single named value.
289    Scalar(ScalarMetric),
290    /// Named series of `(timestamp, value)` points representing an accumulation over a specified interval.
291    Accumulation(AccumulationMetric),
292    /// Named series of `(timestamp, value)` points each representing an instantaneous value.
293    Gauge(GaugeMetric),
294    /// Set of string labels.
295    Label(LabelMetric),
296}
297
298impl From<s2_common::metrics::Metric> for Metric {
299    fn from(value: s2_common::metrics::Metric) -> Self {
300        match value {
301            s2_common::metrics::Metric::Scalar(scalar) => Metric::Scalar(scalar.into()),
302            s2_common::metrics::Metric::Accumulation(timeseries) => {
303                Metric::Accumulation(timeseries.into())
304            }
305            s2_common::metrics::Metric::Gauge(timeseries) => Metric::Gauge(timeseries.into()),
306            s2_common::metrics::Metric::Label(label) => Metric::Label(label.into()),
307        }
308    }
309}
310
311#[rustfmt::skip]
312#[derive(Debug, Clone, Serialize, Deserialize)]
313#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
314pub struct MetricSetResponse {
315    /// Metrics comprising the set.
316    pub values: Vec<Metric>,
317}
318
319impl From<s2_common::metrics::MetricsResponse> for MetricSetResponse {
320    fn from(value: s2_common::metrics::MetricsResponse) -> Self {
321        Self {
322            values: value.values.into_iter().map(Into::into).collect(),
323        }
324    }
325}