Удаление отладочных макросов в Rust - PullRequest
0 голосов
/ 23 января 2019

Я пишу приложение, которое использует slog для регистрации нескольких вещей во время его выполнения. Поэтому я широко использую макросы info!, error!, warn! и debug!.

Однако, как и ожидалось, вызовы debug! помогают мне отлаживать приложения, и я не хочу, чтобы эти вызовы загрязняли журналы при фактическом использовании приложения.

Я пытался собрать их без успеха. Это строка, которую я использую: RUSTFLAGS="$RUSTFLAGS -C debug-assertions" cargo build --release

Компиляция идет гладко, но при выполнении я вижу все вызовы отладки.

Ниже приведен рабочий пример моей проблемы:

Cargo.toml:

[dependencies]
slog = { version = "1.5", features = ["max_level_trace", "release_max_level_warn"] }
slog-stream = "1.2.0"
slog-term = "1.5.0"
slog-json = "1.2.1"
slog-stdlog = "1.1.0"
log = "0.3.7"

main.rs:

#[macro_use]
extern crate slog;
extern crate slog_stream;
extern crate slog_term;
extern crate slog_json;
extern crate slog_stdlog;
#[macro_use]
extern crate log;

use std::path::Path;
use std::fs::OpenOptions;
use slog::DrainExt;

fn init_logger(work_dir : &Path) {
    let mut log_dir_buf = work_dir.to_path_buf();
    log_dir_buf.push("log");

    if !log_dir_buf.exists() {
        std::fs::create_dir(log_dir_buf.as_path()).unwrap();
    }

    log_dir_buf.push("the_log_file.log");
    let log_file_name = log_dir_buf.to_str().unwrap();

    let log_file = OpenOptions::new()
                        .create(true)
                        .write(true)
                        .truncate(true)
                        .open(log_file_name).unwrap();

    let console_drain = slog_term::streamer().build();
    let file_drain = slog_stream::stream(log_file, slog_json::default());
    let logger = slog::Logger::root(slog::duplicate(console_drain, file_drain).fuse(), o!());
    slog_stdlog::set_logger(logger).unwrap();
} 

fn main() {
    init_logger(Path::new("."));

    info!("This is an info message");
    warn!("This is a warn message");
    error!("This is an error message");
    debug!("This is a debug message");
}

Теперь, создав версию релиза, как указано выше, и запустив бинарный файл, я получаю следующий вывод:

Jan 23 17:20:56.640 INFO This is an info message
Jan 23 17:20:56.641 WARN This is a warn message
Jan 23 17:20:56.641 ERRO This is an error message
Jan 23 17:20:56.641 DEBG This is a debug message

Наконец, версия ржавчины: rustc 1.31.0 (abe02cefd 2018-12-04)

Я знаю, что версия slog, которую я использую, старая, но в данный момент обновление зависимости не является приоритетом. Тем не менее, в документации версии говорится, что фильтрация журнала должна быть возможной, как @shepmaster описывает в связанном ответе , но мне кажется, что она не работает. Чего мне не хватает?

Ответы [ 3 ]

0 голосов
/ 23 января 2019

Ящик slog использует опцию codegen debug-assertions, чтобы различать сборки "release" и "debug".Таким образом, при включении debug-assertions (путем передачи -C debug-assertions компилятору через RUSTFLAGS), slog не учитывает флаги функции release_max_level_*.

debug-assertions отключеныпо умолчанию в сборках релиза, поэтому, если вы не хотели включать debug-assertions, просто не передавайте этот флаг компилятору.Также обратите внимание, что вы можете включить или отключить debug-assertions через [profile.*] разделы в Cargo.toml.

0 голосов
/ 30 января 2019

Чтобы упростить проблему, я сделал еще один рабочий пример с текущей версией slog (2.4.1), в которой установлен регистратор глобальной области видимости, а проблема все еще воспроизводится . Вот пример кода:

extern crate slog;
extern crate slog_async;
extern crate slog_json;
extern crate slog_term;
extern crate slog_scope;
extern crate slog_stdlog;
#[macro_use]
extern crate log;

