Log Messages

Log a debug message to the console

log-badge env_logger-badge cat-debugging-badge

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::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-badge env_logger-badge cat-debugging-badge

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-badge env_logger-badge cat-debugging-badge

Creates a custom logger configuration using the Builder::target to set the target of the log output to Target::Stdout.


use env_logger::{Builder, Target};

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

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

Log messages with a custom logger

log-badge cat-debugging-badge

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

use log::{Record, Level, Metadata, LevelFilter, 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-badge syslog-badge cat-debugging-badge

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

#[cfg(target_os = "linux")]
#[cfg(target_os = "linux")]
use syslog::{Facility, Error};

#[cfg(target_os = "linux")]
fn main() -> Result<(), Error> {
    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() {
    println!("So far, only Linux systems are supported.");
}