Print metrics postprocessing to stdout

This allows the code to be simplified a little bit.
This commit is contained in:
Jakub Beránek 2025-03-14 22:21:41 +01:00
parent 301c384262
commit 09d44a48b2
3 changed files with 13 additions and 29 deletions

View file

@ -253,7 +253,7 @@ jobs:
fi
./build/citool/debug/citool postprocess-metrics \
${METRICS} ${GITHUB_STEP_SUMMARY}
${METRICS} >> ${GITHUB_STEP_SUMMARY}
- name: upload job metrics to DataDog
# This step is not critical, and if some I/O problem happens, we don't want

View file

@ -158,9 +158,6 @@ enum Args {
PostprocessMetrics {
/// Path to the metrics.json file
metrics_path: PathBuf,
/// Path to a file where the postprocessed metrics summary will be stored.
/// Usually, this will be GITHUB_STEP_SUMMARY on CI.
summary_path: PathBuf,
},
/// Upload CI metrics to Datadog.
UploadBuildMetrics {
@ -211,8 +208,8 @@ fn main() -> anyhow::Result<()> {
Args::UploadBuildMetrics { cpu_usage_csv } => {
upload_ci_metrics(&cpu_usage_csv)?;
}
Args::PostprocessMetrics { metrics_path, summary_path } => {
postprocess_metrics(&metrics_path, &summary_path)?;
Args::PostprocessMetrics { metrics_path } => {
postprocess_metrics(&metrics_path)?;
}
Args::PostMergeReport { current: commit, parent } => {
post_merge_report(load_db(default_jobs_file)?, parent, commit)?;

View file

@ -1,6 +1,4 @@
use std::collections::BTreeMap;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use anyhow::Context;
@ -8,57 +6,46 @@ use build_helper::metrics::{
BuildStep, JsonNode, JsonRoot, TestOutcome, TestSuite, TestSuiteMetadata, format_build_steps,
};
pub fn postprocess_metrics(metrics_path: &Path, summary_path: &Path) -> anyhow::Result<()> {
pub fn postprocess_metrics(metrics_path: &Path) -> anyhow::Result<()> {
let metrics = load_metrics(metrics_path)?;
let mut file = File::options()
.append(true)
.create(true)
.open(summary_path)
.with_context(|| format!("Cannot open summary file at {summary_path:?}"))?;
if !metrics.invocations.is_empty() {
writeln!(file, "# Bootstrap steps")?;
record_bootstrap_step_durations(&metrics, &mut file)?;
record_test_suites(&metrics, &mut file)?;
println!("# Bootstrap steps");
record_bootstrap_step_durations(&metrics);
record_test_suites(&metrics);
}
Ok(())
}
fn record_bootstrap_step_durations(metrics: &JsonRoot, file: &mut File) -> anyhow::Result<()> {
fn record_bootstrap_step_durations(metrics: &JsonRoot) {
for invocation in &metrics.invocations {
let step = BuildStep::from_invocation(invocation);
let table = format_build_steps(&step);
eprintln!("Step `{}`\n{table}\n", invocation.cmdline);
writeln!(
file,
println!(
r"<details>
<summary>{}</summary>
<pre><code>{table}</code></pre>
</details>
",
invocation.cmdline
)?;
);
}
eprintln!("Recorded {} bootstrap invocation(s)", metrics.invocations.len());
Ok(())
}
fn record_test_suites(metrics: &JsonRoot, file: &mut File) -> anyhow::Result<()> {
fn record_test_suites(metrics: &JsonRoot) {
let suites = get_test_suites(&metrics);
if !suites.is_empty() {
let aggregated = aggregate_test_suites(&suites);
let table = render_table(aggregated);
writeln!(file, "\n# Test results\n")?;
writeln!(file, "{table}")?;
println!("\n# Test results\n");
println!("{table}");
} else {
eprintln!("No test suites found in metrics");
}
Ok(())
}
fn render_table(suites: BTreeMap<String, TestSuiteRecord>) -> String {