fn complex_logging() -> Result<(), log::SetLoggerError> {
    //Create the output file
    let log_path = "your_log_file_path.log";
    let file = OpenOptions::new()
        .create(true)
        .write(true)
        .truncate(true)
        .open(log_path)
        .unwrap();

    //Create the terminal drain
    let decorator = slog_term::TermDecorator::new().build();
    let d1 = slog_term::FullFormat::new(decorator).build().fuse();
    let d1 = slog_async::Async::new(d1).build().fuse();

    //Create the file drain
    let d2 = slog_json::Json::new(file)
        .add_default_keys()
        .build()
        .fuse();
    let d2 = slog_async::Async::new(d2).build().fuse();

    //Fuse the drains and create the logger
    let logger = slog::Logger::root(slog::Duplicate::new(d1, d2).fuse(), o!());
    let _guard = slog_scope::set_global_logger(logger);

    //register slog_stdlog as the log handler with the log crate
    slog_stdlog::init().unwrap();


    trace!("logging a trace message");
    debug!("debug values \"x\" => 1, \"y\" => -1");
    info!("some interesting info; where => right here");
    warn!("be cautious!; why => you never know...");
    error!("wrong, foobar; type => unknown");

    Ok(())
}

fn main() {
  let _res = complex_logging();    
}

Запуск приведенного выше примера после сборки для релиза дает следующий результат:

Jan 30 13:53:52.398 TRCE logging a trace message
Jan 30 13:53:52.399 DEBG debug values "x" => 1, "y" => -1
Jan 30 13:53:52.399 INFO some interesting info; where => right here
Jan 30 13:53:52.399 WARN be cautious!; why => you never know...
Jan 30 13:53:52.399 ERRO wrong, foobar; type => unknown

Однако, новый пример, который передает регистраторы вокруг, решает проблему. Вот рабочий пример:

#[macro_use]
extern crate slog;
extern crate slog_async;
extern crate slog_json;
extern crate slog_term;
extern crate slog_scope;
extern crate slog_stdlog;

use slog::Drain;
use std::fs::OpenOptions;
use std::io;
use std::sync::Mutex;

fn duplicate_log() {
    let plain = slog_term::PlainSyncDecorator::new(std::io::stdout());
    let d1 = slog_term::FullFormat::new(plain).build().fuse();
    let d2 = Mutex::new(slog_json::Json::default(io::stdout())).fuse();
    let log = slog::Logger::root(slog::Duplicate::new(d1, d2).fuse(), o!("version" => env!("CARGO_PKG_VERSION")));

    trace!(log, "logging a trace message");
    debug!(log, "debug values"; "x" => 1, "y" => -1);
    info!(log, "some interesting info"; "where" => "right here");
    warn!(log, "be cautious!"; "why" => "you never know...");
    error!(log, "wrong {}", "foobar"; "type" => "unknown");
    crit!(log, "abandoning test");
}

fn main() {
   duplicate_log();
}

Выполнение рабочего примера дает следующий результат:

Jan 30 13:56:30.839 INFO some interesting info, where: right here, version: 0.1.0
{"msg":"some interesting info","level":"INFO","ts":"2019-01-30T13:56:30.839762+00:00","version":"0.1.0","where":"right here"}
Jan 30 13:56:30.839 WARN be cautious!, why: you never know..., version: 0.1.0
{"msg":"be cautious!","level":"WARN","ts":"2019-01-30T13:56:30.839787+00:00","version":"0.1.0","why":"you never know..."}
Jan 30 13:56:30.839 ERRO wrong foobar, type: unknown, version: 0.1.0
{"msg":"wrong foobar","level":"ERRO","ts":"2019-01-30T13:56:30.839802+00:00","version":"0.1.0","type":"unknown"}
Jan 30 13:56:30.839 CRIT abandoning test, version: 0.1.0
{"msg":"abandoning test","level":"CRIT","ts":"2019-01-30T13:56:30.839815+00:00","version":"0.1.0"}

Если вы столкнулись с подобной проблемой, как я, моя проблема заключалась в настройке регистратора глобальной области действия . Обход логгеров решает эту проблему.

0 голосов
/ 23 января 2019

Эта ссылка может оказаться полезной в вашей ситуации.

Согласно документации, указанной выше,

вызовы debug! и trace! включены в программу, только если debug-assertions=yes включен в конфигурации .toml

Вы проверили файл config.toml , чтобы узнать, установлено ли для debug-assertions значение yes?

...