use std::sync::Arc;
use metrics::{GaugeValue, Key, Unit};
use elfo_core::scope;
use crate::{
metrics::{Counter, Gauge, Histogram},
storage::{ActorScope, GlobalScope, GroupScope, Storable, Storage},
};
pub(crate) struct Recorder {
storage: Arc<Storage>,
}
impl Recorder {
pub(crate) fn new(storage: Arc<Storage>) -> Self {
Self { storage }
}
fn record<M>(&self, key: &Key, value: M::Value)
where
M: Storable,
M::Value: Clone,
{
scope::try_with(|scope| {
let perm = scope.permissions();
if perm.is_telemetry_per_actor_group_enabled() {
self.storage
.upsert::<GroupScope, M>(scope, key, value.clone())
}
if perm.is_telemetry_per_actor_key_enabled() {
if scope.telemetry_meta().key.is_empty() {
return;
}
self.storage
.upsert::<ActorScope, M>(scope, key, value.clone())
}
})
.unwrap_or_else(|| self.storage.upsert::<GlobalScope, M>(&(), key, value))
}
}
impl metrics::Recorder for Recorder {
fn register_counter(&self, key: &Key, unit: Option<Unit>, description: Option<&'static str>) {
self.storage.describe(key, unit, description);
}
fn register_gauge(&self, key: &Key, unit: Option<Unit>, description: Option<&'static str>) {
self.storage.describe(key, unit, description);
}
fn register_histogram(&self, key: &Key, unit: Option<Unit>, description: Option<&'static str>) {
self.storage.describe(key, unit, description);
}
fn increment_counter(&self, key: &Key, value: u64) {
self.record::<Counter>(key, value)
}
fn update_gauge(&self, key: &Key, value: GaugeValue) {
self.record::<Gauge>(key, value)
}
fn record_histogram(&self, key: &Key, value: f64) {
self.record::<Histogram>(key, value)
}
}