canic_core/dto/metrics.rs
1use crate::{dto::prelude::*, ids::AccessMetricKind};
2
3///
4/// Metrics DTOs
5///
6/// WHY THIS MODULE EXISTS
7/// ----------------------
8/// This module defines the **public, serialized representation** of metrics
9/// exposed by the system.
10///
11/// These types are:
12/// - Read-only snapshots
13/// - Emitted at query/read time
14/// - Detached from internal storage or aggregation strategy
15///
16/// Invariants:
17/// - These structs MUST remain stable across upgrades.
18/// - They MUST NOT encode internal metric layout or backend details.
19/// - Cardinality must remain bounded by design.
20///
21/// Any change here affects:
22/// - External dashboards
23/// - Monitoring integrations
24/// - Long-term metric continuity
25///
26/// Treat changes as **breaking API changes**.
27///
28
29///
30/// AccessMetricEntry
31///
32/// Snapshot entry pairing an endpoint with an access denial kind.
33///
34/// Access metrics are emitted only on denial and represent the kind and
35/// predicate where access failed.
36///
37#[derive(CandidType, Clone, Debug, Deserialize, Serialize)]
38pub struct AccessMetricEntry {
39 /// Normalized endpoint name.
40 ///
41 /// This value originates from the access-layer metrics façade
42 /// and must not include dynamic or user-derived data.
43 pub endpoint: String,
44
45 /// Access denial kind (guard, auth, env, rule, custom).
46 pub kind: AccessMetricKind,
47
48 /// Predicate name that denied access.
49 ///
50 /// This is either a built-in predicate name (e.g. "caller_is_root")
51 /// or a custom predicate name returned by user-defined access checks.
52 pub predicate: String,
53
54 /// Total count for this (endpoint, kind, predicate) tuple.
55 pub count: u64,
56}
57
58///
59/// DelegationMetricEntry
60///
61/// Snapshot entry pairing a delegation authority with its usage count.
62///
63/// WHY THIS EXISTS:
64/// - Delegated authorization introduces multiple signing authorities.
65/// - This metric provides visibility into which authorities are active.
66/// - Cardinality is bounded by the number of configured delegation certs.
67///
68#[derive(CandidType, Clone, Debug, Deserialize, Serialize)]
69pub struct DelegationMetricEntry {
70 /// Principal of the delegation authority (cert signer).
71 pub authority: Principal,
72
73 /// Number of successfully verified tokens attributed to this authority.
74 pub count: u64,
75}
76
77///
78/// EndpointAttemptMetricEntry
79///
80/// Snapshot entry for endpoint execution lifecycle metrics.
81///
82/// Semantics:
83/// - `attempted` counts total execution attempts
84/// - `completed` counts executions that reached completion
85///
86/// This metric does NOT encode success or failure.
87///
88#[derive(CandidType, Clone, Debug, Deserialize, Serialize)]
89pub struct EndpointAttemptMetricEntry {
90 /// Normalized endpoint name.
91 pub endpoint: String,
92
93 /// Number of times the endpoint was attempted.
94 pub attempted: u64,
95
96 /// Number of times execution completed.
97 pub completed: u64,
98}
99
100///
101/// EndpointResultMetricEntry
102///
103/// Snapshot entry for endpoint execution outcomes.
104///
105/// Semantics:
106/// - `ok` counts successful executions
107/// - `err` counts failed executions
108///
109/// This metric intentionally excludes *error causes* to prevent
110/// high-cardinality labels.
111///
112#[derive(CandidType, Clone, Debug, Deserialize, Serialize)]
113pub struct EndpointResultMetricEntry {
114 /// Normalized endpoint name.
115 pub endpoint: String,
116
117 /// Number of successful executions.
118 pub ok: u64,
119
120 /// Number of failed executions.
121 pub err: u64,
122}
123
124///
125/// EndpointHealth
126///
127/// Derived, read-only view combining multiple metric streams.
128///
129/// IMPORTANT:
130/// -----------
131/// This struct is NOT stored directly.
132/// It is materialized at read time by joining:
133/// - access metrics
134/// - attempt metrics
135/// - result metrics
136///
137/// It exists purely for observability convenience.
138///
139#[derive(CandidType, Clone, Debug, Deserialize, Serialize)]
140pub struct EndpointHealth {
141 /// Normalized endpoint name.
142 pub endpoint: String,
143
144 /// Total execution attempts.
145 pub attempted: u64,
146
147 /// Total access denials.
148 pub denied: u64,
149
150 /// Total completed executions.
151 pub completed: u64,
152
153 /// Successful executions.
154 pub ok: u64,
155
156 /// Failed executions.
157 pub err: u64,
158}
159
160///
161/// HttpMetricEntry
162///
163/// Snapshot entry for HTTP ingress metrics.
164///
165/// Semantics:
166/// - `method` is the HTTP verb (GET, POST, etc.)
167/// - `label` is a low-cardinality classification
168///
169/// Labels MUST be controlled and finite.
170///
171#[derive(CandidType, Clone, Debug, Deserialize, Serialize)]
172pub struct HttpMetricEntry {
173 /// HTTP method (e.g. GET, POST).
174 pub method: String,
175
176 /// Controlled, low-cardinality label.
177 pub label: String,
178
179 /// Total count for this (method, label) pair.
180 pub count: u64,
181}
182
183///
184/// IccMetricEntry
185///
186/// Inter-canister call (ICC) metric entry.
187///
188/// Tracks outbound calls made by this canister.
189///
190#[derive(CandidType, Clone, Debug, Deserialize, Serialize)]
191pub struct IccMetricEntry {
192 /// Target canister principal.
193 pub target: Principal,
194
195 /// Method name invoked on the target.
196 pub method: String,
197
198 /// Number of calls made.
199 pub count: u64,
200}
201
202///
203/// SystemMetricEntry
204///
205/// Snapshot entry for internal system-level metrics.
206///
207/// `kind` is intentionally a string to allow extension without
208/// schema changes, but MUST remain low-cardinality.
209///
210#[derive(CandidType, Clone, Debug, Deserialize, Serialize)]
211pub struct SystemMetricEntry {
212 /// Metric kind identifier.
213 pub kind: String,
214
215 /// Count for this metric kind.
216 pub count: u64,
217}
218
219///
220/// TimerMetricEntry
221///
222/// Snapshot entry for timer-based execution metrics.
223///
224/// Used to observe scheduled or delayed execution behavior.
225///
226#[derive(CandidType, Clone, Debug, Deserialize, Serialize)]
227pub struct TimerMetricEntry {
228 /// Timer mode (e.g. one-shot, interval).
229 pub mode: String,
230
231 /// Delay in milliseconds.
232 pub delay_ms: u64,
233
234 /// Controlled label describing timer purpose.
235 pub label: String,
236
237 /// Number of times this timer fired.
238 pub count: u64,
239}