use std::sync::Mutex;
use opentelemetry::KeyValue;
use opentelemetry::metrics::{Counter, Meter};
use subms::SubMsStageKind;
pub const REFERENCE_DIVERGENCE_COUNTER_NAME: &str = "subms.reference.divergence";
pub const REFERENCE_KIND_ATTR: &str = "subms.reference.kind";
pub const REFERENCE_EXPECTED_ATTR: &str = "subms.reference.expected";
pub const REFERENCE_OBSERVED_ATTR: &str = "subms.reference.observed";
pub fn divergence_attributes(
stage: &str,
kind: SubMsStageKind,
reference_kind: &str,
expected: &str,
observed: &str,
) -> Vec<KeyValue> {
vec![
KeyValue::new("subms.stage", stage.to_string()),
KeyValue::new("subms.stage.kind", kind.as_str()),
KeyValue::new(REFERENCE_KIND_ATTR, reference_kind.to_string()),
KeyValue::new(REFERENCE_EXPECTED_ATTR, expected.to_string()),
KeyValue::new(REFERENCE_OBSERVED_ATTR, observed.to_string()),
]
}
pub fn record_reference_divergence(
meter: &Meter,
stage: &str,
kind: SubMsStageKind,
reference_kind: &str,
expected: &str,
observed: &str,
) {
let counter: Counter<u64> = meter
.u64_counter(REFERENCE_DIVERGENCE_COUNTER_NAME)
.with_description("Count of detected divergences between a recipe and its reference impl")
.build();
let attrs = divergence_attributes(stage, kind, reference_kind, expected, observed);
counter.add(1, &attrs);
}
pub struct ReferenceDivergenceRecorder {
counter: Mutex<Option<Counter<u64>>>,
meter: Meter,
}
impl ReferenceDivergenceRecorder {
pub fn new(meter: Meter) -> Self {
Self {
counter: Mutex::new(None),
meter,
}
}
pub fn record(
&self,
stage: &str,
kind: SubMsStageKind,
reference_kind: &str,
expected: &str,
observed: &str,
) {
let mut slot = self.counter.lock().expect("divergence counter poisoned");
if slot.is_none() {
*slot = Some(
self.meter
.u64_counter(REFERENCE_DIVERGENCE_COUNTER_NAME)
.with_description(
"Count of detected divergences between a recipe and its reference impl",
)
.build(),
);
}
let counter = slot.as_ref().expect("counter just built");
let attrs = divergence_attributes(stage, kind, reference_kind, expected, observed);
counter.add(1, &attrs);
}
}