use std::time::Duration;
use crate::observer::{ExtensionEvent, GaObserver, IslandGaObserver, Nsga2Observer};
use crate::stats::GenerationStats;
use crate::traits::ChromosomeT;
pub struct MetricsObserver {
run_id: &'static str,
}
impl MetricsObserver {
pub fn new(run_id: &'static str) -> Self {
Self { run_id }
}
pub fn run_id(&self) -> &'static str {
self.run_id
}
}
impl Default for MetricsObserver {
fn default() -> Self {
Self::new("default")
}
}
impl<U: ChromosomeT> GaObserver<U> for MetricsObserver {
fn on_selection_complete(&self, _generation: usize, duration: Duration, _population_size: usize) {
metrics::histogram!("ga.operator.selection_ms", "run_id" => self.run_id)
.record(duration.as_secs_f64() * 1000.0);
}
fn on_crossover_complete(&self, _generation: usize, duration: Duration, _offspring_count: usize) {
metrics::histogram!("ga.operator.crossover_ms", "run_id" => self.run_id)
.record(duration.as_secs_f64() * 1000.0);
}
fn on_mutation_complete(&self, _generation: usize, duration: Duration, _population_size: usize) {
metrics::histogram!("ga.operator.mutation_ms", "run_id" => self.run_id)
.record(duration.as_secs_f64() * 1000.0);
}
fn on_fitness_evaluation_complete(&self, _generation: usize, duration: Duration, _population_size: usize) {
metrics::histogram!("ga.operator.fitness_eval_ms", "run_id" => self.run_id)
.record(duration.as_secs_f64() * 1000.0);
}
fn on_survivor_selection_complete(&self, _generation: usize, duration: Duration, _population_size: usize) {
metrics::histogram!("ga.operator.survivor_ms", "run_id" => self.run_id)
.record(duration.as_secs_f64() * 1000.0);
}
fn on_new_best(&self, _generation: usize, _best: U) {
metrics::counter!("ga.event.new_best", "run_id" => self.run_id).increment(1);
}
fn on_stagnation(&self, _generation: usize, _stagnation_count: usize) {
metrics::counter!("ga.event.stagnation", "run_id" => self.run_id).increment(1);
}
fn on_extension_triggered(&self, _event: ExtensionEvent) {
metrics::counter!("ga.event.extension_triggered", "run_id" => self.run_id).increment(1);
}
fn on_generation_end(&self, stats: &GenerationStats) {
metrics::gauge!("ga.generation.best_fitness", "run_id" => self.run_id).set(stats.best_fitness);
metrics::gauge!("ga.generation.mean_fitness", "run_id" => self.run_id).set(stats.avg_fitness);
metrics::gauge!("ga.generation.diversity", "run_id" => self.run_id).set(stats.diversity);
}
}
impl<U: ChromosomeT> IslandGaObserver<U> for MetricsObserver {}
impl<U: ChromosomeT> Nsga2Observer<U> for MetricsObserver {}