Skip to content

Commit 53b169c

Browse files
feat: check for perf compression and enable multi-events conditionally
1 parent 0d5ea2e commit 53b169c

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

src/executor/wall_time/perf/mod.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::run::UnwindingMode;
1818
use anyhow::Context;
1919
use fifo::PerfFifo;
2020
use libc::pid_t;
21+
use perf_executable::get_compression_flags;
2122
use perf_executable::get_event_flags;
2223
use perf_map::ProcessSymbols;
2324
use runner_shared::artifacts::ArtifactExt;
@@ -137,10 +138,15 @@ impl PerfRunner {
137138
if !is_codspeed_debug_enabled() {
138139
perf_wrapper_builder.arg("--quiet");
139140
}
140-
// Add events flag if all required events are available
141-
if let Some(events_flag) = get_event_flags(&working_perf_executable)? {
142-
perf_wrapper_builder.arg(events_flag);
141+
// Add compression if available
142+
if let Some(compression_flags) = get_compression_flags(&working_perf_executable)? {
143+
perf_wrapper_builder.arg(compression_flags);
144+
// Add events flag if all required events are available
145+
if let Some(events_flag) = get_event_flags(&working_perf_executable)? {
146+
perf_wrapper_builder.arg(events_flag);
147+
}
143148
}
149+
144150
perf_wrapper_builder.args([
145151
"--timestamp",
146152
// Required for matching the markers and URIs to the samples.
@@ -149,7 +155,6 @@ impl PerfRunner {
149155
"--freq=997", // Use a prime number to avoid synchronization with periodic tasks
150156
"--delay=-1",
151157
"-g",
152-
"--compression-level=3", // 3 is a widely adopted default level (AWS Athena, Python, ...)
153158
"--user-callchains",
154159
&format!("--call-graph={cg_mode}"),
155160
&format!(

src/executor/wall_time/perf/perf_executable.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::prelude::*;
2+
use std::path::Path;
23

34
use std::{ffi::OsString, process::Command};
45

@@ -104,3 +105,29 @@ pub fn get_event_flags(perf_executable: &OsString) -> anyhow::Result<Option<Stri
104105
);
105106
Ok(Some(format!("-e {{{}}}", perf_events.join(","))))
106107
}
108+
109+
pub fn get_compression_flags<S: AsRef<Path>>(perf_executable: S) -> Result<Option<String>> {
110+
let output = Command::new(perf_executable.as_ref())
111+
.arg("version")
112+
.arg("--build-options")
113+
.output()
114+
.context("Failed to run perf version --build-options")?;
115+
116+
let stdout = String::from_utf8_lossy(&output.stdout);
117+
debug!("Perf version build options:\n{stdout}");
118+
119+
// Look for zstd compression support in the build options
120+
// Expected format: " zstd: [ on ] # HAVE_ZSTD_SUPPORT"
121+
let has_zstd = stdout
122+
.lines()
123+
.any(|line| line.to_lowercase().contains("zstd: [ on"));
124+
125+
if has_zstd {
126+
debug!("perf supports zstd compression");
127+
// 3 is a widely adopted default level (AWS Athena, Python, ...)
128+
Ok(Some("--compression-level=3".to_string()))
129+
} else {
130+
debug!("perf does not support zstd compression");
131+
Ok(None)
132+
}
133+
}

0 commit comments

Comments
 (0)