Skip to content

Commit e72e49a

Browse files
authored
Rollup merge of #136091 - jieyouxu:core-tracing, r=clubby789
Add some tracing to core bootstrap logic Follow-up to #135391. ### Summary Add some initial tracing logging to bootstrap, focused on the core logic (in this PR). Also: - Adjusted tracing-tree style to not use indent lines (I found that more distracting than helpful). - Avoid glob-importing `tracing` items. - Improve the rustc-dev-guide docs on bootstrap tracing. ### Example output ```bash $ BOOTSTRAP_TRACING=bootstrap=TRACE ./x check src/bootstrap ``` ![Example bootstrap tracing output](https://github.com/user-attachments/assets/0be39042-0822-44b6-9451-30427cfea156) r? bootstrap
2 parents bd2f6d7 + 97efda6 commit e72e49a

File tree

6 files changed

+165
-50
lines changed

6 files changed

+165
-50
lines changed

src/bootstrap/src/bin/main.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@ use bootstrap::{
1616
};
1717
use build_helper::ci::CiEnv;
1818
#[cfg(feature = "tracing")]
19-
use tracing::*;
20-
#[cfg(feature = "tracing")]
21-
use tracing_subscriber::EnvFilter;
22-
#[cfg(feature = "tracing")]
23-
use tracing_subscriber::prelude::*;
19+
use tracing::{debug, instrument};
2420

