logsley 0.1.3

Opinionated logging library
Documentation

logsley

This is an opinionated Rust logging library.

Features

  • Configure the logger with one function call
  • Thread and task scoped variables
  • See logging output from tests
  • Works with libraries that use log, slog, slog-scope, and slog-scope-futures.
  • Logs JSON by default. Set DEV_LOG_FORMAT=full env var to get pretty output in your terminal.
  • Adjust logging verbosity of modules with simple string parameter, and override it with the RUST_LOG env var. Example: RUST_LOG=some::spammy::module=warn,my::buggy::module=trace. See slog-envlogger for details.
  • Approved by Sir Robin of Logsley: Cary Elwes as Robin Hood in the film Robin Hood Men in Tights (1993)

Limitations

  • Uses macros

Examples

// You should do logging like this.

let _global_logger_guard =
  logsley::configure("info").unwrap();
logsley::thread_scope("main", || {
// Log named values:
logsley::error!("err {}", 1; "x" => 2);
// {"time_ns":1604899904064111000,
// "time":"2020-11-08T21:31:44.064-08:00",
// "module":"opinion","level":"ERROR",
// "message":"err 1",
// "thread":"main","x":2}
logsley::warn!("warn {}", 1; "x" => 2);
logsley::info!("info {}", 1; "x" => 2);
logsley::debug!("debug {}", 1; "x" => 2);
logsley::trace!("trace {}", 1; "x" => 2);

// Log simple messages:
log::info!("log {}", 1);
// {"time_ns":1604899904065070000,
// "time":"2020-11-08T21:31:44.065-08:00",
// "module":"opinion","level":"INFO",
// "message":"log 1","thread":"main"}

std::thread::spawn(|| {
  logsley::thread_scope("thread1", || {
    logsley::info!(
      "in thread {}", 1; "x" => 2);
    })
})
.join()
.unwrap();
// {"time_ns":1604899904065111000,
// "time":"2020-11-08T21:31:44.065-08:00",
// "module":"opinion","level":"INFO",
// "message":"in thread 1",
// "thread":"thread1","x":2}

async_std::task::block_on(
  logsley::task_scope("task1", async move {
    logsley::info!(
      "logsley in task {}", 1; "x" => 2);
}));
// {"time_ns":1604899904065241000,
// "time":"2020-11-08T21:31:44.065-08:00",
// "module":"opinion","level":"INFO",
// "message":"logsley in task 1",
// "task":"task1","thread":"main","x":2}

panic!("uhoh");
// {"time_ns":1604899904955593000,
// "time":"2020-11-08T21:31:44.955-08:00",
// "module":"log_panics","level":"ERROR",
// "message":"thread 'main' panicked at 'uhoh': examples/opinion.rs:30\n
//   0: backtrace::backtrace::libunwind::trace\n
//             at /.../backtrace-0.3.54/src/backtrace/libunwind.rs:90:5\n
//      backtrace::backtrace::trace_unsynchronized\n
//             at /.../backtrace-0.3.54/src/backtrace/mod.rs:66:5\n
//   1: backtrace::backtrace::trace\n
//             at /.../backtrace-0.3.54/src/backtrace/mod.rs:53:14\n
//   2: backtrace::capture::Backtrace::create\n
//             at /.../backtrace-0.3.54/src/capture.rs:176:9\n
//   3: backtrace::capture::Backtrace::new\n
//             at /.../backtrace-0.3.54/src/capture.rs:140:22\n
//   4: log_panics::init::{{closure}}\n
//             at /.../log-panics-2.0.0/src/lib.rs:52:25\n
//   5: std::panicking::rust_panic_with_hook\n
//             at /.../library/std/src/panicking.rs:581:17\n
//   6: std::panicking::begin_panic::{{closure}}\n
//             at /.../library/std/src/panicking.rs:506:9\n
//   7: std::sys_common::backtrace::__rust_end_short_backtrace\n
//             at /.../library/std/src/sys_common/backtrace.rs:153:18\n
//   8: std::panicking::begin_panic\n
//             at /.../library/std/src/panicking.rs:505:12\n
//   9: opinion::main::{{closure}}\n
//             at examples/opinion.rs:30:9\n
//  10: slog_scope::scope\n
//             at /.../slog-scope-4.3.0/lib.rs:248:5\n
//  11: logsley::thread_scope\n
//             at src/lib.rs:179:5\n
//  12: opinion::main\n
//             at examples/opinion.rs:5:5\n
//  13: core::ops::function::FnOnce::call_once\n
//             at /.../library/core/src/ops/function.rs:227:5\n
//  14: std::sys_common::backtrace::__rust_begin_short_backtrace\n
//             at /.../library/std/src/sys_common/backtrace.rs:137:18\n
//  15: std::rt::lang_start::{{closure}}\n
//             at /.../library/std/src/rt.rs:66:18\n
//  16: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once\n
//             at /.../library/core/src/ops/function.rs:259:13\n
//      std::panicking::try::do_call\n
//             at /.../library/std/src/panicking.rs:381:40\n
//      std::panicking::try\n
//             at /.../library/std/src/panicking.rs:345:19\n
//      std::panic::catch_unwind\n
//             at /.../library/std/src/panic.rs:382:14\n
//      std::rt::lang_start_internal\n
//             at /.../library/std/src/rt.rs:51:25\n
//  17: std::rt::lang_start\n
//             at /.../library/std/src/rt.rs:65:5\n
//  18: _main\n",
// "thread":"main"}
});
}

For a runnable example, see examples/opinion.rs.

Set the default log level to info. The program will emit log messages with level info and higher.

let _global_logger_guard = logsley::configure("info");
log::error!("emitted");
log::warn!("emitted");
log::info!("emitted");
log::debug!("not emitted");
log::trace!("not emitted");

Set the default log level to info and set the level for chatty::module1 to warn.

let _global_logger_guard =
logsley::configure("info,chatty::module1=warn");

Use the environment variable to override default log level. module1 still gets its special log level.

std::env::set_var("RUST_LOG", "debug");
let _global_logger_guard =
logsley::configure("info,module1=warn");

Use the environment variable to set module1 to debug.

std::env::set_var("RUST_LOG", "module1=debug");
let _global_logger_guard = logsley::configure("info");

Documentation

https://docs.rs/logsley

Alternatives

Release Process

  1. Edit Cargo.toml and bump version number.
  2. Run ./release.sh

Changelog

  • v0.1.3 - Fix missing slog_scope::logger error
  • v0.1.2 - Fix panic in configure_for_test
  • v0.1.1 - Make example code fit in crates.io's 60-column code views.
  • v0.1.0 - First published version

TODO

License: Apache-2.0