Log Messages

Log a debug message to the console

log env_logger cat-development-tools::debugging

The log⮳ crate provides logging utilities. The env_logger⮳ crate configures logging via an environment variable. The log::debug⮳ macro works like other std::fmt⮳ formatted strings.

fn execute_query(query: &str) {
    log::debug!("Executing query: {}", query);
}

fn main() {
    // env_logger is simple logger that can be configured via environment
    // variables. Example: RUST_LOG=info ./app
    env_logger::init();

    execute_query("DROP TABLE students");
}

No output prints when running this code. By default, the log level is error, and any lower levels are dropped.

Set the RUST_LOG⮳ environment variable to print the message:

RUST_LOG=debug cargo run

Cargo prints debugging information then the following line at the very end of the output:

DEBUG:main: Executing query: DROP TABLE students

Log an error message to the console

log env_logger cat-development-tools::debugging

Proper error handling considers exceptions exceptional. Here, an error logs to stderr with log's convenience macro log::error⮳.

fn execute_query(_query: &str) -> Result<(), &'static str> {
    Err("I'm afraid I can't do that")
}

fn main() {
    env_logger::init();

    let response = execute_query("DROP TABLE students");
    if let Err(err) = response {
        log::error!("Failed to execute query: {}", err);
    }
}

Log to stdout instead of stderr

log env_logger cat-development-tools::debugging

Creates a custom logger configuration using the env_logger::Builder::target⮳ to set the target of the log output to env_logger::fmt::Target

use env_logger::Target;

fn main() {
    env_logger::Builder::new().target(Target::Stdout).init();

    log::error!("This error has been printed to Stdout");
}

Log messages with a custom logger

log cat-development-tools::debugging

Implements a custom logger ConsoleLogger which prints to stdout. In order to use the logging macros, ConsoleLogger implements the log::Log⮳ trait and log::Log⮳ installs it.

use log::Level;
use log::LevelFilter;
use log::Metadata;
use log::Record;
use log::SetLoggerError;

static CONSOLE_LOGGER: ConsoleLogger = ConsoleLogger;

struct ConsoleLogger;

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

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

    fn flush(&self) {}
}

fn main() -> Result<(), SetLoggerError> {
    log::set_logger(&CONSOLE_LOGGER)?;
    log::set_max_level(LevelFilter::Info);

    log::info!("hello log");
    log::warn!("warning");
    log::error!("oops");
    Ok(())
}

Log to the Unix syslog

log syslog cat-development-tools::debugging

Logs messages to UNIX syslog⮳. Initializes logger backend with syslog::initsyslog::init⮳ records the program submitting the log entry's classification, syslog::init⮳ denotes allowed log verbosity and Option<&str> holds optional application name.


#[cfg(target_os = "linux")]
fn main() -> anyhow::Result<()> {
    use syslog::Facility;

    syslog::init(
        Facility::LOG_USER,
        log::LevelFilter::Debug,
        Some("My app name"),
    )?;
    log::debug!("this is a debug {}", "message");
    log::error!("this is an error!");
    Ok(())
}

#[cfg(not(target_os = "linux"))]
fn main() -> anyhow::Result<()> {
    println!("So far, only Linux systems are supported.");
    Ok(())
}