Crate logsley[][src]

Expand description

logsley

This is an opinionated Rust logging library.

Features

  • Configure the logger with one function call
  • Thread scoped variables
  • Task scoped variables, with the async feature enabled
  • 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.8 - Add async feature
  • v0.1.7 - Bugfix.
  • v0.1.6 - Add missing slog reexport.
  • v0.1.5 - Rename OutputFormat::JSON to Json to satisfy nightly clippy.
  • v0.1.4 - Update docs.
  • 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

  • DONE - Try to make this crate comply with the Rust API Guidelines.
  • DONE - Include Readme.md info in the crate’s docs.
  • DONE - Make the repo public
  • DONE - Set up continuous integration tests and banner.
    • https://gitlab.com/mattdark/firebase-example/blob/master/.gitlab-ci.yml
    • https://medium.com/astraol/optimizing-ci-cd-pipeline-for-rust-projects-gitlab-docker-98df64ae3bc4
    • https://hub.docker.com/_/rust
  • DONE - Add some documentation tests
    • https://doc.rust-lang.org/rustdoc/documentation-tests.html
    • https://doc.rust-lang.org/stable/rust-by-example/testing/doc_testing.html
  • DONE - Publish to creates.io
  • DONE - Read through https://crate-ci.github.io/index.html
  • DONE - Add and update a changelog
    • Update it manually
    • https://crate-ci.github.io/release/changelog.html
  • Get a code review from an experienced rustacean
  • Add features: threads, futures, term

Macros

Structs

Enums

Functions

Configure log and slog to emit JSON to stdout.

Configures log and slog to emit to stdout with “plain” format. Can be called multiple times from different threads. Each call leaks a GlobalLoggerGuard which contains only a bool.