use super::ledger::{SkipReason, SweepReport};
pub fn describe() {
metrics::describe_counter!(
"faucet_local_outputs_deleted_total",
"Local sink output files deleted by the retention GC, by sweep scope."
);
metrics::describe_counter!(
"faucet_local_outputs_bytes_deleted_total",
"Bytes reclaimed by deleting local sink output files, by sweep scope."
);
metrics::describe_counter!(
"faucet_local_outputs_skipped_total",
"Local sink outputs a sweep declined to delete, by scope and reason \
(pre_existing / already_deleted / not_on_disk / in_flight / delete_failed)."
);
metrics::describe_counter!(
"faucet_local_outputs_sweeps_total",
"Local-output cleanup passes, by scope."
);
metrics::describe_counter!(
"faucet_local_outputs_recorded_total",
"Local sink output files recorded in the ledger, by connector kind."
);
}
pub fn sweep(scope: &'static str, report: &SweepReport) {
if report.dry_run {
return;
}
metrics::counter!("faucet_local_outputs_sweeps_total", "scope" => scope).increment(1);
metrics::counter!("faucet_local_outputs_deleted_total", "scope" => scope)
.increment(report.deleted as u64);
metrics::counter!("faucet_local_outputs_bytes_deleted_total", "scope" => scope)
.increment(report.bytes);
for reason in [
SkipReason::PreExisting,
SkipReason::AlreadyDeleted,
SkipReason::NotOnDisk,
SkipReason::InFlight,
SkipReason::DeleteFailed,
] {
let n = report.skipped_for(reason);
if n > 0 {
metrics::counter!(
"faucet_local_outputs_skipped_total",
"scope" => scope,
"reason" => reason.as_str(),
)
.increment(n as u64);
}
}
}
pub fn recorded(kind: &str, n: usize) {
if n > 0 {
metrics::counter!("faucet_local_outputs_recorded_total", "kind" => kind.to_string())
.increment(n as u64);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::local_outputs::ledger::SweepOutcome;
fn outcome(deleted: bool, skipped: Option<SkipReason>) -> SweepOutcome {
SweepOutcome {
id: "id".into(),
path: "/tmp/a".into(),
dataset_uri: "file:///tmp/a".into(),
deleted,
bytes: if deleted { 10 } else { 0 },
skipped,
error: None,
}
}
#[test]
fn describe_is_idempotent_and_recorder_free() {
describe();
describe();
}
#[test]
fn emitters_are_callable_without_a_recorder() {
let mut report = SweepReport {
scope: "expired".into(),
..Default::default()
};
report.push(outcome(true, None));
report.push(outcome(false, Some(SkipReason::PreExisting)));
sweep("expired", &report);
recorded("jsonl", 3);
recorded("jsonl", 0);
}
#[test]
fn a_dry_run_emits_nothing() {
let report = SweepReport {
dry_run: true,
scope: "all".into(),
deleted: 5,
bytes: 500,
..Default::default()
};
sweep("all", &report);
}
}