use std::{cell::RefCell, collections::HashMap};
thread_local! {
static LIFECYCLE_METRICS: RefCell<HashMap<LifecycleMetricKey, u64>> =
RefCell::new(HashMap::new());
}
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[remain::sorted]
pub enum LifecycleMetricPhase {
Init,
PostUpgrade,
}
impl LifecycleMetricPhase {
#[must_use]
pub const fn metric_label(self) -> &'static str {
match self {
Self::Init => "init",
Self::PostUpgrade => "post_upgrade",
}
}
}
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[remain::sorted]
pub enum LifecycleMetricRole {
Nonroot,
Root,
}
impl LifecycleMetricRole {
#[must_use]
pub const fn metric_label(self) -> &'static str {
match self {
Self::Nonroot => "nonroot",
Self::Root => "root",
}
}
}
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[remain::sorted]
pub enum LifecycleMetricStage {
Bootstrap,
Runtime,
}
impl LifecycleMetricStage {
#[must_use]
pub const fn metric_label(self) -> &'static str {
match self {
Self::Bootstrap => "bootstrap",
Self::Runtime => "runtime",
}
}
}
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[remain::sorted]
pub enum LifecycleMetricOutcome {
Completed,
Failed,
Scheduled,
Skipped,
Started,
Waiting,
}
impl LifecycleMetricOutcome {
#[must_use]
pub const fn metric_label(self) -> &'static str {
match self {
Self::Completed => "completed",
Self::Failed => "failed",
Self::Scheduled => "scheduled",
Self::Skipped => "skipped",
Self::Started => "started",
Self::Waiting => "waiting",
}
}
}
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
pub struct LifecycleMetricKey {
pub phase: LifecycleMetricPhase,
pub role: LifecycleMetricRole,
pub stage: LifecycleMetricStage,
pub outcome: LifecycleMetricOutcome,
}
pub struct LifecycleMetrics;
impl LifecycleMetrics {
pub fn record(
phase: LifecycleMetricPhase,
role: LifecycleMetricRole,
stage: LifecycleMetricStage,
outcome: LifecycleMetricOutcome,
) {
LIFECYCLE_METRICS.with_borrow_mut(|counts| {
let key = LifecycleMetricKey {
phase,
role,
stage,
outcome,
};
let entry = counts.entry(key).or_insert(0);
*entry = entry.saturating_add(1);
});
}
#[must_use]
pub fn snapshot() -> Vec<(LifecycleMetricKey, u64)> {
LIFECYCLE_METRICS
.with_borrow(std::clone::Clone::clone)
.into_iter()
.collect()
}
#[cfg(test)]
pub fn reset() {
LIFECYCLE_METRICS.with_borrow_mut(HashMap::clear);
}
}