Skip to content

Commit 5ee21e0

Browse files
committed
feat: include the execution output in the logs
1 parent 8c14c6a commit 5ee21e0

6 files changed

Lines changed: 70 additions & 7 deletions

File tree

src/ci_provider/buildkite/logger.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use crate::ci_provider::logger::{get_group_event, GroupEvent};
1+
use crate::ci_provider::logger::{
2+
get_group_event, should_provider_logger_handle_record, GroupEvent,
3+
};
24
use log::*;
35
use simplelog::SharedLogger;
46
use std::{env, io::Write};
@@ -26,6 +28,10 @@ impl Log for BuildkiteLogger {
2628
}
2729

2830
fn log(&self, record: &Record) {
31+
if !should_provider_logger_handle_record(record) {
32+
return;
33+
}
34+
2935
let level = record.level();
3036
let message = record.args();
3137

src/ci_provider/github_actions/logger.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use crate::ci_provider::logger::{get_group_event, GroupEvent};
1+
use crate::ci_provider::logger::{
2+
get_group_event, should_provider_logger_handle_record, GroupEvent,
3+
};
24
use log::*;
35
use simplelog::SharedLogger;
46
use std::io::Write;
@@ -14,6 +16,10 @@ impl Log for GithubActionLogger {
1416
}
1517

1618
fn log(&self, record: &Record) {
19+
if !should_provider_logger_handle_record(record) {
20+
return;
21+
}
22+
1723
let level = record.level();
1824
let message = record.args();
1925

src/ci_provider/logger.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use crate::runner::VALGRIND_EXECUTION_TARGET;
2+
13
/// This target is used exclusively to handle group events.
24
pub const GROUP_TARGET: &str = "codspeed::group";
35
pub const OPENED_GROUP_TARGET: &str = "codspeed::group::opened";
@@ -71,3 +73,8 @@ pub(super) fn get_group_event(record: &log::Record) -> Option<GroupEvent> {
7173
_ => None,
7274
}
7375
}
76+
77+
pub(super) fn should_provider_logger_handle_record(record: &log::Record) -> bool {
78+
// Provider logger should handle all records except the ones from the valgrind execution target
79+
record.target() != VALGRIND_EXECUTION_TARGET
80+
}

src/logger.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::ci_provider::logger::{GROUP_TARGET, OPENED_GROUP_TARGET};
12
use crate::runner::RunData;
23
use crate::{ci_provider::CIProvider, prelude::*};
34
use log::LevelFilter;
@@ -16,8 +17,12 @@ impl Logger {
1617
let provider_logger = provider.get_logger();
1718
let log_file = NamedTempFile::new().context("Failed to create log file")?;
1819
let log_file_path = log_file.path().to_path_buf();
19-
let file_logger =
20-
WriteLogger::new(LevelFilter::Trace, simplelog::Config::default(), log_file);
20+
let file_logger_config = simplelog::ConfigBuilder::new()
21+
// Groups are not logged to the file
22+
.add_filter_ignore_str(GROUP_TARGET)
23+
.add_filter_ignore_str(OPENED_GROUP_TARGET)
24+
.build();
25+
let file_logger = WriteLogger::new(LevelFilter::Trace, file_logger_config, log_file);
2126
CombinedLogger::init(vec![provider_logger, file_logger])
2227
.context("Failed to init logger")?;
2328
Ok(Self { log_file_path })

src/runner/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ mod valgrind;
66

77
pub use self::run::RunData;
88
pub use run::run;
9+
pub use valgrind::VALGRIND_EXECUTION_TARGET;

src/runner/valgrind.rs

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ use crate::prelude::*;
44
use crate::runner::helpers::ignored_objects_path::get_objects_path_to_ignore;
55
use crate::runner::helpers::introspected_node::setup_introspected_node;
66
use lazy_static::lazy_static;
7-
use std::env;
87
use std::fs::canonicalize;
8+
use std::io::{Read, Write};
99
use std::path::Path;
10+
use std::process::ExitStatus;
1011
use std::{collections::HashMap, env::consts::ARCH, process::Command};
12+
use std::{env, thread};
1113

1214
lazy_static! {
1315
static ref BASE_INJECTED_ENV: HashMap<&'static str, String> = {
@@ -54,6 +56,43 @@ fn get_bench_command(config: &Config) -> String {
5456
.replace("cargo codspeed", "cargo-codspeed")
5557
}
5658

59+
pub const VALGRIND_EXECUTION_TARGET: &str = "valgrind::execution";
60+
61+
fn run_command_with_log_pipe(mut cmd: Command) -> Result<ExitStatus> {
62+
fn log_tee(
63+
mut reader: impl Read,
64+
mut writer: impl Write,
65+
log_prefix: Option<&str>,
66+
) -> Result<()> {
67+
let prefix = log_prefix.unwrap_or("");
68+
let mut buffer = [0; 1024];
69+
loop {
70+
let bytes_read = reader.read(&mut buffer)?;
71+
if bytes_read == 0 {
72+
break;
73+
}
74+
writer.write_all(&buffer[..bytes_read])?;
75+
trace!(target: VALGRIND_EXECUTION_TARGET, "{}{}", prefix, String::from_utf8_lossy(&buffer[..bytes_read]));
76+
}
77+
Ok(())
78+
}
79+
80+
let mut process = cmd
81+
.stdout(std::process::Stdio::piped())
82+
.stderr(std::process::Stdio::piped())
83+
.spawn()
84+
.context("failed to spawn the process")?;
85+
let stdout = process.stdout.take().expect("unable to get stdout");
86+
let stderr = process.stderr.take().expect("unable to get stderr");
87+
thread::spawn(move || {
88+
log_tee(stdout, std::io::stdout(), None).unwrap();
89+
});
90+
thread::spawn(move || {
91+
log_tee(stderr, std::io::stderr(), Some("[stderr]")).unwrap();
92+
});
93+
process.wait().context("failed to wait for the process")
94+
}
95+
5796
pub fn measure(
5897
config: &Config,
5998
profile_folder: &Path,
@@ -102,8 +141,7 @@ pub fn measure(
102141
}
103142

104143
debug!("cmd: {:?}", cmd);
105-
let status = cmd
106-
.status()
144+
let status = run_command_with_log_pipe(cmd)
107145
.map_err(|e| anyhow!("failed to execute the benchmark process. {}", e))?;
108146
if !status.success() {
109147
bail!("failed to execute the benchmark process");

0 commit comments

Comments
 (0)