Skip to content

Conversation

@weihanglo
Copy link
Member

@weihanglo weihanglo commented Dec 11, 2025

What does this PR try to resolve?

This implements cargo report timings HTML replay feature.

The help text looks like:

Reports the build timings of previous builds (unstable)

Usage: cargo report timings [OPTIONS]

Options:
      --open              Opens the timing report in a browser
      ...

Part of #15844

How to test and review this PR?

Open questions:

  • The replayed HTML report will be written to
    • If in a Cargo workspace, write to <artifact-dir>/cargo-timings/
    • Otherwise, write to a temp directory
  • The log discovery logic
    • Currently look at the newest log file for the workspace.
    • If not in a workspace, pick the newest log file in the log directory.
  • Snapshots HTML report and log files are added.
    • They are huge in size. Should we not do this?
    • Benefit: HTML snapshots help us know better when it is broken

Things left (but should do it follow-up PRs)

  • cargo help hasn't yet worked with with nested commands.
  • There are some more information required by HTML report, but these don't affect the major use of the report IMO.

@weihanglo weihanglo added the Z-build-analysis Nightly: build-analysis label Dec 11, 2025
@rustbot
Copy link
Collaborator

rustbot commented Dec 11, 2025

r? @epage

rustbot has assigned @epage.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added A-build-execution Area: anything dealing with executing the compiler A-cli Area: Command-line interface, option parsing, etc. A-testing-cargo-itself Area: cargo's tests A-timings Area: timings Command-report S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 11, 2025
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you running a mac and have that gatekeeper performance issue?

Interesting to see the impact of linking of build scripts

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah but not my personal machine 😞.
(technically possible but may not be allowed to)

