pub const L_PIPELINE: &str = "pipeline";
pub const L_COMPONENT: &str = "component";
pub const L_COMPONENT_TYPE: &str = "component_type";
pub const L_PARTITION: &str = "partition";
pub const L_SHARD: &str = "shard";
pub const L_REPLICA: &str = "replica";
pub const L_REASON: &str = "reason";
pub const L_OUTCOME: &str = "outcome";
pub const L_OP: &str = "op";
pub const L_EVENT: &str = "event";
pub const L_ERROR_TYPE: &str = "error_type";
pub const L_QUEUE: &str = "queue";
pub const L_STATE: &str = "state";
pub const L_VERSION: &str = "version";
pub const SOURCE_RECORDS_TOTAL: &str = "spate_source_records_total";
pub const SOURCE_BYTES_TOTAL: &str = "spate_source_bytes_total";
pub const SOURCE_POLL_DURATION_SECONDS: &str = "spate_source_poll_duration_seconds";
pub const SOURCE_LAG_RECORDS: &str = "spate_source_lag_records";
pub const SOURCE_REBALANCES_TOTAL: &str = "spate_source_rebalances_total";
pub const SOURCE_LANES_ACTIVE: &str = "spate_source_lanes_active";
pub const DESER_RECORDS_TOTAL: &str = "spate_deser_records_total";
pub const DESER_RECORDS_DROPPED_TOTAL: &str = "spate_deser_records_dropped_total";
pub const DESER_BATCH_DURATION_SECONDS: &str = "spate_deser_batch_duration_seconds";
pub const DESER_NOT_READY_TOTAL: &str = "spate_deser_not_ready_total";
pub const OPERATOR_RECORDS_IN_TOTAL: &str = "spate_operator_records_in_total";
pub const OPERATOR_RECORDS_OUT_TOTAL: &str = "spate_operator_records_out_total";
pub const OPERATOR_RECORDS_DROPPED_TOTAL: &str = "spate_operator_records_dropped_total";
pub const OPERATOR_ERRORS_TOTAL: &str = "spate_operator_errors_total";
pub const OPERATOR_BATCH_DURATION_SECONDS: &str = "spate_operator_batch_duration_seconds";
pub const QUEUE_DEPTH: &str = "spate_queue_depth";
pub const QUEUE_CAPACITY: &str = "spate_queue_capacity";
pub const QUEUE_FULL_EVENTS_TOTAL: &str = "spate_queue_full_events_total";
pub const BACKPRESSURE_PAUSED: &str = "spate_backpressure_paused";
pub const BACKPRESSURE_PAUSED_SECONDS_TOTAL: &str = "spate_backpressure_paused_seconds_total";
pub const BACKPRESSURE_PAUSE_EVENTS_TOTAL: &str = "spate_backpressure_pause_events_total";
pub const BACKPRESSURE_INFLIGHT_BYTES: &str = "spate_backpressure_inflight_bytes";
pub const SINK_RECORDS_TOTAL: &str = "spate_sink_records_total";
pub const SINK_BYTES_TOTAL: &str = "spate_sink_bytes_total";
pub const SINK_BATCH_ROWS: &str = "spate_sink_batch_rows";
pub const SINK_BATCH_BYTES: &str = "spate_sink_batch_bytes";
pub const SINK_FLUSHES_TOTAL: &str = "spate_sink_flushes_total";
pub const SINK_FLUSH_DURATION_SECONDS: &str = "spate_sink_flush_duration_seconds";
pub const SINK_WRITE_DURATION_SECONDS: &str = "spate_sink_write_duration_seconds";
pub const SINK_PERMIT_WAIT_DURATION_SECONDS: &str = "spate_sink_permit_wait_duration_seconds";
pub const SINK_RETRIES_TOTAL: &str = "spate_sink_retries_total";
pub const SINK_RETRY_BACKOFF_SECONDS: &str = "spate_sink_retry_backoff_seconds";
pub const SINK_ERRORS_TOTAL: &str = "spate_sink_errors_total";
pub const SINK_INFLIGHT_BATCHES: &str = "spate_sink_inflight_batches";
pub const SINK_REPLICA_HEALTHY: &str = "spate_sink_replica_healthy";
pub const SINK_BREAKER_OPENS_TOTAL: &str = "spate_sink_breaker_opens_total";
pub const SINK_REPLICA_ERRORS_TOTAL: &str = "spate_sink_replica_errors_total";
pub const SINK_SHARD_HEALTHY: &str = "spate_sink_shard_healthy";
pub const SINK_ABANDONED_BATCHES_TOTAL: &str = "spate_sink_abandoned_batches_total";
pub const SINK_DRAIN_OVERRUN_TOTAL: &str = "spate_sink_drain_overrun_total";
pub const CHECKPOINT_PENDING_BATCHES: &str = "spate_checkpoint_pending_batches";
pub const CHECKPOINT_COMMITS_TOTAL: &str = "spate_checkpoint_commits_total";
pub const CHECKPOINT_COMMIT_DURATION_SECONDS: &str = "spate_checkpoint_commit_duration_seconds";
pub const CHECKPOINT_WATERMARK_AGE_SECONDS: &str = "spate_checkpoint_watermark_age_seconds";
pub const COORDINATION_SPLITS_OWNED: &str = "spate_coordination_splits_owned";
pub const COORDINATION_SPLITS_COMPLETED: &str = "spate_coordination_splits_completed";
pub const COORDINATION_SPLITS_QUARANTINED: &str = "spate_coordination_splits_quarantined";
pub const COORDINATION_LIVE_WORKERS: &str = "spate_coordination_live_workers";
pub const COORDINATION_LEADER: &str = "spate_coordination_leader";
pub const COORDINATION_IDLE: &str = "spate_coordination_idle";
pub const COORDINATION_ACQUISITIONS_TOTAL: &str = "spate_coordination_acquisitions_total";
pub const COORDINATION_SPLIT_LOSSES_TOTAL: &str = "spate_coordination_split_losses_total";
pub const COORDINATION_RELEASES_TOTAL: &str = "spate_coordination_releases_total";
pub const COORDINATION_REVOCATIONS_TOTAL: &str = "spate_coordination_revocations_total";
pub const COORDINATION_DRAIN_DURATION_SECONDS: &str = "spate_coordination_drain_duration_seconds";
pub const COORDINATION_ASSIGNMENT_LATENCY_SECONDS: &str =
"spate_coordination_assignment_latency_seconds";
pub const COORDINATION_SPLITS_DRAINING: &str = "spate_coordination_splits_draining";
pub const COORDINATION_SPLITS_PLANNED_TOTAL: &str = "spate_coordination_splits_planned_total";
pub const COORDINATION_REPLANS_TOTAL: &str = "spate_coordination_replans_total";
pub const COORDINATION_SPLIT_FAILURES_TOTAL: &str = "spate_coordination_split_failures_total";
pub const COORDINATION_QUARANTINES_TOTAL: &str = "spate_coordination_quarantines_total";
pub const COORDINATION_WRITES_TOTAL: &str = "spate_coordination_writes_total";
pub const COORDINATION_WRITE_DURATION_SECONDS: &str = "spate_coordination_write_duration_seconds";
pub const COORDINATION_REPLAN_DURATION_SECONDS: &str = "spate_coordination_replan_duration_seconds";
pub const COORDINATION_RECONCILE_DURATION_SECONDS: &str =
"spate_coordination_reconcile_duration_seconds";
pub const COORDINATION_STORE_OP_DURATION_SECONDS: &str =
"spate_coordination_store_op_duration_seconds";
pub const E2E_LATENCY_SECONDS: &str = "spate_e2e_latency_seconds";
pub const PIPELINE_INFO: &str = "spate_pipeline_info";
pub const PIPELINE_STATE: &str = "spate_pipeline_state";
pub const PIPELINE_THREADS: &str = "spate_pipeline_threads";
pub const COUNTERS: &[&str] = &[
SOURCE_RECORDS_TOTAL,
SOURCE_BYTES_TOTAL,
SOURCE_REBALANCES_TOTAL,
DESER_RECORDS_TOTAL,
DESER_RECORDS_DROPPED_TOTAL,
DESER_NOT_READY_TOTAL,
OPERATOR_RECORDS_IN_TOTAL,
OPERATOR_RECORDS_OUT_TOTAL,
OPERATOR_RECORDS_DROPPED_TOTAL,
OPERATOR_ERRORS_TOTAL,
QUEUE_FULL_EVENTS_TOTAL,
BACKPRESSURE_PAUSE_EVENTS_TOTAL,
SINK_RECORDS_TOTAL,
SINK_BYTES_TOTAL,
SINK_FLUSHES_TOTAL,
SINK_RETRIES_TOTAL,
SINK_ERRORS_TOTAL,
SINK_BREAKER_OPENS_TOTAL,
SINK_REPLICA_ERRORS_TOTAL,
SINK_ABANDONED_BATCHES_TOTAL,
CHECKPOINT_COMMITS_TOTAL,
COORDINATION_ACQUISITIONS_TOTAL,
COORDINATION_SPLIT_LOSSES_TOTAL,
COORDINATION_RELEASES_TOTAL,
COORDINATION_REVOCATIONS_TOTAL,
COORDINATION_SPLITS_PLANNED_TOTAL,
COORDINATION_REPLANS_TOTAL,
COORDINATION_SPLIT_FAILURES_TOTAL,
COORDINATION_QUARANTINES_TOTAL,
COORDINATION_WRITES_TOTAL,
];
pub const GAUGES: &[&str] = &[
SOURCE_LAG_RECORDS,
SOURCE_LANES_ACTIVE,
QUEUE_DEPTH,
QUEUE_CAPACITY,
BACKPRESSURE_PAUSED,
BACKPRESSURE_PAUSED_SECONDS_TOTAL,
BACKPRESSURE_INFLIGHT_BYTES,
SINK_INFLIGHT_BATCHES,
SINK_RETRY_BACKOFF_SECONDS,
SINK_REPLICA_HEALTHY,
SINK_SHARD_HEALTHY,
CHECKPOINT_PENDING_BATCHES,
CHECKPOINT_WATERMARK_AGE_SECONDS,
COORDINATION_SPLITS_OWNED,
COORDINATION_SPLITS_COMPLETED,
COORDINATION_SPLITS_QUARANTINED,
COORDINATION_LIVE_WORKERS,
COORDINATION_LEADER,
COORDINATION_IDLE,
COORDINATION_SPLITS_DRAINING,
PIPELINE_INFO,
PIPELINE_STATE,
PIPELINE_THREADS,
];
pub const HISTOGRAMS: &[&str] = &[
SOURCE_POLL_DURATION_SECONDS,
DESER_BATCH_DURATION_SECONDS,
OPERATOR_BATCH_DURATION_SECONDS,
SINK_BATCH_ROWS,
SINK_BATCH_BYTES,
SINK_FLUSH_DURATION_SECONDS,
SINK_WRITE_DURATION_SECONDS,
SINK_PERMIT_WAIT_DURATION_SECONDS,
CHECKPOINT_COMMIT_DURATION_SECONDS,
COORDINATION_WRITE_DURATION_SECONDS,
COORDINATION_REPLAN_DURATION_SECONDS,
COORDINATION_RECONCILE_DURATION_SECONDS,
COORDINATION_STORE_OP_DURATION_SECONDS,
COORDINATION_DRAIN_DURATION_SECONDS,
COORDINATION_ASSIGNMENT_LATENCY_SECONDS,
E2E_LATENCY_SECONDS,
];
pub const PREFIX: &str = "spate_";
pub const RESERVED_ROOTS: &[&str] = &[
"source",
"deser",
"operator",
"queue",
"backpressure",
"sink",
"checkpoint",
"coordination",
"e2e",
"pipeline",
];
pub const CUSTOM_NAMESPACE: &str = "custom";
pub const ROLE_SEGMENTS: &[&str] = &["source", "sink"];
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashSet;
#[test]
fn names_follow_prometheus_conventions() {
for name in COUNTERS {
assert!(
name.ends_with("_total"),
"counter `{name}` must end in _total"
);
}
for name in HISTOGRAMS {
assert!(
name.ends_with("_seconds") || name.ends_with("_rows") || name.ends_with("_bytes"),
"histogram `{name}` must carry a unit suffix"
);
}
for name in GAUGES {
if *name == BACKPRESSURE_PAUSED_SECONDS_TOTAL {
continue;
}
assert!(
!name.ends_with("_total"),
"gauge `{name}` must not end in _total"
);
}
}
#[test]
fn names_are_prefixed_and_unique() {
let all: Vec<&str> = COUNTERS
.iter()
.chain(GAUGES)
.chain(HISTOGRAMS)
.copied()
.collect();
let unique: HashSet<&str> = all.iter().copied().collect();
assert_eq!(unique.len(), all.len(), "duplicate metric name");
for name in &all {
assert!(name.starts_with(PREFIX), "`{name}` must be spate_-prefixed");
}
}
#[test]
fn every_framework_name_is_under_a_reserved_root() {
for name in COUNTERS.iter().chain(GAUGES).chain(HISTOGRAMS) {
let rest = name
.strip_prefix(PREFIX)
.unwrap_or_else(|| panic!("`{name}` must be spate_-prefixed"));
let root = rest.split('_').next().unwrap_or("");
assert!(
RESERVED_ROOTS.contains(&root),
"`{name}` has root `{root}` not in RESERVED_ROOTS — add it so \
the Meter collision guard covers this family"
);
}
}
}