A pretty, sensible logger for Rust - ideal for running examples and tests on a crate of choice

Overview

sensible-env-logger

github crates.io docs.rs build status

A pretty, sensible logger for Rust - ideal for running examples and tests on a crate of choice.

This is a thin wrapper around pretty_env_logger. It requires minimal configuration to set up, and writes to standard error with nice colored output for log levels.

example-output


This crate works with Cargo with a Cargo.toml like:

[dependencies]
log = "0.4"
sensible-env-logger = "0.1"

Getting started

The sensible-env-logger is ideally used when writing out examples or tests for a Cargo project or crate. It can be added as a dev-dependency if needed.

First, add some usage to your application:

#[macro_use] extern crate log;

fn main() {
    sensible_env_logger::init!();

    info!("such information");
    warn!("o_O");
    error!("much error");
}

Then run your app with cargo, and you should see the full log output:

cargo run

Alternatively, run your app with the environment variables that control the log level for external crates as well as your crate explicitly set:

GLOBAL_RUST_LOG=warn RUST_LOG=trace cargo run

Even though this crate has the name env in it, using the sensible-env-logger in code is dead simple, and requires minimal configuration.

Examples

You can check out sample usage of this crate in the examples/ folder in the project repo on GitHub.

Defaults

The helper macros below can be used to configure the global logger with sensible defaults. Their sample log output is also shown.

Note: any helper macros, such as init!(), should be called early in the execution of a Rust program.

init!()

Initializes the global logger with a pretty, sensible env logger.

INFO  my_module         > an informational message

init_timed!()

Initializes the global logger with a timed pretty, sensible env logger.

2022-03-12T17:15:31.683Z INFO  my_module         > an informational message

init_timed_short!()

Initializes the global logger with a localized time pretty, sensible env logger.

12:15:31.683 INFO  my_module         > an informational message

Using init_timed_short!() requires the local-time feature to be enabled:

[dev-dependencies]
sensible-env-logger = { version = "0.1", features = ["local-time"] }

Rationale

Imagine you are testing out a Cargo project named my_rust_project. That is, the Cargo.toml in your project would look something like this:

[package]
name = "my-rust-project"

[dependencies]
log = "*"

Assuming you are building a library, your src/lib.rs could look like this:

#[macro_use] extern crate log;

pub fn my_awesome_fn() {
    trace!("getting ready to do something cool...");
    std::thread::sleep(std::time::Duration::from_millis(500));
    info!("finished!");
}

You then create a new example file named examples/my_example.rs, with the following contents:

use my_rust_project::my_awesome_fn;
#[macro_use] extern crate log;

fn main() {
    debug!("my debug message");
    my_awesome_fn();
    error!("oops! something went wrong!");
}

You can run the new file with cargo run --example my_example. The problem here is that you won't get any terminal output by default; this is because you need to set up the RUST_LOG environment variable beforehand, in order to see the expected log output.

Setting the RUST_LOG variable works, but there are a few issues with this. For example, what if your Cargo project uses other external libraries? Ideally you want to see the trace logs from your own project (the crate under test), but not the trace logs from these other libraries. In that case, setting RUST_LOG=trace doesn't seem the best approach here.

You could then set the RUST_LOG environment variable to the following log format:

$ export RUST_LOG='warning,my_rust_project=trace,my_example=trace'

When leveraging the pretty_env_logger crate and adding a pretty_env_logger::init() at the top of the main function, this does now work as expected and produce the desired log output.

However, there are few limitations with this approach:

  • In your Cargo project, you'd need to update the documentation for running examples to mention that you need to export the RUST_LOG env variable explicitly. For instance, you'd need to mention that an example is ideally run like RUST_LOG=trace cargo run --example my_example.

  • You'd need to remember to set the RUST_LOG env variable each time. This can be troublesome when your Windows machine reboots for example, or whenever you open a new terminal window.

To solve these minor issues you can simply use the sensible_env_logger crate, which automatically sets up sensible defaults; this involves generating and using a directive string in the same form as the $RUST_LOG environment variable.

Now, the updated code in the examples/my_example.rs would look like this:

use my_rust_project::my_awesome_fn;
#[macro_use] extern crate log;

fn main() {
    sensible_env_logger::init!();

    debug!("my debug message");
    my_awesome_fn();
    error!("oops! something went wrong!");
}

Contributing

Contributions are welcome! Open a pull request to fix a bug, or open an issue to discuss a new feature or change.

Check out the Contributing section in the docs for more info.

License

