Skip to main content

ic_analytics_sdk/
lib.rs

1use candid::{CandidType, Principal};
2use serde::{Deserialize, Serialize};
3
4/// The value carried by an incoming metric record.
5/// Determines how the metric is stored and aggregated.
6#[derive(Clone, Debug, CandidType, Deserialize, Serialize)]
7pub enum MetricValue {
8    /// Delta to apply: positive increments, negative decrements.
9    Counter(i64),
10    /// Absolute value to set.
11    Gauge(f64),
12    /// A single data point; the canister appends it with a timestamp.
13    TimeSeries(f64),
14    /// A text entry; the canister appends it with a timestamp.
15    Log(String),
16}
17
18/// An incoming metric record.
19#[derive(Clone, Debug, CandidType, Deserialize, Serialize)]
20pub struct Metric {
21    pub name: String,
22    pub key: String,
23    pub value: MetricValue,
24}
25
26/// The aggregated metric as stored in the canister, keyed by `key`.
27#[derive(Clone, Debug, CandidType, Deserialize, Serialize)]
28pub enum StoredMetric {
29    Counter { name: String, value: i64 },
30    Gauge { name: String, value: f64 },
31    TimeSeries { name: String, total: u64 },
32    Log { name: String, total: u64 },
33}
34
35/// A page of log entries returned by `get_log_page`.
36#[derive(Clone, Debug, CandidType, Deserialize, Serialize)]
37pub struct LogPage {
38    pub name: String,
39    pub entries: Vec<(u64, String)>,
40    pub total: u64,
41    pub offset: u64,
42}
43
44
45
46/// A page of time-series data points returned by `get_time_series_page`.
47#[derive(Clone, Debug, CandidType, Deserialize, Serialize)]
48pub struct TimeSeriesPage {
49    pub name: String,
50    pub points: Vec<(u64, f64)>,
51    pub total: u64,
52}
53
54#[derive(Clone, Debug)]
55pub struct AnalyticsClient {
56    pub backend_canister_id: Principal,
57}
58
59impl AnalyticsClient {
60    pub fn new(backend_canister_id: Principal) -> Self {
61        Self {
62            backend_canister_id,
63        }
64    }
65
66    /// Fire-and-forget metric recording
67    pub fn record_metric(&self, metric: Metric) -> Result<(), String> {
68        ic_cdk::call::Call::bounded_wait(self.backend_canister_id, "record_metric").with_args(&(metric,)).oneway().map_err(|e| e.to_string())?;
69        Ok(())
70    }
71}