2521
#[cfg_attr(feature = "tracing", instrument(level = "trace", name = "main"))]
2622
fn main() {
@@ -33,7 +29,11 @@ fn main() {
3329
return;
3430
}
3531

32+
#[cfg(feature = "tracing")]
33+
debug!("parsing flags");
3634
let flags = Flags::parse(&args);
35+
#[cfg(feature = "tracing")]
36+
debug!("parsing config based on flags");
3737
let config = Config::parse(flags);
3838

3939
let mut build_lock;
@@ -95,6 +95,8 @@ fn main() {
9595
let dump_bootstrap_shims = config.dump_bootstrap_shims;
9696
let out_dir = config.out.clone();
9797

98+
#[cfg(feature = "tracing")]
99+
debug!("creating new build based on config");
98100
Build::new(config).build();
99101

100102
if suggest_setup {
@@ -211,16 +213,14 @@ fn check_version(config: &Config) -> Option<String> {
211213
// "tracing", instrument(..))]`.
212214
#[cfg(feature = "tracing")]
213215
fn setup_tracing() {
216+
use tracing_subscriber::EnvFilter;
217+
use tracing_subscriber::layer::SubscriberExt;
218+
214219
let filter = EnvFilter::from_env("BOOTSTRAP_TRACING");
215-
let layer = tracing_tree::HierarchicalLayer::default()
216-
.with_writer(std::io::stderr)
217-
.with_ansi(true)
218-
.with_targets(true)
219-
.with_bracketed_fields(true)
220-
.with_indent_amount(2)
221-
.with_indent_lines(true);
222-
let subscriber = tracing_subscriber::registry().with(filter).with(layer);
223-
224-
tracing::subscriber::set_global_default(subscriber).unwrap();
225-
trace!("tracing subscriber setup");
220+
// cf. <https://docs.rs/tracing-tree/latest/tracing_tree/struct.HierarchicalLayer.html>.
221+
let layer = tracing_tree::HierarchicalLayer::default().with_targets(true).with_indent_amount(2);
222+
223+
let registry = tracing_subscriber::registry().with(filter).with(layer);
224+
225+
tracing::subscriber::set_global_default(registry).unwrap();
226226
}

src/bootstrap/src/core/config/config.rs

+46-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ use build_helper::exit;
1818
use build_helper::git::{GitConfig, get_closest_merge_commit, output_result};
1919
use serde::{Deserialize, Deserializer};
2020
use serde_derive::Deserialize;
21+
#[cfg(feature = "tracing")]
22+
use tracing::{instrument, span};
2123

2224
use crate::core::build_steps::compile::CODEGEN_BACKEND_PREFIX;
2325
use crate::core::build_steps::llvm;
@@ -1227,7 +1229,14 @@ define_config! {
12271229
}
12281230

12291231
impl Config {
1232+
#[cfg_attr(
1233+
feature = "tracing",
1234+
instrument(target = "CONFIG_HANDLING", level = "trace", name = "Config::default_opts")
1235+
)]
12301236
pub fn default_opts() -> Config {
1237+
#[cfg(feature = "tracing")]
1238+
span!(target: "CONFIG_HANDLING", tracing::Level::TRACE, "constructing default config");
1239+
12311240
Config {
12321241
bypass_bootstrap_lock: false,
12331242
llvm_optimize: true,
@@ -1311,10 +1320,23 @@ impl Config {
13111320
})
13121321
}
13131322

1323+
#[cfg_attr(
1324+
feature = "tracing",
1325+
instrument(target = "CONFIG_HANDLING", level = "trace", name = "Config::parse", skip_all)
1326+
)]
13141327
pub fn parse(flags: Flags) -> Config {
13151328
Self::parse_inner(flags, Self::get_toml)
13161329
}
13171330

1331+
#[cfg_attr(
1332+
feature = "tracing",
1333+
instrument(
1334+
target = "CONFIG_HANDLING",
1335+
level = "trace",
1336+
name = "Config::parse_inner",
1337+
skip_all
1338+
)
1339+
)]
13181340
pub(crate) fn parse_inner(
13191341
mut flags: Flags,
13201342
get_toml: impl Fn(&Path) -> Result<TomlConfig, toml::de::Error>,
@@ -1323,6 +1345,17 @@ impl Config {
13231345

13241346
// Set flags.
13251347
config.paths = std::mem::take(&mut flags.paths);
1348+
1349+
#[cfg(feature = "tracing")]
1350+
span!(
1351+
target: "CONFIG_HANDLING",
1352+
tracing::Level::TRACE,
1353+
"collecting paths and path exclusions",
1354+
"flags.paths" = ?flags.paths,
1355+
"flags.skip" = ?flags.skip,
1356+
"flags.exclude" = ?flags.exclude
1357+
);
1358+
13261359
config.skip = flags
13271360
.skip
13281361
.into_iter()
@@ -1339,6 +1372,14 @@ impl Config {
13391372
})
13401373
.collect();
13411374

1375+
#[cfg(feature = "tracing")]
1376+
span!(
1377+
target: "CONFIG_HANDLING",
1378+
tracing::Level::TRACE,
1379+
"normalizing and combining `flag.skip`/`flag.exclude` paths",
1380+
"config.skip" = ?config.skip,
1381+
);
1382+
13421383
config.include_default_paths = flags.include_default_paths;
13431384
config.rustc_error_format = flags.rustc_error_format;
13441385
config.json_output = flags.json_output;
@@ -1418,7 +1459,11 @@ impl Config {
14181459

14191460
config.stage0_metadata = build_helper::stage0_parser::parse_stage0_file();
14201461

1421-
// Read from `--config`, then `RUST_BOOTSTRAP_CONFIG`, then `./config.toml`, then `config.toml` in the root directory.
1462+
// Find configuration file, with the following cascading fallback (first match wins):
1463+
// - `--config <path>`
1464+
// - `RUST_BOOTSTRAP_CONFIG`
1465+
// - `./config.toml`
1466+
// - `config.toml` in the root directory.
14221467
let toml_path = flags
14231468
.config
14241469
.clone()

src/bootstrap/src/core/config/flags.rs

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
use std::path::{Path, PathBuf};
77

88
use clap::{CommandFactory, Parser, ValueEnum};
9+
#[cfg(feature = "tracing")]
10+
use tracing::instrument;
911

1012
use crate::core::build_steps::setup::Profile;
1113
use crate::core::builder::{Builder, Kind};
@@ -211,6 +213,10 @@ impl Flags {
211213
}
212214
}
213215

216+
#[cfg_attr(
217+
feature = "tracing",
218+
instrument(level = "trace", name = "Flags::parse", skip_all, fields(args = ?args))
219+
)]
214220
pub fn parse(args: &[String]) -> Self {
215221
Flags::parse_from(normalize_args(args))
216222
}

