Rustで使えるロガーを調べてみます。この記事ではいくつかある実装のうち、

    • env_logger

 

    • simple_logger

 

    stderrlog

を動かしてみました。

log crate

Rustのlog crateにinfo!等のマクロが定義されてますが、用途に応じてその実装を選べる作りになっているようです。

log実装の一覧

Available loggin implementationsの転載です。

    • Simple minimal loggers:

env_logger
simple_logger
simplelog
pretty_env_logger
stderrlog
flexi_logger

Complex configurable frameworks:

log4rs
fern

Adaptors for other facilities:

syslog
slog-stdlog_

env_logger

logの実装でどれを使えばいいのか分かりませんが、crates.ioによるとenv_loggerのダウンロード数が圧倒的に多いようです。

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

use log::Level;
use std::env;

fn main() {
    env::set_var("RUST_LOG", "info");
    // env::set_var("RUST_LOG", "trace");
    logger::init();

    debug!("this is a debug {}", "message");
    error!("this is printed by default");

    if log_enabled!(Level::Info) {
        let x = 3 * 4; // expensive computation
        info!("the answer was: {}", x);
    }
}

実行ファイルの名前がmainとすると、次のような実行結果が得られます。env_loggerのデフォルトログレベルはErrorで、標準エラー出力に書き出されます。ソースコードの中で環境変数のRUST_LOGをInfoに設定しているため、ここではerrorとinfoは出力されていますが、debugは何も出ませんね。

$ ./main
[2019-03-24T14:16:11Z ERROR log_sample] this is printed by default
[2019-03-24T14:16:11Z INFO  log_sample] the answer was: 12

simple_logger

crateの名前の通り、シンプルに標準出力に書き出します

#[macro_use]
extern crate log;
extern crate simple_logger as logger;

use log::Level;

fn main() {
    // logger::init().unwrap();
    logger::init_with_level(Level::Info).unwrap();

    debug!("this is a debug {}", "message");
    error!("this is printed by default");

    if log_enabled!(Level::Info) {
        let x = 3 * 4; // expensive computation
        info!("the answer was: {}", x);
    }
}

実行ファイルの名前がmainとすると、次のような実行結果が得られます。simple_loggerのデフォルトログレベルはtraceですが、そのレベルは簡単に変更できるみたいです。多くのloggerの実装ではこのようなinit関数が用意されているとのことです。

$ ./main
2019-03-24 23:32:48 ERROR [log_sample] this is printed by default
2019-03-24 23:32:48 INFO  [log_sample] the answer was: 12

stderrlog

もう一つくらい、stderrlog試してみます。

#[macro_use]
extern crate log;
extern crate stderrlog as logger;

use log::Level;

fn main() {
    logger::new()
        .module(module_path!())
        .verbosity(2)
        .init()
        .unwrap();

    debug!("this is a debug {}", "message");
    error!("this is printed by default");

    if log_enabled!(Level::Info) {
        let x = 3 * 4; // expensive computation
        info!("the answer was: {}", x);
    }
}

実行結果は次のようになります。タイムスタンプを入れたりもっと細かい設定もできますが、ここではサボっています。実行結果は次のようになります。

$ ./main
ERROR - this is printed by default
INFO - the answer was: 12

注意点としては、stderrlogのverbosityがログレベルに相当するのですが、logcrateのLovelとは微妙にずれているのでverbosity(Level::Info as usize)等とすると期待する結果とずれてしまいました。ソースコードで確認しといたほうが良さそうですね。

    • logのLevel

 

    stderrlogのverbosity

補足(?)

use … as loggerとすればダックタイピングになるかなと期待したのですが、実装ごとに初期化に必要な手順が異なってるのでほとんど意味がありませんでしたorz

参考にした記事など

    • Crate log

 

    • Rustでライブラリのデバッグをする

 

    Rust:logでログ出力を行う

コード

log_sample

广告
将在 10 秒后关闭
bannerAds