Диагностические сообщения

Вывод отладочного сообщения в консоль

log-badge env_logger-badge cat-debugging-badge

Крейт log обеспечивает инструменты для логирования. Крейт env_logger конфигурирует логирование с помощью переменных окружения. Макрос debug! работает подобно другим макросам, принимая строки форматирования по образцу std::fmt.

#[macro_use]
extern crate log;
extern crate env_logger;

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

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

    execute_query("DROP TABLE students");
}

Ничего не выводится после запуска этого кода. По умолчанию, уровень логирования установлен в error, и все сообщения более низкого уровня отбрасываются.

Установка переменной окружения RUST_LOG включает печать:

$ RUST_LOG=debug cargo run

Сначала Cargo печатает отладочную информацию, и затем будет напечатана строка в самом конце вывода на экран:

DEBUG:main: Executing query: DROP TABLE students

Вывод сообщения об ошибке в консоль

log-badge env_logger-badge cat-debugging-badge

Правильная обработка ошибок рассматривает исключительные ситуации как, ну... исключительные. Здесь ошибка выводится в stderr с помощью удобного макроса error!, определённого в крейте log.

#[macro_use]
extern crate log;
extern crate env_logger;

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 {
        error!("Failed to execute query: {}", err);
    }
}

Вывод в stdout вместо stderr

log-badge env_logger-badge cat-debugging-badge

Пример создаёт особую конфигурацию логгера используя Builder::target, чтобы установить стандартный вывод для логирования в Target::Stdout.

#[macro_use]
extern crate log;
extern crate env_logger;

use env_logger::{Builder, Target};

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

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

Логирование сообщений с помощью пользовательского логгера

log-badge cat-debugging-badge

Реализует особый логгер в консоль ConsoleLogger, который печатает в стандартный вывод. Чтобы иметь возможность использовать макросы для логгеров, ConsoleLogger реализует типаж log::Log. Вызов функции log::set_logger подключает логгер.

#[macro_use]
extern crate log;

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);

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

Логирование в Unix syslog

log-badge syslog-badge cat-debugging-badge

Код в примере выводит сообщения в UNIX syslog. Инициализируется движок логирования через syslog::init. Объект syslog::Facility регистрирует программу путём передачи класса логирования, log::LevelFilter определяет уровень логирования, через Option<&str> передаётся необязательное имя программы.

#[macro_use]
extern crate log;
#[cfg(target_os = "linux")]
extern crate syslog;

#[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"))?;
    debug!("this is a debug {}", "message");
    error!("this is an error!");
    Ok(())
}

#[cfg(not(target_os = "linux"))]
fn main() {
    println!("So far, only Linux systems are supported.");
}