Skip to main content

canic_core/domain/
metrics.rs

1//! Module: domain::metrics
2//!
3//! Responsibility: define pure metric-family selector values shared by runtime
4//! metric projection, workflow queries, and endpoint DTOs.
5//! Does not own: metric row DTO structs, metric recording, or CLI metrics
6//! transport models.
7//! Boundary: DTOs re-export these values to preserve the public API path while
8//! internal code imports them from the domain owner.
9
10use candid::CandidType;
11use serde::Deserialize;
12
13///
14/// MetricsKind
15///
16/// Metric tier selector.
17///
18
19#[derive(CandidType, Clone, Copy, Debug, Deserialize)]
20#[remain::sorted]
21pub enum MetricsKind {
22    Core,
23    Placement,
24    Platform,
25    Runtime,
26    Security,
27    Storage,
28}
29
30///
31/// CanisterOpsMetricOperation
32///
33/// Canister operation metric dimension used by public metrics projection.
34///
35
36#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
37#[remain::sorted]
38pub enum CanisterOpsMetricOperation {
39    Create,
40    Delete,
41    Install,
42    Reinstall,
43    Upgrade,
44}
45
46impl CanisterOpsMetricOperation {
47    /// Return the stable public metrics label for this operation.
48    #[must_use]
49    pub const fn metric_label(self) -> &'static str {
50        match self {
51            Self::Create => "create",
52            Self::Delete => "delete",
53            Self::Install => "install",
54            Self::Reinstall => "reinstall",
55            Self::Upgrade => "upgrade",
56        }
57    }
58}
59
60///
61/// CanisterOpsMetricOutcome
62///
63/// Canister operation outcome dimension used by public metrics projection.
64///
65
66#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
67#[remain::sorted]
68pub enum CanisterOpsMetricOutcome {
69    Completed,
70    Failed,
71    Skipped,
72    Started,
73}
74
75impl CanisterOpsMetricOutcome {
76    /// Return the stable public metrics label for this outcome.
77    #[must_use]
78    pub const fn metric_label(self) -> &'static str {
79        match self {
80            Self::Completed => "completed",
81            Self::Failed => "failed",
82            Self::Skipped => "skipped",
83            Self::Started => "started",
84        }
85    }
86}
87
88///
89/// CanisterOpsMetricReason
90///
91/// Bounded canister operation reason dimension used by public metrics projection.
92///
93
94#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
95#[remain::sorted]
96pub enum CanisterOpsMetricReason {
97    AlreadyExists,
98    Cycles,
99    InvalidState,
100    ManagementCall,
101    MissingWasm,
102    NewAllocation,
103    NotFound,
104    Ok,
105    PolicyDenied,
106    PoolReuse,
107    PoolTopup,
108    StatePropagation,
109    Topology,
110    TopologyPropagation,
111    Unknown,
112}
113
114impl CanisterOpsMetricReason {
115    /// Return the stable public metrics label for this reason.
116    #[must_use]
117    pub const fn metric_label(self) -> &'static str {
118        match self {
119            Self::AlreadyExists => "already_exists",
120            Self::NewAllocation => "new_allocation",
121            Self::Cycles => "cycles",
122            Self::InvalidState => "invalid_state",
123            Self::ManagementCall => "management_call",
124            Self::MissingWasm => "missing_wasm",
125            Self::NotFound => "not_found",
126            Self::Ok => "ok",
127            Self::PolicyDenied => "policy_denied",
128            Self::PoolReuse => "pool_reuse",
129            Self::PoolTopup => "pool_topup",
130            Self::StatePropagation => "state_propagation",
131            Self::Topology => "topology",
132            Self::TopologyPropagation => "topology_propagation",
133            Self::Unknown => "unknown",
134        }
135    }
136}
137
138///
139/// LifecycleMetricPhase
140///
141/// Lifecycle phase dimension used by public metrics projection.
142///
143
144#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
145#[remain::sorted]
146pub enum LifecycleMetricPhase {
147    Init,
148    PostUpgrade,
149}
150
151impl LifecycleMetricPhase {
152    /// Return the stable public metrics label for this phase.
153    #[must_use]
154    pub const fn metric_label(self) -> &'static str {
155        match self {
156            Self::Init => "init",
157            Self::PostUpgrade => "post_upgrade",
158        }
159    }
160}
161
162///
163/// LifecycleMetricRole
164///
165/// Lifecycle canister role dimension used by public metrics projection.
166///
167
168#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
169#[remain::sorted]
170pub enum LifecycleMetricRole {
171    Nonroot,
172    Root,
173}
174
175impl LifecycleMetricRole {
176    /// Return the stable public metrics label for this role.
177    #[must_use]
178    pub const fn metric_label(self) -> &'static str {
179        match self {
180            Self::Nonroot => "nonroot",
181            Self::Root => "root",
182        }
183    }
184}
185
186///
187/// LifecycleMetricStage
188///
189/// Lifecycle stage dimension used by public metrics projection.
190///
191
192#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
193#[remain::sorted]
194pub enum LifecycleMetricStage {
195    Bootstrap,
196    Runtime,
197}
198
199impl LifecycleMetricStage {
200    /// Return the stable public metrics label for this stage.
201    #[must_use]
202    pub const fn metric_label(self) -> &'static str {
203        match self {
204            Self::Bootstrap => "bootstrap",
205            Self::Runtime => "runtime",
206        }
207    }
208}
209
210///
211/// LifecycleMetricOutcome
212///
213/// Lifecycle outcome dimension used by public metrics projection.
214///
215
216#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
217#[remain::sorted]
218pub enum LifecycleMetricOutcome {
219    Completed,
220    Failed,
221    Scheduled,
222    Skipped,
223    Started,
224    Waiting,
225}
226
227impl LifecycleMetricOutcome {
228    /// Return the stable public metrics label for this outcome.
229    #[must_use]
230    pub const fn metric_label(self) -> &'static str {
231        match self {
232            Self::Completed => "completed",
233            Self::Failed => "failed",
234            Self::Scheduled => "scheduled",
235            Self::Skipped => "skipped",
236            Self::Started => "started",
237            Self::Waiting => "waiting",
238        }
239    }
240}
241
242///
243/// WasmStoreMetricOperation
244///
245/// Wasm-store operation dimension used by public metrics projection.
246///
247
248#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
249#[remain::sorted]
250pub enum WasmStoreMetricOperation {
251    BootstrapChunkSync,
252    ChunkPublish,
253    ChunkUpload,
254    ManifestPromote,
255    Prepare,
256    ReleasePublish,
257    SourceResolve,
258}
259
260impl WasmStoreMetricOperation {
261    /// Return the stable public metrics label for this operation.
262    #[must_use]
263    pub const fn metric_label(self) -> &'static str {
264        match self {
265            Self::BootstrapChunkSync => "bootstrap_chunk_sync",
266            Self::ChunkPublish => "chunk_publish",
267            Self::ChunkUpload => "chunk_upload",
268            Self::ManifestPromote => "manifest_promote",
269            Self::Prepare => "prepare",
270            Self::ReleasePublish => "release_publish",
271            Self::SourceResolve => "source_resolve",
272        }
273    }
274}
275
276///
277/// WasmStoreMetricSource
278///
279/// Wasm-store source dimension used by public metrics projection.
280///
281
282#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
283#[remain::sorted]
284pub enum WasmStoreMetricSource {
285    Bootstrap,
286    Embedded,
287    ManagedFleet,
288    Resolver,
289    Store,
290    TargetStore,
291}
292
293impl WasmStoreMetricSource {
294    /// Return the stable public metrics label for this source.
295    #[must_use]
296    pub const fn metric_label(self) -> &'static str {
297        match self {
298            Self::Bootstrap => "bootstrap",
299            Self::Embedded => "embedded",
300            Self::ManagedFleet => "managed_fleet",
301            Self::Resolver => "resolver",
302            Self::Store => "store",
303            Self::TargetStore => "target_store",
304        }
305    }
306}
307
308///
309/// WasmStoreMetricOutcome
310///
311/// Wasm-store outcome dimension used by public metrics projection.
312///
313
314#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
315#[remain::sorted]
316pub enum WasmStoreMetricOutcome {
317    Completed,
318    Failed,
319    Skipped,
320    Started,
321}
322
323impl WasmStoreMetricOutcome {
324    /// Return the stable public metrics label for this outcome.
325    #[must_use]
326    pub const fn metric_label(self) -> &'static str {
327        match self {
328            Self::Completed => "completed",
329            Self::Failed => "failed",
330            Self::Skipped => "skipped",
331            Self::Started => "started",
332        }
333    }
334}
335
336///
337/// WasmStoreMetricReason
338///
339/// Bounded wasm-store reason dimension used by public metrics projection.
340///
341
342#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
343#[remain::sorted]
344pub enum WasmStoreMetricReason {
345    CacheHit,
346    CacheMiss,
347    Capacity,
348    HashMismatch,
349    InvalidState,
350    ManagementCall,
351    MissingChunk,
352    MissingManifest,
353    Ok,
354    StoreCall,
355    UnsupportedInline,
356}
357
358impl WasmStoreMetricReason {
359    /// Return the stable public metrics label for this reason.
360    #[must_use]
361    pub const fn metric_label(self) -> &'static str {
362        match self {
363            Self::CacheHit => "cache_hit",
364            Self::CacheMiss => "cache_miss",
365            Self::Capacity => "capacity",
366            Self::HashMismatch => "hash_mismatch",
367            Self::InvalidState => "invalid_state",
368            Self::ManagementCall => "management_call",
369            Self::MissingChunk => "missing_chunk",
370            Self::MissingManifest => "missing_manifest",
371            Self::Ok => "ok",
372            Self::StoreCall => "store_call",
373            Self::UnsupportedInline => "unsupported_inline",
374        }
375    }
376}
377
378///
379/// ManagementCallMetricOperation
380///
381/// Management canister operation dimension used by runtime metrics recording.
382///
383
384#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
385#[remain::sorted]
386pub enum ManagementCallMetricOperation {
387    CanisterStatus,
388    ClearChunkStore,
389    CreateCanister,
390    DeleteCanister,
391    DepositCycles,
392    EcdsaPublicKey,
393    GetCycles,
394    InstallChunkedCode,
395    InstallCode,
396    SignWithEcdsa,
397    StopCanister,
398    StoredChunks,
399    UninstallCode,
400    UpdateSettings,
401    UploadChunk,
402}
403
404///
405/// ManagementCallMetricOutcome
406///
407/// Management canister outcome dimension used by runtime metrics recording.
408///
409
410#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
411#[remain::sorted]
412pub enum ManagementCallMetricOutcome {
413    Completed,
414    Failed,
415    Started,
416}
417
418///
419/// ManagementCallMetricReason
420///
421/// Bounded management canister reason dimension used by runtime metrics recording.
422///
423
424#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
425#[remain::sorted]
426pub enum ManagementCallMetricReason {
427    Infra,
428    Ok,
429}
430
431///
432/// PlatformCallMetricSurface
433///
434/// Platform call surface dimension used by public metrics projection.
435///
436
437#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
438#[remain::sorted]
439pub enum PlatformCallMetricSurface {
440    Generic,
441    Management,
442}
443
444impl PlatformCallMetricSurface {
445    /// Return the stable public metrics label for this surface.
446    #[must_use]
447    pub const fn metric_label(self) -> &'static str {
448        match self {
449            Self::Generic => "generic",
450            Self::Management => "management",
451        }
452    }
453}
454
455///
456/// PlatformCallMetricMode
457///
458/// Platform call mode dimension used by public metrics projection.
459///
460
461#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
462#[remain::sorted]
463pub enum PlatformCallMetricMode {
464    BoundedWait,
465    UnboundedWait,
466    Update,
467}
468
469impl PlatformCallMetricMode {
470    /// Return the stable public metrics label for this mode.
471    #[must_use]
472    pub const fn metric_label(self) -> &'static str {
473        match self {
474            Self::BoundedWait => "bounded_wait",
475            Self::UnboundedWait => "unbounded_wait",
476            Self::Update => "update",
477        }
478    }
479}
480
481///
482/// PlatformCallMetricOutcome
483///
484/// Platform call outcome dimension used by public metrics projection.
485///
486
487#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
488#[remain::sorted]
489pub enum PlatformCallMetricOutcome {
490    Completed,
491    Failed,
492    Started,
493}
494
495impl PlatformCallMetricOutcome {
496    /// Return the stable public metrics label for this outcome.
497    #[must_use]
498    pub const fn metric_label(self) -> &'static str {
499        match self {
500            Self::Completed => "completed",
501            Self::Failed => "failed",
502            Self::Started => "started",
503        }
504    }
505}
506
507///
508/// PlatformCallMetricReason
509///
510/// Bounded platform call reason dimension used by public metrics projection.
511///
512
513#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
514#[remain::sorted]
515pub enum PlatformCallMetricReason {
516    CandidDecode,
517    CandidEncode,
518    Infra,
519    Ok,
520}
521
522impl PlatformCallMetricReason {
523    /// Return the stable public metrics label for this reason.
524    #[must_use]
525    pub const fn metric_label(self) -> &'static str {
526        match self {
527            Self::CandidDecode => "candid_decode",
528            Self::CandidEncode => "candid_encode",
529            Self::Infra => "infra",
530            Self::Ok => "ok",
531        }
532    }
533}