LoginSignup
14
10

More than 5 years have passed since last update.

Rustでのロギング

Last updated at Posted at 2019-03-24

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

  • env_logger
  • simple_logger
  • stderrlog

を動かしてみました。

log crate

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

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_LOGInfoに設定しているため、ここではerrorinfoは出力されていますが、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)等とすると期待する結果とずれてしまいました。ソースコードで確認しといたほうが良さそうですね。

補足(?)

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

参考にした記事など

コード

log_sample

14
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
10