Skip to content

Commit f92e8b7

Browse files
committed
Add tracing debug.log
1 parent bc6ccc4 commit f92e8b7

File tree

8 files changed

+194
-8
lines changed

8 files changed

+194
-8
lines changed

Cargo.lock

Lines changed: 143 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ similar = "2.0"
3131
subprocess = "0.2.8"
3232
tempfile = "3.2"
3333
toml = "0.5"
34+
tracing = "0.1"
35+
tracing-appender = "0.2"
36+
tracing-subscriber = "0.3"
3437
walkdir = "2.3"
3538
whoami = "1.2"
3639

DESIGN.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,11 @@ default the source directory.
122122
Some trees are configured so that any unused variable is an error. This is a reasonable choice to keep the tree very clean in CI, but if unhandled it would be a problem for cargo mutants. Many mutants -- in fact at the time of writing all generated mutants -- ignore function parameters and return a static value. Rejecting them due to the lint failure is a missed opportunity to consider a similar but more subtle potential bug.
123123

124124
Therefore when running `rustc` we configure all warnings off, with `--cap-lints`.
125+
126+
## Logging
127+
128+
cargo-mutants writes two types of log files into the `mutants.out` directory:
129+
130+
Within the `log` directory, there is a file for each mutant scenario. This mostly contains the output from the Cargo commands, interspersed with some lines showing what command was run and the outcome. This is opened in append mode so that both cargo-mutants and cargo can write to it. This log is watched and the last line is shown in the progress bar to indicate what's going on.
131+
132+
Also, a file `mutants.out/debug.log` is written using [tracing](https://docs.rs/tracing) and written using the tracing macros. This contains more detailed information about what's happening in cargo-mutants itself.

src/cargo.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use camino::Utf8Path;
1010
use serde::Serialize;
1111
use serde_json::Value;
1212
use subprocess::{Popen, PopenConfig, Redirection};
13+
use tracing::{debug, info, warn};
1314

1415
use crate::console::Console;
1516
use crate::log_file::LogFile;
@@ -63,7 +64,9 @@ pub fn run_cargo(
6364

6465
let mut argv: Vec<String> = vec![cargo_bin];
6566
argv.extend(cargo_args.iter().cloned());
66-
log_file.message(&format!("run {}", argv.join(" "),));
67+
let message = format!("run {}", argv.join(" "),);
68+
log_file.message(&message);
69+
info!("{}", message);
6770
let mut child = Popen::create(
6871
&argv,
6972
PopenConfig {
@@ -78,14 +81,16 @@ pub fn run_cargo(
7881
.with_context(|| format!("failed to spawn {}", argv.join(" ")))?;
7982
let exit_status = loop {
8083
if start.elapsed() > timeout {
81-
log_file.message(&format!(
84+
let message = format!(
8285
"timeout after {:.3}s, terminating cargo process...\n",
8386
start.elapsed().as_secs_f32()
84-
));
87+
);
88+
log_file.message(&message);
89+
info!("{}", message);
8590
terminate_child(child, log_file)?;
8691
return Ok(CargoResult::Timeout);
8792
} else if let Err(e) = check_interrupted() {
88-
log_file.message("interrupted\n");
93+
warn!("interrupted: {}", e);
8994
console.message(&console::style_interrupted());
9095
terminate_child(child, log_file)?;
9196
return Err(e);
@@ -94,11 +99,13 @@ pub fn run_cargo(
9499
}
95100
console.tick();
96101
};
97-
log_file.message(&format!(
102+
let message = format!(
98103
"cargo result: {:?} in {:.3}s",
99104
exit_status,
100105
start.elapsed().as_secs_f64()
101-
));
106+
);
107+
log_file.message(&message);
108+
info!("{}", message);
102109
check_interrupted()?;
103110
if exit_status.success() {
104111
Ok(CargoResult::Success)
@@ -133,12 +140,14 @@ fn terminate_child(mut child: Popen, log_file: &mut LogFile) -> Result<()> {
133140
use std::convert::TryInto;
134141

135142
let pid = nix::unistd::Pid::from_raw(child.pid().expect("child has a pid").try_into().unwrap());
143+
info!("terminating cargo process {}", pid);
136144
if let Err(errno) = killpg(pid, Signal::SIGTERM) {
137145
if errno == Errno::ESRCH {
138146
// most likely we raced and it's already gone
139147
return Ok(());
140148
} else {
141149
let message = format!("failed to terminate child: {}", errno);
150+
warn!("{}", message);
142151
log_file.message(&message);
143152
return Err(anyhow!(message));
144153
}
@@ -151,9 +160,11 @@ fn terminate_child(mut child: Popen, log_file: &mut LogFile) -> Result<()> {
151160

152161
#[cfg(not(unix))]
153162
fn terminate_child(mut child: Popen, log_file: &mut LogFile) -> Result<()> {
163+
info!("terminating cargo process {child:?}");
154164
if let Err(e) = child.terminate() {
155165
// most likely we raced and it's already gone
156166
let message = format!("failed to terminate child: {}", e);
167+
warn!("{}", message);
157168
log_file.message(&message);
158169
return Err(anyhow!(message));
159170
}
@@ -203,6 +214,7 @@ pub fn locate_project(path: &Utf8Path) -> Result<Utf8PathBuf> {
203214
{
204215
return Err(anyhow!(stderr));
205216
}
217+
debug!("locate-project output: {stdout}");
206218
let val: Value = serde_json::from_str(&stdout).context("parse cargo locate-project output")?;
207219
let root = &val["root"];
208220
root.as_str()

src/console.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::time::{Duration, Instant};
88

99
use ::console::{style, StyledObject};
1010
use camino::Utf8Path;
11+
use tracing::info;
1112

1213
use crate::outcome::SummaryOutcome;
1314
use crate::*;
@@ -106,6 +107,7 @@ impl Console {
106107
}
107108

108109
pub fn message(&self, message: &str) {
110+
info!("{}", message);
109111
self.view.message(message)
110112
}
111113

src/lab.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use anyhow::{anyhow, Result};
1212
use camino::Utf8Path;
1313
use rand::prelude::*;
1414
use serde::Serialize;
15+
use tracing::info;
1516

1617
use crate::cargo::{cargo_args, run_cargo};
1718
use crate::console::{self, plural, Console};
@@ -72,6 +73,15 @@ pub fn test_unmutated_then_all_mutants(
7273
source_tree.path()
7374
};
7475
let output_dir = OutputDir::new(output_in_dir)?;
76+
77+
let debug_log = tracing_appender::rolling::never(output_dir.path(), "debug.log");
78+
tracing_subscriber::fmt()
79+
.with_ansi(false)
80+
.with_file(true) // source file name
81+
.with_line_number(true)
82+
.with_writer(debug_log)
83+
.init();
84+
7585
let console = Console::new();
7686

7787
if options.build_source {
@@ -184,6 +194,7 @@ fn run_cargo_phases(
184194
phases: &[Phase],
185195
console: &Console,
186196
) -> Result<Outcome> {
197+
info!("start testing {scenario} in {in_dir}");
187198
let mut log_file = output_dir.create_log(scenario)?;
188199
log_file.message(&scenario.to_string());
189200
let start_time = Instant::now();
@@ -207,6 +218,7 @@ fn run_cargo_phases(
207218
break;
208219
}
209220
}
221+
info!("{scenario} outcome {:?}", outcome.summary());
210222
console.cargo_outcome(scenario, start_time, &outcome, options);
211223

212224
Ok(outcome)

0 commit comments

Comments
 (0)