koudenpaのブログ

趣味のブログです。株式会社はてなでWebアプリケーションエンジニアをやっています。職業柄IT関連の記事が多いと思います。

まぜるな危険ライブラリ(Serilog と Microsoft.Extensions.Logging の場合)

SerilogMicrosoft.Extensions.Logging をまぜこぜで使っていたらログレベルの設定でちょっと失敗した話。

背景

.NETのアプリケーションでログを出力するときは大体 Microsoft.Extensions.Logging を使っている。

Webアプリケーションを開発している分には、ログは標準出力や標準エラー出力に出力しておけばあとは実行環境の側でいい感じ処理できる。

最近はWindowsのデスクトップアプリケーションを作っているのでファイルにログを出力したいなぁと思った。

が、どうやらファイルに出力するロガー実装は無いようだった。

ので、Serilogというメジャーっぽいライブラリでファイルに出力していた。

出来事

こんな感じで Microsoft.Extensions.Logging でDebugレベルのデバッグログ*1を構成して、

LoggerFactory = Microsoft.Extensions.Logging.LoggerFactory.Create(builder =>
{
    builder
        .SetMinimumLevel(LogLevel.Debug)
        .AddDebug();
});

こんな感じで Serilog でファイルへのTraceレベル*2のログを構成したら、Traceログが出なかった。

Program.LoggerFactory.AddProvider(new SerilogLoggerProvider(
    new LoggerConfiguration()
        .MinimumLevel.Verbose()
        .WriteTo.File("logs\\srcsform..log", rollingInterval: RollingInterval.Day)
        .CreateLogger()));

どうやら .SetMinimumLevel(LogLevel.Debug) 設定が作用してTraceレベルを出力するように作ったSerilogのロガーまでメッセージが届いていないようだった。

対応

Microsoft.Extensions.Logging では LoggerFactory だけを作って、LoggerはすべてSerilogで作成するようにした。

LoggerFactory = Microsoft.Extensions.Logging.LoggerFactory.Create(builder =>
{
    builder
        .SetMinimumLevel(LogLevel.Trace);
});
LoggerFactory.AddProvider(new SerilogLoggerProvider(
    new LoggerConfiguration()
        .MinimumLevel.Debug()
        .WriteTo.Debug()
        .CreateLogger()));
Program.LoggerFactory.AddProvider(new SerilogLoggerProvider(
    new LoggerConfiguration()
        .MinimumLevel.Verbose()
        .WriteTo.File("logs\\srcsform..log", rollingInterval: RollingInterval.Day)
        .CreateLogger()));

構成はシンプルになったのではなかろうか。

これは別にライブラリをまぜていなくても設定のスコープで親のほうが優先されるってだけの話なのだろうだけれど、まぜるとより見るべきところが増えて分かり辛くなると思う。

同種のライブラリは極力まぜたくないと思った次第。

(今回はインタフェースと実装を分けておきたくて、インタフェースは Microsoft.Extensions.Logging にしたところにいい感じのファイルロガーを仕込みたかったので仕方ない)

そんな感じ。

*1:開発中に眺めているデバッグ出力に出るやつ

*2:SerilogのVerboseとTraceが対応している