sofie-http 0.2.0

The HTTP server, areas, routes and the handler model.
Documentation
use super::detector::Decision;

#[cfg(feature = "metrics")]
static DECISIONS: sofie_telemetry::metrics::Instrument = sofie_telemetry::metrics::Instrument {
    name: "sofie.shield.decisions",
    description: "The shield's decisions, by rule and grade; dry runs included.",
    kind: sofie_telemetry::metrics::Kind::Counter,
    labels: &["shield.rule", "shield.grade"],
};
#[cfg(feature = "metrics")]
static DROPPED: sofie_telemetry::metrics::Instrument = sofie_telemetry::metrics::Instrument {
    name: "sofie.shield.signals.dropped",
    description: "Signals dropped because the shield's queue or its windows were full.",
    kind: sofie_telemetry::metrics::Kind::Counter,
    labels: &[],
};

pub(crate) fn decided(decision: &Decision, dry_run: bool) {
    tracing::warn!(
        shield.rule = decision.rule.name(),
        shield.grade = decision.grade.name(),
        shield.reason = decision.rule.reason(),
        shield.caller = %decision.key.shown(),
        shield.count = decision.count,
        shield.threshold = decision.threshold,
        shield.until = %instant(decision.until),
        shield.dry_run = dry_run,
        area = decision.area.unwrap_or_default(),
        "the shield decided"
    );
    #[cfg(feature = "metrics")]
    sofie_telemetry::metrics::record(
        &DECISIONS,
        &[decision.rule.name().into(), decision.grade.name().into()],
        1.0,
    );
}

pub(crate) fn instant(micros: i64) -> String {
    sofie_core::Timestamp::from_microsecond(micros)
        .map_or_else(|_| micros.to_string(), |at| at.to_string())
}

pub(crate) fn table_full(decision: &Decision) {
    tracing::warn!(
        shield.rule = decision.rule.name(),
        shield.grade = decision.grade.name(),
        "the shield's block table is full; the decision is reported only"
    );
}

pub(crate) fn dropped(count: u64) {
    if count == 0 {
        return;
    }
    tracing::warn!(
        shield.dropped = count,
        "the shield dropped signals it had no room for"
    );
    #[cfg(feature = "metrics")]
    #[expect(
        clippy::cast_precision_loss,
        reason = "a count of dropped signals is far below 2^52"
    )]
    sofie_telemetry::metrics::record(&DROPPED, &[], count as f64);
}