Skip to main content

agentmail/types/
metrics.rs

1use std::collections::BTreeMap;
2
3use crate::util::QueryBuilder;
4use serde::Deserialize;
5
6/// One time-bucket of an event metric.
7#[derive(Clone, Debug, Deserialize)]
8pub struct MetricBucket {
9    /// Start of the bucket (RFC 3339).
10    pub timestamp: String,
11    /// Event count in the bucket.
12    pub count: i64,
13}
14
15/// One time-bucket of a usage metric.
16#[derive(Clone, Debug, Deserialize)]
17pub struct UsagePoint {
18    /// Start of the bucket (RFC 3339).
19    pub timestamp: String,
20    /// Usage value in the bucket.
21    pub value: i64,
22}
23
24/// One time-bucket of a rate metric (bounce/complaint percentages).
25#[derive(Clone, Debug, Deserialize)]
26pub struct RatePoint {
27    /// Start of the bucket (RFC 3339).
28    pub timestamp: String,
29    /// The rate (proportion) observed in the bucket.
30    #[serde(default)]
31    pub rate: Option<f64>,
32    /// Messages sent in the bucket the rate is computed over.
33    #[serde(default)]
34    pub sent: Option<u64>,
35}
36
37/// Event metrics keyed by event type (e.g. `message.received`).
38pub type MetricsEvents = BTreeMap<String, Vec<MetricBucket>>;
39
40/// Usage metrics keyed by usage type.
41pub type MetricsUsage = BTreeMap<String, Vec<UsagePoint>>;
42
43/// Rate metrics keyed by rate type (`bounce`, `complaint`).
44pub type MetricsRates = BTreeMap<String, Vec<RatePoint>>;
45
46/// Query parameters for the metrics endpoints (`get_metrics_events`,
47/// `get_metrics_usage`, `get_metrics_rates`). `types` filters by
48/// event/usage/rate type; leave it empty for all. `window` is only meaningful
49/// for rates (the bucket the rate is computed over, in seconds).
50#[derive(Clone, Debug, Default)]
51pub struct MetricsQuery {
52    /// Event, usage, or rate types to include; empty means all.
53    pub types: Vec<String>,
54    /// Window start (RFC 3339).
55    pub start: Option<String>,
56    /// Window end (RFC 3339).
57    pub end: Option<String>,
58    /// Bucket size in seconds (1 to 86400).
59    pub period: Option<u32>,
60    /// Rate window in seconds; rates only.
61    pub window: Option<u32>,
62    /// Maximum buckets to return.
63    pub limit: Option<u32>,
64    /// Return newest bucket first.
65    pub descending: Option<bool>,
66}
67
68impl MetricsQuery {
69    pub(crate) fn query(&self, types_key: &'static str) -> Vec<(&'static str, String)> {
70        QueryBuilder::new()
71            .many(types_key, &self.types)
72            .opt("start", self.start.as_ref())
73            .opt("end", self.end.as_ref())
74            .opt("period", self.period.as_ref())
75            .opt("window", self.window.as_ref())
76            .opt("limit", self.limit.as_ref())
77            .opt("descending", self.descending.as_ref())
78            .build()
79    }
80}