Comment on lines +217 to +244
// This is pretty similar to how the current `core::compiler::timings`
// renders `core::manifest::Target`. However, our target is
// a simplified type so we cannot reuse the same logic here.
let mut target_str = if target.kind == "lib" && mode == CompileMode::Build {
// Special case for brevity, since most dependencies hit this path.
"".to_string()
} else if target.kind == "build-script" {
" build-script".to_string()
} else {
format!(r#" {} "{}""#, target.name, target.kind)
};

match mode {
CompileMode::Test => target_str.push_str(" (test)"),
CompileMode::Build => {}
CompileMode::Check { test: true } => target_str.push_str(" (check-test)"),
CompileMode::Check { test: false } => target_str.push_str(" (check)"),
CompileMode::Doc { .. } => target_str.push_str(" (doc)"),
CompileMode::Doctest => target_str.push_str(" (doc test)"),
CompileMode::Docscrape => target_str.push_str(" (doc scrape)"),
CompileMode::RunCustomBuild => target_str.push_str(" (run)"),
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably want to reconsider using the old cargo::core::Target struct instead of the new simplified one.

Or better, HTML from --timings should be generated by in-memory log message, so that we don't need to have two parallel implementations doing the same thing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or better, HTML from --timings should be generated by in-memory log message, so that we don't need to have two parallel implementations doing the same thing.

Would love to switch to something like that. Also, working to deprecate --timings

TempDir::with_prefix("cargo-timings-")?.keep()
};

let timing_path = reports_dir.join(format!("cargo-timing-{run_id}.html"));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might also want to change the output HTML path of --timings, though I am not sure if it is a part of stable interface. I guess not?

  • cargo-timing-20251211T043934.741441Z.html -> --timing timestamp-based file name
  • cargo-timing-2025-12-11T044138699Z-a2f1dccc7ac1667a.html -> RunId-based file name

@eth3lbert
Copy link
Contributor

eth3lbert commented Dec 11, 2025

I haven't taken a review yet, and this is not a blocker, but I'm wondering if it's possible to provide an HTML page that allows users to select a JSON(L) file for rendering (something similar to profiler.firefox.com or speedscope). This would be a more general solution that separates the presentation from the data, preventing the data from being embedded directly in the HTML. The implementation probably wouldn't need to be in Cargo itself. Some drawbacks are that it might require migrating some of the logic from Rust to frontend, and we'd likely need some setup to make it testable.

@epage
Copy link
Contributor

epage commented Dec 11, 2025

I haven't taken a review yet, and this is not a blocker, but I'm wondering if it's possible to provide an HTML page that allows users to select a JSON(L) file for rendering (something similar to profiler.firefox.com or speedscope). This would be a more general solution that separates the presentation from the data, preventing the data from being embedded directly in the HTML. The implementation probably wouldn't need to be in Cargo itself. Some drawbacks are that it might require migrating some of the logic from Rust to frontend, and we'd likely need some setup to make it testable.

This would be dependent on stabilizing the json

@weihanglo
Copy link
Member Author

…but I'm wondering if it's possible to provide an HTML page that allows users to select a JSON(L) file for rendering (something similar to profiler.firefox.com or speedscope)…

This will be nice and actually the entire prepare_context can be ported to JavaScript. Though like epage said, we need a stable interface that Cargo controls. I would love to see --timing entirely generated from in-memory log message on stable Cargo (this doesn't requires JSON schema stabilization, more a internal refactor #16377 (comment))

github-merge-queue bot pushed a commit that referenced this pull request Dec 11, 2025
### What does this PR try to resolve?

Factored out of <#16377>.
This makes data more self-contained.

### How to test and review this PR?
@rustbot

This comment has been minimized.

@weihanglo weihanglo force-pushed the report-timings branch 3 times, most recently from 5a1d7eb to a2cb338 Compare December 12, 2025 01:06
Currently look at the newest log file for the workspace.
If not in a workspace, pick the newest log file in the log directory.
This implements `cargo report timings` HTML replay feature.

The help text looks like:

```
Reports the build timings of previous builds (unstable)

Usage: cargo report timings [OPTIONS]

Options:
      --open              Opens the timing report in a browser
      ...
```

The replayed HTML report will be written to

* If in a Cargo workspace, write to `<artifact-dir>/cargo-timings/`
* Otherwise, write to a temp directory

The log discovery logic

* Currently look at the newest log file for the workspace.
* If not in a workspace, pick the newest log file in the log directory.
This adds a log file generated by

```
cargod build --timings  -Zsection-timings -p cargo-util-schemas
```

With this we can track what changed in HTML report.
@rustbot
Copy link
Collaborator

rustbot commented Dec 12, 2025

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

Copy link
Contributor

@epage epage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@epage epage enabled auto-merge December 12, 2025 22:48
@epage epage added this pull request to the merge queue Dec 12, 2025
Merged via the queue into rust-lang:master with commit c46423d Dec 12, 2025
28 checks passed
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Dec 12, 2025
bors added a commit to rust-lang/rust that referenced this pull request Dec 13, 2025
Update cargo submodule

27 commits in 2c283a9a5c5968eeb9a8f12313f04feb1ff8dfac..c46423de7351e3c4c734b2faa86088a9f5d1302b
2025-12-04 16:47:28 +0000 to 2025-12-12 23:16:12 +0000
- feat(report): cargo report timings HTML replay (rust-lang/cargo#16377)
- feat: stabilize `-Zconfig-include` (rust-lang/cargo#16284)
- fix(package): Don't verify registry for --list  (rust-lang/cargo#16341)
- Fixed incorrect locking logic when artifact-dir == build-dir (rust-lang/cargo#16385)
- feat(log): make timing messages ready for HTML replay (rust-lang/cargo#16382)
- chore(deps): update msrv (1 version) to v1.92 (rust-lang/cargo#16381)
- Downgrade curl-sys to 0.4.83 (rust-lang/cargo#16379)
- fix(timing): more self-contained timing/log data (rust-lang/cargo#16378)
- test: update to `proc_macro::tracked::path` (rust-lang/cargo#16380)
- refactor(lint): move lints to separate modules (rust-lang/cargo#16364)
- fix(index): Apply feedback from Cargo team (rust-lang/cargo#16369)
- fix(lints): handle lints separately at ws pkg level  (rust-lang/cargo#16367)
- feat(lint): new `implicit_minimum_version_req` lint (rust-lang/cargo#16321)
- fix(info): default to local without explicit reg (rust-lang/cargo#16358)
- Remove `[no-mentions]` handler in our triagebot config (rust-lang/cargo#16361)
- Don't read the config file twice when $CARGO_HOME is a symlink (rust-lang/cargo#16325)
- fix(timings): forgot to negate filter (rust-lang/cargo#16352)
- fix(doctest): Include all search paths with new build layout  (rust-lang/cargo#16348)
- fix(layout): Remove hashes from bins in new layout  (rust-lang/cargo#16351)
- docs(faq): Include an entry on disk space (rust-lang/cargo#16349)
- feat(timings): derive concurrency data from unit data (rust-lang/cargo#16350)
- perf(layout): Use unit_id, not pkg hash, for bin/lib pkg_dirs for new layout (rust-lang/cargo#16345)
- Validate target source paths before compilation with clearer errors (rust-lang/cargo#16338)
- test(doc): Remove unused build script (rust-lang/cargo#16344)
- refactor(timings): store UnitData in RenderContext instead  (rust-lang/cargo#16346)
- perf(clean): Optimize (legacy) clean with multiple -p specifiers (rust-lang/cargo#16264)
- test: Adjust output for out-of-tree build-dir (rust-lang/cargo#16343)
bors added a commit to rust-lang/rust that referenced this pull request Dec 13, 2025
Update cargo submodule

29 commits in 2c283a9a5c5968eeb9a8f12313f04feb1ff8dfac..e91b2baa632c0c7e84216c91ecfe107c37d887c1
2025-12-04 16:47:28 +0000 to 2025-12-13 16:29:21 +0000
- refactor(lints): move from cargo::util::lints to cargo::lints (rust-lang/cargo#16392)
- test(lint): redact more due to line got omitted (rust-lang/cargo#16391)
- feat(report): cargo report timings HTML replay (rust-lang/cargo#16377)
- feat: stabilize `-Zconfig-include` (rust-lang/cargo#16284)
- fix(package): Don't verify registry for --list  (rust-lang/cargo#16341)
- Fixed incorrect locking logic when artifact-dir == build-dir (rust-lang/cargo#16385)
- feat(log): make timing messages ready for HTML replay (rust-lang/cargo#16382)
- chore(deps): update msrv (1 version) to v1.92 (rust-lang/cargo#16381)
- Downgrade curl-sys to 0.4.83 (rust-lang/cargo#16379)
- fix(timing): more self-contained timing/log data (rust-lang/cargo#16378)
- test: update to `proc_macro::tracked::path` (rust-lang/cargo#16380)
- refactor(lint): move lints to separate modules (rust-lang/cargo#16364)
- fix(index): Apply feedback from Cargo team (rust-lang/cargo#16369)
- fix(lints): handle lints separately at ws pkg level  (rust-lang/cargo#16367)
- feat(lint): new `implicit_minimum_version_req` lint (rust-lang/cargo#16321)
- fix(info): default to local without explicit reg (rust-lang/cargo#16358)
- Remove `[no-mentions]` handler in our triagebot config (rust-lang/cargo#16361)
- Don't read the config file twice when $CARGO_HOME is a symlink (rust-lang/cargo#16325)
- fix(timings): forgot to negate filter (rust-lang/cargo#16352)
- fix(doctest): Include all search paths with new build layout  (rust-lang/cargo#16348)
- fix(layout): Remove hashes from bins in new layout  (rust-lang/cargo#16351)
- docs(faq): Include an entry on disk space (rust-lang/cargo#16349)
- feat(timings): derive concurrency data from unit data (rust-lang/cargo#16350)
- perf(layout): Use unit_id, not pkg hash, for bin/lib pkg_dirs for new layout (rust-lang/cargo#16345)
- Validate target source paths before compilation with clearer errors (rust-lang/cargo#16338)
- test(doc): Remove unused build script (rust-lang/cargo#16344)
- refactor(timings): store UnitData in RenderContext instead  (rust-lang/cargo#16346)
- perf(clean): Optimize (legacy) clean with multiple -p specifiers (rust-lang/cargo#16264)
- test: Adjust output for out-of-tree build-dir (rust-lang/cargo#16343)
@rustbot rustbot added this to the 1.94.0 milestone Dec 13, 2025
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Dec 14, 2025
Update cargo submodule

29 commits in 2c283a9a5c5968eeb9a8f12313f04feb1ff8dfac..e91b2baa632c0c7e84216c91ecfe107c37d887c1
2025-12-04 16:47:28 +0000 to 2025-12-13 16:29:21 +0000
- refactor(lints): move from cargo::util::lints to cargo::lints (rust-lang/cargo#16392)
- test(lint): redact more due to line got omitted (rust-lang/cargo#16391)
- feat(report): cargo report timings HTML replay (rust-lang/cargo#16377)
- feat: stabilize `-Zconfig-include` (rust-lang/cargo#16284)
- fix(package): Don't verify registry for --list  (rust-lang/cargo#16341)
- Fixed incorrect locking logic when artifact-dir == build-dir (rust-lang/cargo#16385)
- feat(log): make timing messages ready for HTML replay (rust-lang/cargo#16382)
- chore(deps): update msrv (1 version) to v1.92 (rust-lang/cargo#16381)
- Downgrade curl-sys to 0.4.83 (rust-lang/cargo#16379)
- fix(timing): more self-contained timing/log data (rust-lang/cargo#16378)
- test: update to `proc_macro::tracked::path` (rust-lang/cargo#16380)
- refactor(lint): move lints to separate modules (rust-lang/cargo#16364)
- fix(index): Apply feedback from Cargo team (rust-lang/cargo#16369)
- fix(lints): handle lints separately at ws pkg level  (rust-lang/cargo#16367)
- feat(lint): new `implicit_minimum_version_req` lint (rust-lang/cargo#16321)
- fix(info): default to local without explicit reg (rust-lang/cargo#16358)
- Remove `[no-mentions]` handler in our triagebot config (rust-lang/cargo#16361)
- Don't read the config file twice when $CARGO_HOME is a symlink (rust-lang/cargo#16325)
- fix(timings): forgot to negate filter (rust-lang/cargo#16352)
- fix(doctest): Include all search paths with new build layout  (rust-lang/cargo#16348)
- fix(layout): Remove hashes from bins in new layout  (rust-lang/cargo#16351)
- docs(faq): Include an entry on disk space (rust-lang/cargo#16349)
- feat(timings): derive concurrency data from unit data (rust-lang/cargo#16350)
- perf(layout): Use unit_id, not pkg hash, for bin/lib pkg_dirs for new layout (rust-lang/cargo#16345)
- Validate target source paths before compilation with clearer errors (rust-lang/cargo#16338)
- test(doc): Remove unused build script (rust-lang/cargo#16344)
- refactor(timings): store UnitData in RenderContext instead  (rust-lang/cargo#16346)
- perf(clean): Optimize (legacy) clean with multiple -p specifiers (rust-lang/cargo#16264)
- test: Adjust output for out-of-tree build-dir (rust-lang/cargo#16343)
github-actions bot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Dec 15, 2025
Update cargo submodule

29 commits in 2c283a9a5c5968eeb9a8f12313f04feb1ff8dfac..e91b2baa632c0c7e84216c91ecfe107c37d887c1
2025-12-04 16:47:28 +0000 to 2025-12-13 16:29:21 +0000
- refactor(lints): move from cargo::util::lints to cargo::lints (rust-lang/cargo#16392)
- test(lint): redact more due to line got omitted (rust-lang/cargo#16391)
- feat(report): cargo report timings HTML replay (rust-lang/cargo#16377)
- feat: stabilize `-Zconfig-include` (rust-lang/cargo#16284)
- fix(package): Don't verify registry for --list  (rust-lang/cargo#16341)
- Fixed incorrect locking logic when artifact-dir == build-dir (rust-lang/cargo#16385)
- feat(log): make timing messages ready for HTML replay (rust-lang/cargo#16382)
- chore(deps): update msrv (1 version) to v1.92 (rust-lang/cargo#16381)
- Downgrade curl-sys to 0.4.83 (rust-lang/cargo#16379)
- fix(timing): more self-contained timing/log data (rust-lang/cargo#16378)
- test: update to `proc_macro::tracked::path` (rust-lang/cargo#16380)
- refactor(lint): move lints to separate modules (rust-lang/cargo#16364)
- fix(index): Apply feedback from Cargo team (rust-lang/cargo#16369)
- fix(lints): handle lints separately at ws pkg level  (rust-lang/cargo#16367)
- feat(lint): new `implicit_minimum_version_req` lint (rust-lang/cargo#16321)
- fix(info): default to local without explicit reg (rust-lang/cargo#16358)
- Remove `[no-mentions]` handler in our triagebot config (rust-lang/cargo#16361)
- Don't read the config file twice when $CARGO_HOME is a symlink (rust-lang/cargo#16325)
- fix(timings): forgot to negate filter (rust-lang/cargo#16352)
- fix(doctest): Include all search paths with new build layout  (rust-lang/cargo#16348)
- fix(layout): Remove hashes from bins in new layout  (rust-lang/cargo#16351)
- docs(faq): Include an entry on disk space (rust-lang/cargo#16349)
- feat(timings): derive concurrency data from unit data (rust-lang/cargo#16350)
- perf(layout): Use unit_id, not pkg hash, for bin/lib pkg_dirs for new layout (rust-lang/cargo#16345)
- Validate target source paths before compilation with clearer errors (rust-lang/cargo#16338)
- test(doc): Remove unused build script (rust-lang/cargo#16344)
- refactor(timings): store UnitData in RenderContext instead  (rust-lang/cargo#16346)
- perf(clean): Optimize (legacy) clean with multiple -p specifiers (rust-lang/cargo#16264)
- test: Adjust output for out-of-tree build-dir (rust-lang/cargo#16343)
Kobzol pushed a commit to Kobzol/rustc_codegen_gcc that referenced this pull request Dec 21, 2025
Update cargo submodule

29 commits in 2c283a9a5c5968eeb9a8f12313f04feb1ff8dfac..e91b2baa632c0c7e84216c91ecfe107c37d887c1
2025-12-04 16:47:28 +0000 to 2025-12-13 16:29:21 +0000
- refactor(lints): move from cargo::util::lints to cargo::lints (rust-lang/cargo#16392)
- test(lint): redact more due to line got omitted (rust-lang/cargo#16391)
- feat(report): cargo report timings HTML replay (rust-lang/cargo#16377)
- feat: stabilize `-Zconfig-include` (rust-lang/cargo#16284)
- fix(package): Don't verify registry for --list  (rust-lang/cargo#16341)
- Fixed incorrect locking logic when artifact-dir == build-dir (rust-lang/cargo#16385)
- feat(log): make timing messages ready for HTML replay (rust-lang/cargo#16382)
- chore(deps): update msrv (1 version) to v1.92 (rust-lang/cargo#16381)
- Downgrade curl-sys to 0.4.83 (rust-lang/cargo#16379)
- fix(timing): more self-contained timing/log data (rust-lang/cargo#16378)
- test: update to `proc_macro::tracked::path` (rust-lang/cargo#16380)
- refactor(lint): move lints to separate modules (rust-lang/cargo#16364)
- fix(index): Apply feedback from Cargo team (rust-lang/cargo#16369)
- fix(lints): handle lints separately at ws pkg level  (rust-lang/cargo#16367)
- feat(lint): new `implicit_minimum_version_req` lint (rust-lang/cargo#16321)
- fix(info): default to local without explicit reg (rust-lang/cargo#16358)
- Remove `[no-mentions]` handler in our triagebot config (rust-lang/cargo#16361)
- Don't read the config file twice when $CARGO_HOME is a symlink (rust-lang/cargo#16325)
- fix(timings): forgot to negate filter (rust-lang/cargo#16352)
- fix(doctest): Include all search paths with new build layout  (rust-lang/cargo#16348)
- fix(layout): Remove hashes from bins in new layout  (rust-lang/cargo#16351)
- docs(faq): Include an entry on disk space (rust-lang/cargo#16349)
- feat(timings): derive concurrency data from unit data (rust-lang/cargo#16350)
- perf(layout): Use unit_id, not pkg hash, for bin/lib pkg_dirs for new layout (rust-lang/cargo#16345)
- Validate target source paths before compilation with clearer errors (rust-lang/cargo#16338)
- test(doc): Remove unused build script (rust-lang/cargo#16344)
- refactor(timings): store UnitData in RenderContext instead  (rust-lang/cargo#16346)
- perf(clean): Optimize (legacy) clean with multiple -p specifiers (rust-lang/cargo#16264)
- test: Adjust output for out-of-tree build-dir (rust-lang/cargo#16343)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-build-execution Area: anything dealing with executing the compiler A-cli Area: Command-line interface, option parsing, etc. A-testing-cargo-itself Area: cargo's tests A-timings Area: timings Command-doc Command-report Z-build-analysis Nightly: build-analysis

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants