Skip to content

Commit

Permalink
Use env_logger as default logger.
Browse files Browse the repository at this point in the history
  • Loading branch information
tao-guo committed Oct 18, 2023
1 parent 9fee93f commit de7bc73
Show file tree
Hide file tree
Showing 11 changed files with 34 additions and 45 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ log = "0.4"
faccess = "0.2"
os_pipe = "0.9"
main_error = "0.1.2"
env_logger = "0.10.0"

[dev-dependencies]
rayon = "1.5"
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,6 @@ are printed to stderr will be logged. Since it is returning result type, you can
errors if command execution fails.

```rust
// this code snppit is using a builtin simple logger, you can replace it with a real logger
init_builtin_logger();
let dir: &str = "folder with spaces";
assert!(run_cmd!(mkdir /tmp/$dir; ls /tmp/$dir).is_ok());
assert!(run_cmd!(mkdir /tmp/"$dir"; ls /tmp/"$dir"; rmdir /tmp/"$dir").is_err());
Expand All @@ -183,7 +181,8 @@ assert!(run_cmd!(mkdir /tmp/"$dir"; ls /tmp/"$dir"; rmdir /tmp/"$dir").is_err())
```

It is using rust [log crate](https://crates.io/crates/log), and you can use your actual favorite
logging implementation. **Notice that if you don't provide any logger, the stderr from process will be discarded**.
logger implementation. Notice that if you don't provide any logger, it will use env_logger to print
messages from process's stderr.

#### Builtin commands
##### cd
Expand Down
1 change: 0 additions & 1 deletion examples/dd_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ struct Opt {
}

fn main() -> MainResult {
init_builtin_logger();
let Opt {
block_size,
thread_num,
Expand Down
2 changes: 0 additions & 2 deletions examples/pipes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,6 @@ fn rand() -> i32 {
}

fn main() -> MainResult {
init_builtin_logger();

// simple pre-check of TERM, tput's error message should be enough
let term = std::env::var("TERM").unwrap();
run_cmd!(tput -T $term sgr0 >/dev/null)?;
Expand Down
1 change: 0 additions & 1 deletion examples/rust_cookbook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use cmd_lib::*;
use std::io::{BufRead, BufReader};
fn main() -> MainResult {
init_builtin_logger();
cmd_lib::set_pipefail(false); // do not fail due to pipe errors

// Run an external command and process stdout
Expand Down
1 change: 0 additions & 1 deletion examples/tetris.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,6 @@ fn cmd_exit() {
}

fn main() -> MainResult {
init_builtin_logger();
#[rustfmt::skip]
let old_cfg = run_fun!(stty -g)?; // let's save terminal state ...
tls_set!(old_stty_cfg, |cfg| *cfg = old_cfg);
Expand Down
6 changes: 6 additions & 0 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ pub fn cmd_error(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let msg = parse_msg(input.into());
quote!({
use ::cmd_lib::AsOsStr;
let _ = ::cmd_lib::try_init_default_logger();
::cmd_lib::log::error!("{}", #msg)
})
.into()
Expand All @@ -210,6 +211,7 @@ pub fn cmd_warn(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let msg = parse_msg(input.into());
quote!({
use ::cmd_lib::AsOsStr;
let _ = ::cmd_lib::try_init_default_logger();
::cmd_lib::log::warn!("{}", #msg)
})
.into()
Expand Down Expand Up @@ -243,6 +245,7 @@ pub fn cmd_info(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let msg = parse_msg(input.into());
quote!({
use ::cmd_lib::AsOsStr;
let _ = ::cmd_lib::try_init_default_logger();
::cmd_lib::log::info!("{}", #msg)
})
.into()
Expand All @@ -255,6 +258,7 @@ pub fn cmd_debug(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let msg = parse_msg(input.into());
quote!({
use ::cmd_lib::AsOsStr;
let _ = ::cmd_lib::try_init_default_logger();
::cmd_lib::log::debug!("{}", #msg)
})
.into()
Expand All @@ -267,6 +271,7 @@ pub fn cmd_trace(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let msg = parse_msg(input.into());
quote!({
use ::cmd_lib::AsOsStr;
let _ = ::cmd_lib::try_init_default_logger();
::cmd_lib::log::trace!("{}", #msg)
})
.into()
Expand All @@ -292,6 +297,7 @@ pub fn cmd_die(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let msg = parse_msg(input.into());
quote!({
use ::cmd_lib::AsOsStr;
let _ = ::cmd_lib::try_init_default_logger();
::cmd_lib::log::error!("FATAL: {}", #msg);
std::process::exit(1)
})
Expand Down
7 changes: 7 additions & 0 deletions src/builtins.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{CmdEnv, CmdResult};
use crate::logger::try_init_default_logger;
use log::*;
use std::io::Write;

Expand All @@ -8,31 +9,37 @@ pub(crate) fn builtin_echo(env: &mut CmdEnv) -> CmdResult {
}

pub(crate) fn builtin_die(env: &mut CmdEnv) -> CmdResult {
let _ = try_init_default_logger();
error!("FATAL: {}", env.args()[1..].join(" "));
std::process::exit(1);
}

pub(crate) fn builtin_error(env: &mut CmdEnv) -> CmdResult {
let _ = try_init_default_logger();
error!("{}", env.args()[1..].join(" "));
Ok(())
}

pub(crate) fn builtin_warn(env: &mut CmdEnv) -> CmdResult {
let _ = try_init_default_logger();
warn!("{}", env.args()[1..].join(" "));
Ok(())
}

pub(crate) fn builtin_info(env: &mut CmdEnv) -> CmdResult {
let _ = try_init_default_logger();
info!("{}", env.args()[1..].join(" "));
Ok(())
}

pub(crate) fn builtin_debug(env: &mut CmdEnv) -> CmdResult {
let _ = try_init_default_logger();
debug!("{}", env.args()[1..].join(" "));
Ok(())
}

pub(crate) fn builtin_trace(env: &mut CmdEnv) -> CmdResult {
let _ = try_init_default_logger();
trace!("{}", env.args()[1..].join(" "));
Ok(())
}
7 changes: 6 additions & 1 deletion src/child.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{process, CmdResult, FunResult};
use crate::logger::try_init_default_logger;
use log::{info, warn};
use os_pipe::PipeReader;
use std::io::{BufRead, BufReader, Error, ErrorKind, Read, Result};
Expand Down Expand Up @@ -284,7 +285,10 @@ impl StderrLogging {
BufReader::new(stderr)
.lines()
.map_while(Result::ok)
.for_each(|line| info!("{}", line))
.for_each(|line| {
let _ = try_init_default_logger();
info!("{}", line)
})
});
Self {
cmd: cmd.into(),
Expand All @@ -303,6 +307,7 @@ impl Drop for StderrLogging {
fn drop(&mut self) {
if let Some(thread) = self.thread.take() {
if let Err(e) = thread.join() {
let _ = try_init_default_logger();
warn!("{} logging thread exited with error: {:?}", self.cmd, e);
}
}
Expand Down
7 changes: 3 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,6 @@
//!
//! ```no_run
//! # use cmd_lib::*;
//! // this code snppit is using a builtin simple logger, you can replace it with a real logger
//! init_builtin_logger();
//! let dir: &str = "folder with spaces";
//! assert!(run_cmd!(mkdir /tmp/$dir; ls /tmp/$dir).is_ok());
//! assert!(run_cmd!(mkdir /tmp/"$dir"; ls /tmp/"$dir"; rmdir /tmp/"$dir").is_err());
Expand All @@ -201,7 +199,8 @@
//! ```
//!
//! It is using rust [log crate](https://crates.io/crates/log), and you can use your actual favorite
//! logging implementation. **Notice that if you don't provide any logger, the stderr from process will be discarded**.
//! logger implementation. Notice that if you don't provide any logger, it will use env_logger to print
//! messages from process's stderr.
//!
//! ### Builtin commands
//! #### cd
Expand Down Expand Up @@ -364,12 +363,12 @@ pub type CmdResult = std::io::Result<()>;
pub use child::{CmdChildren, FunChildren};
#[doc(hidden)]
pub use log;
pub use logger::init_builtin_logger;
pub use main_error::MainError;
pub use main_error::MainResult;
pub use process::{
export_cmd, set_debug, set_pipefail, AsOsStr, Cmd, CmdEnv, CmdString, Cmds, GroupCmds, Redirect,
};
pub use logger::try_init_default_logger;

mod builtins;
mod child;
Expand Down
41 changes: 9 additions & 32 deletions src/logger.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,11 @@
use log::{Level, LevelFilter, Metadata, Record};

static LOGGER: CmdLogger = CmdLogger;

/// Initializes the builtin cmd_lib logger
///
/// This is to make examples in this library work, and users should usually use a real logger
/// instead. When being used, it should be called early in the main() function. Default log level
/// is set to `debug`.
///
/// # Panics
///
/// This function will panic if it is called more than once, or if another
/// library has already initialized a global logger.
pub fn init_builtin_logger() {
log::set_logger(&LOGGER)
.map(|()| log::set_max_level(LevelFilter::Debug))
.unwrap();
use log::SetLoggerError;

#[doc(hidden)]
pub fn try_init_default_logger() -> Result<(), SetLoggerError> {
env_logger::builder()
.filter_level(log::LevelFilter::Info)
.format_target(false)
.format_timestamp(None)
.try_init()
}

struct CmdLogger;
impl log::Log for CmdLogger {
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= Level::Debug
}

fn log(&self, record: &Record) {
if self.enabled(record.metadata()) {
eprintln!("{} - {}", record.level(), record.args());
}
}

fn flush(&self) {}
}

0 comments on commit de7bc73

Please sign in to comment.