This project is proudly licensed under the MIT license (LICENSE or http://opensource.org/licenses/MIT).

sensible-env-logger can be distributed according to the MIT license. Contributions will be accepted under the same license.

Authors

You might also like...
Compute and derive metrics by watching a log file
Compute and derive metrics by watching a log file

Export Prometheus metrics from your web server's access log Web servers only offer limited metrics. For example, nginx only offers stub_status unless

SWC Transform to prefix logs. Useful for adding file and line number to logs

SWC Transform to prefix logs. Useful for adding file and line number to logs

Log for concurrent workloads, with support for atomic batches and in-order recovery

sharded-log A batch-oriented multi-threaded sharded log for workloads that occasionally flush logs into some other system. All batches have a 32-bit C

Logging implementation for Rust

log A Rust library providing a lightweight logging facade. log documentation A logging facade provides a single logging API that abstracts over the ac

Structured, contextual, extensible, composable logging for Rust
Structured, contextual, extensible, composable logging for Rust

Getting started Introduction FAQ Crate list slog-rs - The Logging for Rust Introduction (please read) slog is an ecosystem of reusable components for

A highly configurable logging framework for Rust

log4rs log4rs is a highly configurable logging framework modeled after Java's Logback and log4j libraries. Warning If you are using the file rotation

Application level tracing for Rust.

Website | Chat | Documentation (master branch) Overview tracing is a framework for instrumenting Rust programs to collect structured, event-based diag

Task-based logging for rust
Task-based logging for rust

task_log task_log is a task-based logger. Installing Just add task_log = 0.1.4 to your Cargo.toml's dependency section. Example Let's get right to the

💬 A couple of functions to make logging in Rust easier.
💬 A couple of functions to make logging in Rust easier.

Rust logging ⛔ 💬 A couple of functions to make logging in Rust easier. Installation 📦 Just add the code of code.rs to your project. You can copy/pas

Comments
  • local time keep the same format as utc

    local time keep the same format as utc

    Description

    I am so excited that the crate support local time,thank you for the wonderful job. Can you format the loca time with the same format as utc,at least add date prefix?

    enhancement help wanted good first issue acknowledged 
    opened by dobefore 3
Owner
Ritvik Nag
Python / Typescript developer, currently learning Rust 🦀
Ritvik Nag
A pretty, easy-to-use logger for Rust.

pretty-env-logger A simple logger built on top of env_logger. It is configured via an environment variable and writes to standard error with nice colo

Sean McArthur 390 Dec 29, 2022
A standalone, `#![no_std]`-friendly `Logger` crate.

A standalone, #![no_std]-friendly Logger crate. Based on the design of the logger built into the bootloader crate and meant to be used in OS kernels.

Kenny Strawn 1 Feb 6, 2022
Rall is an incredibly simple and intuitive logger

Really...? Another Logging Library? Yes! :P rall is an incredibly simple and intuitive logger, consider this crate a failure if you can't get setup wi

Hamothy 4 Sep 5, 2022
A dead simple logger that works globally and across threads.

Woody A logger for Rust that's *actually* easy to use. Features Easy to use: Just import the macros and you're good to go. No need to configure anythi

Travis A. Wagner 11 Apr 13, 2023
A Rust logger with various features.

Moe Logger (>ω<) Another logger based on pretty-env-logger and env_logger. Allow writing log to file with features like formatting, file rotation. Usa

Rui Li 4 Sep 24, 2021
Another Key Logger Yet. Rust.

Another Key Logger Yet. Rust. For my very first experience of working with Rust, I decided to manage the keyboard, this time by logging and writing th

(Not) Kearash 0 May 3, 2022
A loki logger for the log facade

Loki Logger A loki logger for the log facade. Examples extern crate log; extern crate loki_logger; use log::LevelFilter; #[tokio::main] async fn main

Thomas Nicollet 11 Dec 24, 2022
HTTP request logger

nosy - HTTP request logger How hard can it be to build your own HTTP request logger in Rust? Well, not that easy if you've never written a webapp in R

Manuel Hutter 1 Nov 26, 2021
Firecracker takes your HTTP logs and uses them to map your API flows and to detect anomalies in them.

Who is BLST and what do we do? BLST (Business Logic Security Testing) is a startup company that's developing an automatic penetration tester, replacin

BLST 692 Jan 2, 2023
A rust library for creating and managing logs of arbitrary binary data

A rust library for creating and managing logs of arbitrary binary data. Presently it's used to collect sensor data. But it should generally be helpful in cases where you need to store timeseries data, in a nearly (but not strictly) append-only fashion.

Yusuf Simonson 1 May 9, 2022