Skip to main content

aster_bench/
reporting.rs

1use crate::bench_session::BenchAgentError;
2use crate::eval_suites::EvalMetricValue;
3use chrono::Local;
4use serde::{Deserialize, Serialize};
5use std::fmt;
6
7/// Represents a single evaluation result
8#[derive(Default, Deserialize, Serialize)]
9pub struct EvaluationResult {
10    pub name: String,
11    pub metrics: Vec<(String, EvalMetricValue)>,
12    pub errors: Vec<BenchAgentError>,
13}
14
15/// Represents results for an entire suite
16#[derive(Default, Deserialize, Serialize)]
17pub struct SuiteResult {
18    pub name: String,
19    pub evaluations: Vec<EvaluationResult>,
20}
21
22/// Contains all benchmark results and metadata
23#[derive(Default, Deserialize, Serialize)]
24pub struct BenchmarkResults {
25    pub provider: String,
26    pub start_time: String,
27    pub suites: Vec<SuiteResult>,
28}
29
30impl EvaluationResult {
31    pub fn new(name: String) -> Self {
32        Self {
33            name,
34            metrics: Vec::new(),
35            errors: Vec::new(),
36        }
37    }
38
39    pub fn add_metric(&mut self, name: String, metric: EvalMetricValue) {
40        self.metrics.push((name, metric));
41    }
42
43    pub fn add_error(&mut self, error: BenchAgentError) {
44        self.errors.push(error);
45    }
46}
47
48impl SuiteResult {
49    pub fn new(name: String) -> Self {
50        Self {
51            name,
52            evaluations: Vec::new(),
53        }
54    }
55
56    pub fn add_evaluation(&mut self, eval: EvaluationResult) {
57        self.evaluations.push(eval);
58    }
59}
60
61impl BenchmarkResults {
62    pub fn new(provider: String) -> Self {
63        Self {
64            provider,
65            start_time: Local::now().format("%Y-%m-%d %H:%M:%S").to_string(),
66            suites: Vec::new(),
67        }
68    }
69
70    pub fn add_suite(&mut self, suite: SuiteResult) {
71        self.suites.push(suite);
72    }
73
74    /// Generate a summary of the benchmark results
75    pub fn summary(&self) -> String {
76        let mut summary = String::new();
77        summary.push_str(&format!("Benchmark Summary - {}\n", self.provider));
78        summary.push_str(&format!("Run at: {}\n\n", self.start_time));
79
80        for suite in &self.suites {
81            summary.push_str(&format!(
82                "Suite: {} ({} evaluations)\n",
83                suite.name,
84                suite.evaluations.len()
85            ));
86
87            // Count total metrics and errors
88            let total_metrics: usize = suite.evaluations.iter().map(|e| e.metrics.len()).sum();
89            let total_errors: usize = suite.evaluations.iter().map(|e| e.errors.len()).sum();
90
91            summary.push_str(&format!("  Total metrics: {}\n", total_metrics));
92            if total_errors > 0 {
93                summary.push_str(&format!("  Total errors: {}\n", total_errors));
94            }
95        }
96
97        summary
98    }
99}
100
101impl fmt::Display for BenchmarkResults {
102    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103        writeln!(f, "Benchmark Results")?;
104        writeln!(f, "Provider: {}", self.provider)?;
105        writeln!(f, "Start Time: {}", self.start_time)?;
106        writeln!(f)?;
107
108        for suite in &self.suites {
109            writeln!(f, "Suite: {}", suite.name)?;
110
111            for eval in &suite.evaluations {
112                writeln!(f, "  Evaluation: {}", eval.name)?;
113                for (metric_name, metric_value) in &eval.metrics {
114                    writeln!(f, "    {}: {}", metric_name, metric_value)?;
115                }
116                if !eval.errors.is_empty() {
117                    writeln!(f, "    Errors:")?;
118                    for error in &eval.errors {
119                        writeln!(
120                            f,
121                            "      [{}] {}: {}",
122                            error.timestamp.format("%H:%M:%S"),
123                            error.level,
124                            error.message
125                        )?;
126                    }
127                }
128                writeln!(f)?;
129            }
130        }
131        Ok(())
132    }
133}