Skip to content

Commit 5428f1b

Browse files
committed
feat(logging): use tracing format layer + env filter
The comment here was resolved upstream in September 2021, so we can now apply a filter directly to a layer. This causes `WARN` (or more severe) logs to be written to stderr.
1 parent 25927eb commit 5428f1b

File tree

3 files changed

+40
-28
lines changed

3 files changed

+40
-28
lines changed

git-branchless-lib/src/core/effects.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
//! Wrappers around various side effects.
22
3+
use bstr::ByteSlice;
34
use std::convert::TryInto;
45
use std::fmt::{Debug, Write};
56
use std::io::{stderr, stdout, Stderr, Stdout, Write as WriteIo};
67
use std::mem::take;
78
use std::sync::{Arc, Mutex, RwLock};
8-
use std::thread;
99
use std::time::{Duration, Instant};
10+
use std::{io, thread};
1011

1112
use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressStyle};
1213
use itertools::Itertools;
@@ -919,7 +920,7 @@ impl Write for ErrorStream {
919920
match &self.dest {
920921
OutputDest::Stdout => {
921922
self.buffer.push_str(s);
922-
self.flush();
923+
WriteProgress::flush(self);
923924
}
924925

925926
OutputDest::Suppress => {
@@ -935,6 +936,33 @@ impl Write for ErrorStream {
935936
}
936937
}
937938

939+
/// You probably don't want this. This implementation is only for `tracing`'s `fmt_layer`, because
940+
/// it needs a writer of type `io::Write`, but `Effects` normally uses its implementation of
941+
/// `fmt::Write`.
942+
impl io::Write for ErrorStream {
943+
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
944+
match &self.dest {
945+
OutputDest::Stdout => {
946+
self.buffer.push_str(buf.to_str_lossy().as_ref());
947+
Ok(buf.len())
948+
}
949+
OutputDest::Suppress => {
950+
// Do nothing.
951+
Ok(buf.len())
952+
}
953+
OutputDest::BufferForTest { stdout: _, stderr } => {
954+
let mut buffer = stderr.lock().unwrap();
955+
buffer.write(buf)
956+
}
957+
}
958+
}
959+
960+
fn flush(&mut self) -> io::Result<()> {
961+
WriteProgress::flush(self);
962+
Ok(())
963+
}
964+
}
965+
938966
impl Drop for ErrorStream {
939967
fn drop(&mut self) {
940968
WriteProgress::drop(self);

git-branchless/src/commands/mod.rs

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use lib::core::rewrite::MergeConflictRemediation;
3737
use lib::git::Repo;
3838
use lib::git::RepoError;
3939
use lib::util::ExitCode;
40+
use tracing::level_filters::LevelFilter;
4041
use tracing_chrome::ChromeLayerBuilder;
4142
use tracing_error::ErrorLayer;
4243
use tracing_subscriber::fmt as tracing_fmt;
@@ -94,8 +95,6 @@ fn rewrite_args(args: Vec<OsString>) -> Vec<OsString> {
9495
/// Wrapper function for `main` to ensure that `Drop` is called for local
9596
/// variables, since `std::process::exit` will skip them.
9697
fn do_main_and_drop_locals() -> eyre::Result<i32> {
97-
let _tracing_guard = install_tracing();
98-
9998
let args = rewrite_args(std::env::args_os().collect_vec());
10099
let Opts {
101100
working_directory,
@@ -126,6 +125,8 @@ fn do_main_and_drop_locals() -> eyre::Result<i32> {
126125
};
127126
let effects = Effects::new(color);
128127

128+
let _tracing_guard = install_tracing(effects.clone());
129+
129130
if let Some(ExitCode(exit_code)) = check_unsupported_config_options(&effects)? {
130131
let exit_code: i32 = exit_code.try_into()?;
131132
return Ok(exit_code);
@@ -406,27 +407,11 @@ pub fn main() {
406407
}
407408

408409
#[must_use = "This function returns a guard object to flush traces. Dropping it immediately is probably incorrect. Make sure that the returned value lives until tracing has finished."]
409-
fn install_tracing() -> eyre::Result<impl Drop> {
410-
let (filter_layer, fmt_layer) = match EnvFilter::try_from_default_env() {
411-
Ok(filter_layer) => {
412-
let fmt_layer = tracing_fmt::layer()
413-
.with_span_events(tracing_fmt::format::FmtSpan::CLOSE)
414-
.with_target(false);
415-
(Some(filter_layer), Some(fmt_layer))
416-
}
417-
Err(_) => {
418-
// We would like the filter layer to apply *only* to the formatting
419-
// layer. That way, the logging output is suppressed, but we still
420-
// get spantraces for use with `color-eyre`. However, it's currently
421-
// not possible (?), at least not without writing some a custom
422-
// subscriber. See https://github.com/tokio-rs/tracing/pull/1523
423-
//
424-
// The workaround is to only display logging messages if `RUST_LOG`
425-
// is set (which is unfortunate, because we'll miss out on
426-
// `WARN`-level messages by default).
427-
(None, None)
428-
}
429-
};
410+
fn install_tracing(effects: Effects) -> eyre::Result<impl Drop> {
411+
let env_filter = EnvFilter::builder()
412+
.with_default_directive(LevelFilter::WARN.into())
413+
.from_env_lossy();
414+
let fmt_layer = tracing_fmt::layer().with_writer(move || effects.clone().get_error_stream());
430415

431416
let (profile_layer, flush_guard): (_, Box<dyn Any>) = {
432417
// We may invoke a hook that calls back into `git-branchless`. In that case,
@@ -475,8 +460,7 @@ fn install_tracing() -> eyre::Result<impl Drop> {
475460

476461
tracing_subscriber::registry()
477462
.with(ErrorLayer::default())
478-
.with(filter_layer)
479-
.with(fmt_layer)
463+
.with(fmt_layer.with_filter(env_filter))
480464
.with(profile_layer)
481465
.try_init()?;
482466

git-branchless/src/commands/reword.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use std::collections::{HashMap, HashSet};
88
use std::convert::TryFrom;
99
use std::fmt::Write;
1010
use std::fs::File;
11-
use std::io::Write as OtherWrite;
1211
use std::time::SystemTime;
1312

1413
use bstr::{ByteSlice, ByteVec};
@@ -500,6 +499,7 @@ fn prepare_messages(
500499

501500
let mut w = File::create(repo.get_path().join("REWORD_EDITMSG"))
502501
.context("Creating REWORD_EDITMSG file")?;
502+
use std::io::Write;
503503
writeln!(
504504
&mut w,
505505
"{} This file was created by `git branchless reword` at {}\n\

0 commit comments

Comments
 (0)