Skip to content

Commit 6368002

Browse files
authored
feat(build-analysis): emit timing-info log (#16179)
### What does this PR try to resolve? Log timing information. The schema is currently the same as the `--timings` JSON output. Part of #15844 ### How to test and review this PR? ``` CARGO_BUILD_ANALYSIS_ENABLED=true cargo -Zbuild-analysis check ```
2 parents fa7afa1 + 5b83f80 commit 6368002

File tree

7 files changed

+118
-5
lines changed

7 files changed

+118
-5
lines changed

src/cargo/core/compiler/build_context/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::util::Rustc;
99
use crate::util::context::GlobalContext;
1010
use crate::util::errors::CargoResult;
1111
use crate::util::interning::InternedString;
12+
use crate::util::logger::BuildLogger;
1213
use std::collections::{HashMap, HashSet};
1314

1415
mod target_info;
@@ -50,6 +51,9 @@ pub struct BuildContext<'a, 'gctx> {
5051
/// The cargo context.
5152
pub gctx: &'gctx GlobalContext,
5253

54+
/// Build logger for `-Zbuild-analysis`.
55+
pub logger: Option<&'a BuildLogger>,
56+
5357
/// This contains a collection of compiler flags presets.
5458
pub profiles: Profiles,
5559

@@ -83,6 +87,7 @@ pub struct BuildContext<'a, 'gctx> {
8387
impl<'a, 'gctx> BuildContext<'a, 'gctx> {
8488
pub fn new(
8589
ws: &'a Workspace<'gctx>,
90+
logger: Option<&'a BuildLogger>,
8691
packages: PackageSet<'gctx>,
8792
build_config: &'a BuildConfig,
8893
profiles: Profiles,
@@ -102,6 +107,7 @@ impl<'a, 'gctx> BuildContext<'a, 'gctx> {
102107
Ok(BuildContext {
103108
ws,
104109
gctx: ws.gctx(),
110+
logger,
105111
packages,
106112
build_config,
107113
profiles,

src/cargo/core/compiler/job_queue/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,7 @@ impl<'gctx> DrainState<'gctx> {
11241124
}
11251125
let unlocked = self.queue.finish(unit, &artifact);
11261126
match artifact {
1127-
Artifact::All => self.timings.unit_finished(id, unlocked),
1127+
Artifact::All => self.timings.unit_finished(build_runner, id, unlocked),
11281128
Artifact::Metadata => self.timings.unit_rmeta_finished(id, unlocked),
11291129
}
11301130
Ok(())

src/cargo/core/compiler/timings.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::core::PackageId;
77
use crate::core::compiler::job_queue::JobId;
88
use crate::core::compiler::{BuildContext, BuildRunner, TimingOutput};
99
use crate::util::cpu::State;
10+
use crate::util::log_message::LogMessage;
1011
use crate::util::machine_message::{self, Message};
1112
use crate::util::style;
1213
use crate::util::{CargoResult, GlobalContext};
@@ -208,7 +209,7 @@ impl<'gctx> Timings<'gctx> {
208209
let has_report = |what| bcx.build_config.timing_outputs.contains(&what);
209210
let report_html = has_report(TimingOutput::Html);
210211
let report_json = has_report(TimingOutput::Json);
211-
let enabled = report_html | report_json;
212+
let enabled = report_html | report_json | bcx.logger.is_some();
212213

213214
let mut root_map: HashMap<PackageId, Vec<String>> = HashMap::new();
214215
for unit in root_units {
@@ -314,7 +315,12 @@ impl<'gctx> Timings<'gctx> {
314315
}
315316

316317
/// Mark that a unit has finished running.
317-
pub fn unit_finished(&mut self, id: JobId, unlocked: Vec<&Unit>) {
318+
pub fn unit_finished(
319+
&mut self,
320+
build_runner: &BuildRunner<'_, '_>,
321+
id: JobId,
322+
unlocked: Vec<&Unit>,
323+
) {
318324
if !self.enabled {
319325
return;
320326
}
@@ -340,6 +346,16 @@ impl<'gctx> Timings<'gctx> {
340346
.to_json_string();
341347
crate::drop_println!(self.gctx, "{}", msg);
342348
}
349+
if let Some(logger) = build_runner.bcx.logger {
350+
logger.log(LogMessage::TimingInfo {
351+
package_id: unit_time.unit.pkg.package_id().to_spec(),
352+
target: unit_time.unit.target.clone(),
353+
mode: unit_time.unit.mode,
354+
duration: unit_time.duration,
355+
rmeta_time: unit_time.rmeta_time,
356+
sections: unit_time.sections.clone().into_iter().collect(),
357+
});
358+
}
343359
self.unit_times.push(unit_time);
344360
}
345361

src/cargo/ops/cargo_compile/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ pub fn compile_ws<'a>(
173173
});
174174
}
175175

176-
let bcx = create_bcx(ws, options, &interner)?;
176+
let bcx = create_bcx(ws, options, &interner, logger.as_ref())?;
177177

178178
if options.build_config.unit_graph {
179179
unit_graph::emit_serialized_unit_graph(&bcx.roots, &bcx.unit_graph, ws.gctx())?;
@@ -232,6 +232,7 @@ pub fn create_bcx<'a, 'gctx>(
232232
ws: &'a Workspace<'gctx>,
233233
options: &'a CompileOptions,
234234
interner: &'a UnitInterner,
235+
logger: Option<&'a BuildLogger>,
235236
) -> CargoResult<BuildContext<'a, 'gctx>> {
236237
let CompileOptions {
237238
ref build_config,
@@ -586,6 +587,7 @@ where `<compatible-ver>` is the latest version supporting rustc {rustc_version}"
586587

587588
let bcx = BuildContext::new(
588589
ws,
590+
logger,
589591
pkg_set,
590592
build_config,
591593
profiles,

src/cargo/util/log_message.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,14 @@
33
use std::io::Write;
44
use std::path::PathBuf;
55

6+
use cargo_util_schemas::core::PackageIdSpec;
67
use jiff::Timestamp;
78
use serde::Serialize;
89

10+
use crate::core::Target;
11+
use crate::core::compiler::CompilationSection;
12+
use crate::core::compiler::CompileMode;
13+
914
/// A log message.
1015
///
1116
/// Each variant represents a different type of event.
@@ -23,6 +28,17 @@ pub enum LogMessage {
2328
target_dir: PathBuf,
2429
workspace_root: PathBuf,
2530
},
31+
/// Emitted when a compilation unit finishes.
32+
TimingInfo {
33+
package_id: PackageIdSpec,
34+
target: Target,
35+
mode: CompileMode,
36+
duration: f64,
37+
#[serde(skip_serializing_if = "Option::is_none")]
38+
rmeta_time: Option<f64>,
39+
#[serde(skip_serializing_if = "Vec::is_empty")]
40+
sections: Vec<(String, CompilationSection)>,
41+
},
2642
}
2743

2844
impl LogMessage {

src/cargo/util/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub mod job;
5757
pub mod lints;
5858
mod lockserver;
5959
pub mod log_message;
60-
mod logger;
60+
pub mod logger;
6161
pub mod machine_message;
6262
pub mod network;
6363
mod once;

tests/testsuite/build_analysis.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,79 @@ fn log_msg_build_started() {
116116
"target_dir": "[ROOT]/foo/target",
117117
"timestamp": "[..]T[..]Z",
118118
"workspace_root": "[ROOT]/foo"
119+
},
120+
"{...}"
121+
]
122+
"#]]
123+
.is_json()
124+
.against_jsonlines(),
125+
);
126+
}
127+
128+
#[cargo_test]
129+
fn log_msg_timing_info() {
130+
let p = project()
131+
.file(
132+
"Cargo.toml",
133+
r#"
134+
[package]
135+
name = "foo"
136+
version = "0.0.0"
137+
edition = "2015"
138+
139+
[dependencies]
140+
bar = { path = "bar" }
141+
"#,
142+
)
143+
.file("src/lib.rs", "")
144+
.file("bar/Cargo.toml", &basic_manifest("bar", "0.0.0"))
145+
.file("bar/src/lib.rs", "")
146+
.build();
147+
148+
p.cargo("check -Zbuild-analysis")
149+
.env("CARGO_BUILD_ANALYSIS_ENABLED", "true")
150+
.masquerade_as_nightly_cargo(&["build-analysis"])
151+
.run();
152+
153+
let cargo_home = paths::cargo_home();
154+
let log_dir = cargo_home.join("log");
155+
assert!(log_dir.exists());
156+
157+
let entries = std::fs::read_dir(&log_dir).unwrap();
158+
let log_file = entries
159+
.filter_map(Result::ok)
160+
.find(|e| e.path().extension().and_then(|s| s.to_str()) == Some("jsonl"))
161+
.unwrap();
162+
163+
let content = std::fs::read_to_string(log_file.path()).unwrap();
164+
165+
assert_e2e().eq(
166+
&content,
167+
str![[r#"
168+
[
169+
{
170+
"reason": "build-started",
171+
"...": "{...}"
172+
},
173+
{
174+
"duration": "{...}",
175+
"mode": "check",
176+
"package_id": "path+[ROOTURL]/foo/bar#0.0.0",
177+
"reason": "timing-info",
178+
"rmeta_time": "{...}",
179+
"run_id": "[..]T[..]Z-[..]",
180+
"target": "{...}",
181+
"timestamp": "[..]T[..]Z"
182+
},
183+
{
184+
"duration": "{...}",
185+
"mode": "check",
186+
"package_id": "path+[ROOTURL]/foo#0.0.0",
187+
"reason": "timing-info",
188+
"rmeta_time": "{...}",
189+
"run_id": "[..]T[..]Z-[..]",
190+
"target": "{...}",
191+
"timestamp": "[..]T[..]Z"
119192
}
120193
]
121194
"#]]

0 commit comments

Comments
 (0)