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