Skip to content

Commit f819729

Browse files
committed
Store Chrome step trace into the tracing directory
1 parent c97b606 commit f819729

File tree

2 files changed

+48
-14
lines changed

2 files changed

+48
-14
lines changed

src/bootstrap/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ default-run = "bootstrap"
77

88
[features]
99
build-metrics = ["sysinfo"]
10-
tracing = ["dep:tracing", "dep:tracing-chrome", "dep:tracing-subscriber", "dep:tracing-forest"]
10+
tracing = ["dep:tracing", "dep:tracing-chrome", "dep:tracing-subscriber", "dep:tracing-forest", "dep:tempfile"]
1111

1212
[lib]
1313
path = "src/lib.rs"
@@ -65,6 +65,7 @@ tracing = { version = "0.1", optional = true, features = ["attributes"] }
6565
tracing-chrome = { version = "0.7", optional = true }
6666
tracing-subscriber = { version = "0.3", optional = true, features = ["env-filter", "fmt", "registry", "std"] }
6767
tracing-forest = { version = "0.1.6", optional = true, default-features = false, features = ["smallvec", "ansi", "env-filter"] }
68+
tempfile = { version = "3.15.0", optional = true }
6869

6970
[target.'cfg(windows)'.dependencies.junction]
7071
version = "1.0.0"

src/bootstrap/src/bin/main.rs

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ fn is_tracing_enabled() -> bool {
2929
#[cfg_attr(feature = "tracing", instrument(level = "trace", name = "main"))]
3030
fn main() {
3131
#[cfg(feature = "tracing")]
32-
let _guard = setup_tracing();
32+
let guard = setup_tracing(is_profiling_enabled());
3333

3434
let start_time = Instant::now();
3535

@@ -183,7 +183,12 @@ fn main() {
183183
}
184184

185185
#[cfg(feature = "tracing")]
186-
build.report_step_graph(&tracing_dir);
186+
{
187+
build.report_step_graph(&tracing_dir);
188+
if let Some(guard) = guard {
189+
guard.copy_to_dir(&tracing_dir);
190+
}
191+
}
187192

188193
if tracing_enabled {
189194
eprintln!("Tracing/profiling output has been written to {}", latest_trace_dir.display());
@@ -257,25 +262,53 @@ fn check_version(config: &Config) -> Option<String> {
257262
// - `tracing`'s `#[instrument(..)]` macro will need to be gated like `#![cfg_attr(feature =
258263
// "tracing", instrument(..))]`.
259264
#[cfg(feature = "tracing")]
260-
fn setup_tracing() -> impl Drop {
265+
fn setup_tracing(profiling_enabled: bool) -> Option<TracingGuard> {
266+
use std::fs::File;
267+
use std::io::BufWriter;
268+
261269
use tracing_forest::ForestLayer;
262270
use tracing_subscriber::EnvFilter;
263271
use tracing_subscriber::layer::SubscriberExt;
264272

265273
let filter = EnvFilter::from_env("BOOTSTRAP_TRACING");
266274

267-
let mut chrome_layer = tracing_chrome::ChromeLayerBuilder::new().include_args(true);
275+
let registry = tracing_subscriber::registry().with(filter).with(ForestLayer::default());
268276

269-
// Writes the Chrome profile to trace-<unix-timestamp>.json if enabled
270-
if !is_profiling_enabled() {
271-
chrome_layer = chrome_layer.writer(io::sink());
272-
}
277+
let guard = if profiling_enabled {
278+
// When we're creating this layer, we do not yet know the location of the tracing output
279+
// directory, because it is stored in the output directory determined after Config is parsed,
280+
// but we already want to make tracing calls during (and before) config parsing.
281+
// So we store the output into a temporary file, and then move it to the tracing directory
282+
// before bootstrap ends.
283+
let tempdir = tempfile::TempDir::new().expect("Cannot create temporary directory");
284+
let chrome_tracing_path = tempdir.path().join("bootstrap-trace.json");
285+
let file = BufWriter::new(File::create(&chrome_tracing_path).unwrap());
273286

274-
let (chrome_layer, _guard) = chrome_layer.build();
287+
let chrome_layer =
288+
tracing_chrome::ChromeLayerBuilder::new().writer(file).include_args(true);
289+
let (chrome_layer, guard) = chrome_layer.build();
275290

276-
let registry =
277-
tracing_subscriber::registry().with(filter).with(ForestLayer::default()).with(chrome_layer);
291+
tracing::subscriber::set_global_default(registry.with(chrome_layer)).unwrap();
292+
Some(TracingGuard { guard, _tempdir: tempdir, chrome_tracing_path })
293+
} else {
294+
tracing::subscriber::set_global_default(registry).unwrap();
295+
None
296+
};
278297

279-
tracing::subscriber::set_global_default(registry).unwrap();
280-
_guard
298+
guard
299+
}
300+
301+
#[cfg(feature = "tracing")]
302+
struct TracingGuard {
303+
guard: tracing_chrome::FlushGuard,
304+
_tempdir: tempfile::TempDir,
305+
chrome_tracing_path: std::path::PathBuf,
306+
}
307+
308+
#[cfg(feature = "tracing")]
309+
impl TracingGuard {
310+
fn copy_to_dir(self, dir: &std::path::Path) {
311+
drop(self.guard);
312+
std::fs::rename(&self.chrome_tracing_path, dir.join("chrome-trace.json")).unwrap();
313+
}
281314
}

0 commit comments

Comments
 (0)