#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BackendMetricKind {
Counter,
Gauge,
Max,
Histogram,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BackendMetricUnit {
One,
Bytes,
Seconds,
}
impl BackendMetricUnit {
pub const fn as_ucum(self) -> &'static str {
match self {
Self::One => "1",
Self::Bytes => "By",
Self::Seconds => "s",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BackendMetricUpdatePoint {
LedgerTransition,
ReportReady,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BackendMetricLabel {
pub(crate) name: &'static str,
pub(crate) cardinality: usize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BackendMetricDescriptor {
pub metric: BackendMetric,
pub name: &'static str,
pub unit: BackendMetricUnit,
pub kind: BackendMetricKind,
pub labels: &'static [BackendMetricLabel],
pub buckets: &'static [u64],
pub update_point: BackendMetricUpdatePoint,
pub max_series: usize,
}
#[derive(Debug, Clone, PartialEq)]
pub struct BackendDurationHistogramProjection {
pub bucket_bounds: Vec<f64>,
pub sum: f64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BackendDurationProjectionError {
pub metric_name: &'static str,
pub unit: BackendMetricUnit,
}
impl std::fmt::Display for BackendDurationProjectionError {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(formatter, "{} cannot project a duration with UCUM unit {}", self.metric_name, self.unit.as_ucum())
}
}
impl std::error::Error for BackendDurationProjectionError {}
pub fn project_backend_duration_histogram(
descriptor: &BackendMetricDescriptor,
sum_ns: u64,
) -> Result<BackendDurationHistogramProjection, BackendDurationProjectionError> {
match descriptor.unit {
BackendMetricUnit::Seconds => Ok(BackendDurationHistogramProjection {
bucket_bounds: descriptor.buckets.iter().map(|bound_ns| *bound_ns as f64 / 1_000_000_000.0).collect(),
sum: sum_ns as f64 / 1_000_000_000.0,
}),
unit => Err(BackendDurationProjectionError { metric_name: descriptor.name, unit }),
}
}
const DEVICE: BackendMetricLabel = BackendMetricLabel { name: "device.ordinal", cardinality: 64 };
const OUTCOME: BackendMetricLabel = BackendMetricLabel { name: "attempt.outcome", cardinality: 8 };
const DISPOSITION: BackendMetricLabel = BackendMetricLabel { name: "attempt.disposition", cardinality: 4 };
const DURATION: BackendMetricLabel = BackendMetricLabel { name: "attempt.duration", cardinality: 4 };
const EMPTY_BUCKETS: &[u64] = &[];
const DEVICE_LABELS: &[BackendMetricLabel] = &[DEVICE];
const ATTEMPT_LABELS: &[BackendMetricLabel] = &[DISPOSITION, OUTCOME];
const ATTEMPT_DURATION_LABELS: &[BackendMetricLabel] = &[DISPOSITION, OUTCOME, DURATION];
pub const BACKEND_ATTEMPT_DURATION_BUCKETS_NS: [u64; 7] =
[1_000, 10_000, 100_000, 1_000_000, 10_000_000, 100_000_000, 1_000_000_000];
const DURATION_BUCKETS_NS: &[u64] = &BACKEND_ATTEMPT_DURATION_BUCKETS_NS;
macro_rules! for_each_backend_metric {
($macro:ident) => {
$macro! {
"Current admitted attempts whose grant is active or being cleaned up."; admission_active_attempts => "algeon.gpu.admission.active_attempts": BackendMetricUnit::One, BackendMetricKind::Gauge, DEVICE_LABELS, EMPTY_BUCKETS, BackendMetricUpdatePoint::LedgerTransition, 64;
"Current bytes committed to immutable active or cleaning query grants."; admission_live_grant_bytes => "algeon.gpu.admission.live_grant": BackendMetricUnit::Bytes, BackendMetricKind::Gauge, DEVICE_LABELS, EMPTY_BUCKETS, BackendMetricUpdatePoint::LedgerTransition, 64;
"Current bytes retained by live resident owners."; admission_resident_owner_bytes => "algeon.gpu.admission.resident_owner": BackendMetricUnit::Bytes, BackendMetricKind::Gauge, DEVICE_LABELS, EMPTY_BUCKETS, BackendMetricUpdatePoint::LedgerTransition, 64;
"Maximum resident-owner bytes over the backend generation."; admission_max_resident_owner_bytes => "algeon.gpu.admission.max_resident_owner": BackendMetricUnit::Bytes, BackendMetricKind::Max, DEVICE_LABELS, EMPTY_BUCKETS, BackendMetricUpdatePoint::LedgerTransition, 64;
"Terminal attempts counted when their sealed report becomes ready."; attempts_completed => "algeon.gpu.attempts.completed": BackendMetricUnit::One, BackendMetricKind::Counter, ATTEMPT_LABELS, EMPTY_BUCKETS, BackendMetricUpdatePoint::ReportReady, 32;
"Sealed attempt durations grouped by coverage, outcome and duration kind."; attempts_duration => "algeon.gpu.attempts.duration": BackendMetricUnit::Seconds, BackendMetricKind::Histogram, ATTEMPT_DURATION_LABELS, DURATION_BUCKETS_NS, BackendMetricUpdatePoint::ReportReady, 128;
"Current cached resident bytes eligible for eviction."; cache_evictable_resident_bytes => "algeon.gpu.cache.evictable.resident": BackendMetricUnit::Bytes, BackendMetricKind::Gauge, DEVICE_LABELS, EMPTY_BUCKETS, BackendMetricUpdatePoint::LedgerTransition, 64;
"Current cached resident bytes pinned by active use."; cache_pinned_in_use_bytes => "algeon.gpu.cache.pinned.in_use": BackendMetricUnit::Bytes, BackendMetricKind::Gauge, DEVICE_LABELS, EMPTY_BUCKETS, BackendMetricUpdatePoint::LedgerTransition, 64;
}
};
}
macro_rules! define_backend_metric_ids {
($( $doc:literal; $field:ident => $name:literal: $unit:expr, $kind:expr, $labels:ident, $buckets:ident, $point:expr, $max:literal; )*) => {
#[expect(
non_camel_case_types,
reason = "metric identifiers are generated in snake_case matching descriptor fields"
)]
#[repr(usize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BackendMetric {
$( #[doc = $doc] $field, )*
}
pub const BACKEND_METRIC_DESCRIPTORS: &[BackendMetricDescriptor] = &[
$( BackendMetricDescriptor { metric: BackendMetric::$field, name: $name, unit: $unit, kind: $kind, labels: $labels, buckets: $buckets, update_point: $point, max_series: $max }, )*
];
};
}
for_each_backend_metric!(define_backend_metric_ids);
pub const fn backend_metric_descriptors() -> &'static [BackendMetricDescriptor] {
BACKEND_METRIC_DESCRIPTORS
}
impl BackendMetric {
pub(crate) const fn descriptor(self) -> &'static BackendMetricDescriptor {
&BACKEND_METRIC_DESCRIPTORS[self as usize]
}
}
#[cfg(test)]
mod tests {
use super::*;
const GOLDEN: &[(&str, BackendMetricUnit, BackendMetricKind, BackendMetricUpdatePoint, usize)] = &[
(
"algeon.gpu.admission.active_attempts",
BackendMetricUnit::One,
BackendMetricKind::Gauge,
BackendMetricUpdatePoint::LedgerTransition,
64,
),
(
"algeon.gpu.admission.live_grant",
BackendMetricUnit::Bytes,
BackendMetricKind::Gauge,
BackendMetricUpdatePoint::LedgerTransition,
64,
),
(
"algeon.gpu.admission.resident_owner",
BackendMetricUnit::Bytes,
BackendMetricKind::Gauge,
BackendMetricUpdatePoint::LedgerTransition,
64,
),
(
"algeon.gpu.admission.max_resident_owner",
BackendMetricUnit::Bytes,
BackendMetricKind::Max,
BackendMetricUpdatePoint::LedgerTransition,
64,
),
(
"algeon.gpu.attempts.completed",
BackendMetricUnit::One,
BackendMetricKind::Counter,
BackendMetricUpdatePoint::ReportReady,
32,
),
(
"algeon.gpu.attempts.duration",
BackendMetricUnit::Seconds,
BackendMetricKind::Histogram,
BackendMetricUpdatePoint::ReportReady,
128,
),
(
"algeon.gpu.cache.evictable.resident",
BackendMetricUnit::Bytes,
BackendMetricKind::Gauge,
BackendMetricUpdatePoint::LedgerTransition,
64,
),
(
"algeon.gpu.cache.pinned.in_use",
BackendMetricUnit::Bytes,
BackendMetricKind::Gauge,
BackendMetricUpdatePoint::LedgerTransition,
64,
),
];
#[test]
fn descriptor_table_golden_is_stable() {
assert_eq!(BACKEND_METRIC_DESCRIPTORS.len(), GOLDEN.len());
for (actual, expected) in BACKEND_METRIC_DESCRIPTORS.iter().zip(GOLDEN) {
assert_eq!((actual.name, actual.unit, actual.kind, actual.update_point, actual.max_series), *expected);
assert_eq!(actual.metric.descriptor(), actual, "{} must retain its descriptor identity", actual.name);
}
}
#[test]
fn label_products_fit_declared_series_bounds() {
for descriptor in BACKEND_METRIC_DESCRIPTORS {
let product = descriptor.labels.iter().map(|label| label.cardinality).product::<usize>();
assert!(product <= descriptor.max_series, "{} exceeds max_series", descriptor.name);
if descriptor.kind == BackendMetricKind::Histogram {
assert!(!descriptor.buckets.is_empty());
} else {
assert!(descriptor.buckets.is_empty());
}
}
}
#[test]
fn labels_are_closed_and_measurement_names_are_not_dimensions() {
let forbidden = ["query_id", "attempt_id", "sql", "user", "path", "uri", "message", "node_id"];
for descriptor in BACKEND_METRIC_DESCRIPTORS {
for label in descriptor.labels {
assert!(!forbidden.contains(&label.name));
assert!(!label.name.ends_with("_bytes"));
assert!(!label.name.ends_with("_rows"));
assert!(!label.name.ends_with("_ns"));
}
}
}
#[test]
fn names_and_units_follow_backend_conventions() {
for descriptor in BACKEND_METRIC_DESCRIPTORS {
assert!(descriptor.name.starts_with("algeon."));
assert!(
descriptor.name.chars().all(|c| c == '.' || c == '_' || c.is_ascii_lowercase() || c.is_ascii_digit())
);
assert!(matches!(descriptor.unit.as_ucum(), "1" | "By" | "s"));
}
}
}