use std::{collections::HashMap, sync::Arc};
use super::{Aggregate, Direction, Event, EventStore, Split, aggregate::NumericMetricsAggregate};
use crate::logger::MetricLogger;
#[derive(Default)]
pub(crate) struct LogEventStore {
loggers: Vec<Box<dyn MetricLogger>>,
aggregate: NumericMetricsAggregate,
epochs: HashMap<Split, usize>,
}
impl EventStore for LogEventStore {
fn add_event(&mut self, event: Event, split: Split, tag: Option<Arc<String>>) {
let epoch = *self.epochs.entry(split).or_insert(1);
match event {
Event::MetricsInit(definitions) => {
definitions.iter().for_each(|def| {
self.loggers
.iter_mut()
.for_each(|logger| logger.log_metric_definition(def.clone()));
});
}
Event::MetricsUpdate(update) => {
self.loggers
.iter_mut()
.for_each(|logger| logger.log(update.clone(), epoch, split, tag.clone()));
}
Event::EndEpoch(summary) => {
self.epochs.insert(split, summary.epoch_number + 1);
self.loggers
.iter_mut()
.for_each(|logger| logger.log_epoch_summary(summary.clone()));
}
}
}
fn find_epoch(
&mut self,
name: &str,
aggregate: Aggregate,
direction: Direction,
split: Split,
) -> Option<usize> {
self.aggregate
.find_epoch(name, split, aggregate, direction, &mut self.loggers)
}
fn find_metric(
&mut self,
name: &str,
epoch: usize,
aggregate: Aggregate,
split: Split,
) -> Option<f64> {
self.aggregate
.aggregate(name, epoch, split, aggregate, &mut self.loggers)
}
}
impl LogEventStore {
pub(crate) fn register_logger<ML: MetricLogger + 'static>(&mut self, logger: ML) {
self.loggers.push(Box::new(logger));
}
pub(crate) fn has_loggers(&self) -> bool {
!self.loggers.is_empty()
}
}