1use candid::{CandidType, Principal};
2use serde::{Deserialize, Serialize};
3
4#[derive(Clone, Debug, CandidType, Deserialize, Serialize)]
7pub enum MetricValue {
8 Counter(i64),
10 Gauge(f64),
12 TimeSeries(f64),
14 Log(String),
16}
17
18#[derive(Clone, Debug, CandidType, Deserialize, Serialize)]
20pub struct Metric {
21 pub name: String,
22 pub key: String,
23 pub value: MetricValue,
24}
25
26#[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#[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#[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 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}