src/bootstrap/src/lib.rs

+39-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ use std::{env, fs, io, str};
2828
use build_helper::ci::gha;
2929
use build_helper::exit;
3030
use termcolor::{ColorChoice, StandardStream, WriteColor};
31+
#[cfg(feature = "tracing")]
32+
use tracing::{debug, instrument, span, trace};
3133
use utils::build_stamp::BuildStamp;
3234
use utils::channel::GitInfo;
3335

@@ -537,14 +539,25 @@ impl Build {
537539
}
538540

539541
/// Executes the entire build, as configured by the flags and configuration.
542+
#[cfg_attr(feature = "tracing", instrument(level = "debug", name = "Build::build", skip_all))]
540543
pub fn build(&mut self) {
544+
#[cfg(feature = "tracing")]
545+
trace!("setting up job management");
541546
unsafe {
542547
crate::utils::job::setup(self);
543548
}
544549

550+
#[cfg(feature = "tracing")]
551+
trace!("downloading rustfmt early");
552+
545553
// Download rustfmt early so that it can be used in rust-analyzer configs.
546554
let _ = &builder::Builder::new(self).initial_rustfmt();
547555

556+
#[cfg(feature = "tracing")]
557+
let hardcoded_span =
558+
span!(tracing::Level::DEBUG, "handling hardcoded subcommands (Format, Suggest, Perf)")
559+
.entered();
560+
548561
// hardcoded subcommands
549562
match &self.config.cmd {
550563
Subcommand::Format { check, all } => {
@@ -561,25 +574,50 @@ impl Build {
561574
Subcommand::Perf { .. } => {
562575
return core::build_steps::perf::perf(&builder::Builder::new(self));
563576
}
564-
_ => (),
577+
_cmd => {
578+
#[cfg(feature = "tracing")]
579+
debug!(cmd = ?_cmd, "not a hardcoded subcommand; returning to normal handling");
580+
}
565581
}
566582

583+
#[cfg(feature = "tracing")]
584+
drop(hardcoded_span);
585+
#[cfg(feature = "tracing")]
586+
debug!("handling subcommand normally");
587+
567588
if !self.config.dry_run() {
589+
#[cfg(feature = "tracing")]
590+
let _real_run_span = span!(tracing::Level::DEBUG, "executing real run").entered();
591+
568592
{
593+
#[cfg(feature = "tracing")]
594+
let _sanity_check_span =
595+
span!(tracing::Level::DEBUG, "(1) executing dry-run sanity-check").entered();
596+
569597
// We first do a dry-run. This is a sanity-check to ensure that
570598
// steps don't do anything expensive in the dry-run.
571599
self.config.dry_run = DryRun::SelfCheck;
572600
let builder = builder::Builder::new(self);
573601
builder.execute_cli();
574602
}
603+
604+
#[cfg(feature = "tracing")]
605+
let _actual_run_span =
606+
span!(tracing::Level::DEBUG, "(2) executing actual run").entered();
575607
self.config.dry_run = DryRun::Disabled;
576608
let builder = builder::Builder::new(self);
577609
builder.execute_cli();
578610
} else {
611+
#[cfg(feature = "tracing")]
612+
let _dry_run_span = span!(tracing::Level::DEBUG, "executing dry run").entered();
613+
579614
let builder = builder::Builder::new(self);
580615
builder.execute_cli();
581616
}
582617

618+
#[cfg(feature = "tracing")]
619+
debug!("checking for postponed test failures from `test --no-fail-fast`");
620+
583621
// Check for postponed failures from `test --no-fail-fast`.
584622
let failures = self.delayed_failures.borrow();
585623
if failures.len() > 0 {

src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md

+58-32
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Debugging bootstrap
22

3-
> FIXME: this page could be expanded
3+
> FIXME: this section should be expanded
44
55
## `tracing` in bootstrap
66

@@ -10,21 +10,69 @@ Bootstrap has conditional [`tracing`][tracing] setup to provide structured loggi
1010

1111
### Enabling `tracing` output
1212

13-
Bootstrap will conditionally enable `tracing` output if the `BOOTSTRAP_TRACING` env var is set.
13+
Bootstrap will conditionally build `tracing` support and enable `tracing` output if the `BOOTSTRAP_TRACING` env var is set.
1414

15-
Example usage:
15+
#### Basic usage
16+
17+
Example basic usage[^just-trace]:
18+
19+
[^just-trace]: It is not recommend to use *just* `BOOTSTRAP_TRACING=TRACE` because that will dump *everything* at `TRACE` level, including logs intentionally gated behind custom targets as they are too verbose even for `TRACE` level by default.
1620

1721
```bash
18-
$ BOOTSTRAP_TRACING=TRACE ./x build library --stage 1
22+
$ BOOTSTRAP_TRACING=bootstrap=TRACE ./x build library --stage 1
23+
```
24+
25+
Example output[^unstable]:
26+
27+
```
28+
$ BOOTSTRAP_TRACING=bootstrap=TRACE ./x check src/bootstrap/
29+
Building bootstrap
30+
Compiling bootstrap v0.0.0 (/home/joe/repos/rust/src/bootstrap)
31+
Finished `dev` profile [unoptimized] target(s) in 2.74s
32+
DEBUG bootstrap parsing flags
33+
bootstrap::core::config::flags::Flags::parse args=["check", "src/bootstrap/"]
34+
DEBUG bootstrap parsing config based on flags
35+
DEBUG bootstrap creating new build based on config
36+
bootstrap::Build::build
37+
TRACE bootstrap setting up job management
38+
TRACE bootstrap downloading rustfmt early
39+
bootstrap::handling hardcoded subcommands (Format, Suggest, Perf)
40+
DEBUG bootstrap not a hardcoded subcommand; returning to normal handling, cmd=Check { all_targets: false }
41+
DEBUG bootstrap handling subcommand normally
42+
bootstrap::executing real run
43+
bootstrap::(1) executing dry-run sanity-check
44+
bootstrap::(2) executing actual run
45+
Checking stage0 library artifacts (x86_64-unknown-linux-gnu)
46+
Finished `release` profile [optimized + debuginfo] target(s) in 0.04s
47+
Checking stage0 compiler artifacts {rustc-main, rustc_abi, rustc_arena, rustc_ast, rustc_ast_ir, rustc_ast_lowering, rustc_ast_passes, rustc_ast_pretty, rustc_attr_data_structures, rustc_attr_parsing, rustc_baked_icu_data, rustc_borrowck, rustc_builtin_macros, rustc_codegen_llvm, rustc_codegen_ssa, rustc_const_eval, rustc_data_structures, rustc_driver, rustc_driver_impl, rustc_error_codes, rustc_error_messages, rustc_errors, rustc_expand, rustc_feature, rustc_fluent_macro, rustc_fs_util, rustc_graphviz, rustc_hir, rustc_hir_analysis, rustc_hir_pretty, rustc_hir_typeck, rustc_incremental, rustc_index, rustc_index_macros, rustc_infer, rustc_interface, rustc_lexer, rustc_lint, rustc_lint_defs, rustc_llvm, rustc_log, rustc_macros, rustc_metadata, rustc_middle, rustc_mir_build, rustc_mir_dataflow, rustc_mir_transform, rustc_monomorphize, rustc_next_trait_solver, rustc_parse, rustc_parse_format, rustc_passes, rustc_pattern_analysis, rustc_privacy, rustc_query_impl, rustc_query_system, rustc_resolve, rustc_sanitizers, rustc_serialize, rustc_session, rustc_smir, rustc_span, rustc_symbol_mangling, rustc_target, rustc_trait_selection, rustc_traits, rustc_transmute, rustc_ty_utils, rustc_type_ir, rustc_type_ir_macros, stable_mir} (x86_64-unknown-linux-gnu)
48+
Finished `release` profile [optimized + debuginfo] target(s) in 0.23s
49+
Checking stage0 bootstrap artifacts (x86_64-unknown-linux-gnu)
50+
Checking bootstrap v0.0.0 (/home/joe/repos/rust/src/bootstrap)
51+
Finished `release` profile [optimized + debuginfo] target(s) in 0.64s
52+
DEBUG bootstrap checking for postponed test failures from `test --no-fail-fast`
53+
Build completed successfully in 0:00:08
1954
```
2055

21-
Example output[^experimental]:
56+
#### Controlling log output
57+
58+
The env var `BOOTSTRAP_TRACING` accepts a [`tracing` env-filter][tracing-env-filter].
59+
60+
There are two orthogonal ways to control which kind of logs you want:
2261

23-
![Example bootstrap tracing output](./debugging-bootstrap/tracing-output-example.png)
62+
1. You can specify the log **level**, e.g. `DEBUG` or `TRACE`.
63+
2. You can also control the log **target**, e.g. `bootstrap` or `bootstrap::core::config` vs custom targets like `CONFIG_HANDLING`.
64+
- Custom targets are used to limit what is output when `BOOTSTRAP_TRACING=bootstrap=TRACE` is used, as they can be too verbose even for `TRACE` level by default. Currently used custom targets:
65+
- `CONFIG_HANDLING`
2466

25-
[^experimental]: This shows what's *possible* with the infra in an experimental implementation.
67+
The `TRACE` filter will enable *all* `trace` level or less verbose level tracing output.
2668

27-
The env var `BOOTSTRAP_TRACING` accepts a [`tracing` env-filter][tracing-env-filter]. The `TRACE` filter will enable *all* `trace` level or less verbose level tracing output.
69+
You can of course combine them (custom target logs are typically gated behind `TRACE` log level additionally):
70+
71+
```bash
72+
$ BOOTSTRAP_TRACING=CONFIG_HANDLING=TRACE ./x build library --stage 1
73+
```
74+
75+
[^unstable]: This output is always subject to further changes.
2876

2977
[tracing-env-filter]: https://docs.rs/tracing-subscriber/0.3.19/tracing_subscriber/filter/struct.EnvFilter.html
3078

@@ -73,28 +121,6 @@ For `#[instrument]`, it's recommended to:
73121
- Explicitly pick an instrumentation name via `name = ".."` to distinguish between e.g. `run` of different steps.
74122
- Take care to not cause diverging behavior via tracing, e.g. building extra things only when tracing infra is enabled.
75123

76-
### Enabling `tracing` bootstrap feature in rust-analyzer
124+
### rust-analyzer integration?
77125

78-
You can adjust your `settings.json`'s `rust-analyzer.check.overrideCommand` and `rust-analyzer.cargo.buildScripts.overrideCommand` if you want to also enable `logging` cargo feature by default in your editor. This is mostly useful if you want proper r-a completions and such when working on bootstrap itself.
79-
80-
```json
81-
"rust-analyzer.check.overrideCommand": [
82-
"BOOTSTRAP_TRACING=1", // <- BOOTSTRAP_TRACING=1 won't enable tracing filter, but it will activate bootstrap's `tracing` feature
83-
"python3",
84-
"x.py",
85-
"check",
86-
"--json-output",
87-
"--build-dir=build-rust-analyzer"
88-
],
89-
```
90-
91-
```json
92-
"rust-analyzer.cargo.buildScripts.overrideCommand": [
93-
"BOOTSTRAP_TRACING=1", // <- note this
94-
"python3",
95-
"x.py",
96-
"check",
97-
"--json-output",
98-
"--build-dir=build-rust-analyzer"
99-
],
100-
```
126+
Unfortunately, because bootstrap is a `rust-analyzer.linkedProjects`, you can't ask r-a to check/build bootstrap itself with `tracing` feature enabled to get relevant completions, due to lack of support as described in <https://github.com/rust-lang/rust-analyzer/issues/8521>.

0 commit comments

Comments
 (0)