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