
Microsoft.Extensions.Loggingを使用したアダプティブ・ライブラリ・ロギング
私はいかにして心配することをやめ、ログを残すことを愛するようになったか
私のキャリアの中で、私はいくつかの異なる中規模から大規模の.NETプロジェクトに取り組んできました。それぞれのプロジェクトで、異なるタイプのロガーを目にし、通常、すべてのプロジェクトで複数のロガーを使用していました!
初期の頃は、どのロガーを使うか決められなかったので、自分たちで作りました。その後、ロギングを実装した方法が最も効率的でないことに気づいたので、アプリがスケールするにつれてXロガーに切り替えました。古いロガーを削除することは、ソリューションのすべてのファイルを触ることになるのでやりたくなかった。
申し上げたように、これは意外とよくある問題で、ロギングからロガーを抽象化することで回避できる。
Nexmo .NETライブラリのログイン
最近、私はNexmoの .NETサーバーSDKを見て、いくつかのことをクリーンアップしています。そうしているうちに、ロギングフレームワークの LibLogが非推奨になったことです。
このツールは、ロギングの操作からロガーを抽象化するので、素晴らしかった。このツールのおかげで、SDKに対して開発する誰もが、独自のロガーを持ち込むことができました。あなたのロガーがサポートされている限り、SDKのロガーをあなたのロガーにピギーバックさせることができます。
LibLogが非推奨になったため、私たちのニーズを満たすロギング・ツールを他で探すことを余儀なくされました。幸い、遠くを探す必要はなかった。
Microsoft.Extensions.Loggingで前進する
比較的)新しい Microsoft.Extensions.Loggingパッケージは、機能性において正鵠を射ている。拡張パッケージを使用すると、NuGetパッケージと使用するロギングフレームワークをインストールし、ファクトリーをセットアップし、ロガーを作成するだけです。
これは私たちのユースケースに適している。なぜなら、私たちのログがユーザーのログに自動的にピギーバックしたり、インターリーブしたりすることを必ずしも望んでいないからである。
そのため、次のメジャーバージョンリリースである5.0.0では、SDKのロガーファクトリーを入れ替えるだけで、SDK内で好きなレベルやカテゴリーを動的にアクティブ化できるようになります。
Microsoft.Extensions.Loggingでロガーを構築する
ログ・プロバイダの構築
Microsoft.Extensions.Loggingを支える2つのコンポーネント:ILoggerFactory と ILogger です。ファクトリーはロガーを生成し、ロガーはロギングを行います。
これらの2つのコンポーネントは、LogProviderクラスで使用され、完全に動的で拡張可能なライブラリのロガーを作成することができます。
public static class LogProvider
{
private static IDictionary<string, ILogger> _loggers = new Dictionary<string, ILogger>();
private static ILoggerFactory _loggerFactory = new LoggerFactory();
public static void SetLogFactory(ILoggerFactory factory)
{
_loggerFactory?.Dispose();
_loggerFactory = factory;
_loggers.Clear();
}
public static ILogger GetLogger(string category)
{
if (!_loggers.ContainsKey(category))
{
_loggers[category] = _loggerFactory?.CreateLogger(category)?? NullLogger.Instance;
}
return _loggers[category];
}
}このモデルでは、2つのフィールドを持つLogProviderという静的クラスを作成します:各カテゴリのロガーを含む辞書である _loggers と、ロガーを構築する _loggerFactory です。
また、2つのメソッドがある:古いLogFactoryを破棄し、ログファクトリを渡された新しいログファクトリに設定するSetLogFactoryと、_loggersをチェックしてそのカテゴリのロガーが作成されているかどうかを確認し、作成されていない場合は作成するGetLoggerです。
ログプロバイダーの使用
これで、ログを取りたいメソッドの開始時に、適切なカテゴリーでGetLoggerを呼び出すだけです:
var logger = Api.Logger.LogProvider.GetLogger(LOGGER_CATEGORY); ロギング
ここからは、これまで見てきた他のロガーと同じように、ロガーを使用するだけです。例えば
logger.LogInformation("Available authentication: {0}", string.Join(",", authCapabilities));これは、ロガーに提供したフォーマットで、利用可能な認証機能を情報としてログに記録します。
アダプティブ・ロガーの設定
さて、ロガーの作成と利用について説明したので、実際にロガーを設定し、望んだことを実行できるようにしてみましょう。
ログプロバイダーの選択
Microsoft.Extensions.Loggingのクールな点の一つは、使用するログ・プロバイダに依存しないことです。ログプロバイダが ILogProviderインターフェイスを実装している限り、好きなものにすることができます。そして、それを活用しようとする開発者の観点からは、さらにシンプルです。ほとんどの主要なサードパーティのログプロバイダー(Log4Net、Serilog、NLogなど)には、必要なロガーを簡単に追加できる拡張パッケージがあります。
Serilogによるコンソールへのログ記録
これらのロガーをどのように構築できるかを示すために、Serilogでコンソールをログアウトする例を見てみましょう。これを行うには、以下のNuGetパッケージが必要です:
Microsoft.Extensions.Logging
Serilog.Extensions.Logging
セリログ・シンク・コンソール
その後、以下のことを行う:
新しいLoggerFactoryを作成する。
Serilogコンフィギュレーションを設定する新しいLoggerConfigurationを作成します。
ファクトリーでAddSerilog関数を呼び出す。
カテゴリー'test'のロガーを作成する。
ログアウト
連鎖するとこうなる:
var log = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console(outputTemplate: "{Timestamp:HH:mm} [{Level}] ({Name:l}) {Message}\n")
.CreateLogger();
var factory = new LoggerFactory();
factory.AddSerilog(log);
ILogger logger = factory.CreateLogger("test");
logger.LogInformation("Hello world");とてもクリーンでシンプルだ。
Nexmo SDKとやり取りするには、ファクトリーを設定した後にロガーを作成するのではなく、ログプロバイダーのLogFactoryを、作成しSerilogを追加したログファクトリーに設定するだけです。
var log = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console(outputTemplate: "{Timestamp:HH:mm} [{Level}] ({Name:l}) {Message}\n")
.CreateLogger();
var factory = new LoggerFactory();
factory.AddSerilog(log);
LogProvider.SetLogFactory(factory);これで、高度に設定可能な独自のライブラリ・ロガーが完成しました。
メリット
Microsoft.Extensions.Loggingによって、あるロガーを使ってプロジェクトを開始し、何らかの理由で別のロガーに切り替える必要があるという悪夢のようなシナリオを避けることができます。
自分のロガーを使用したい場合は、ロギング拡張機能を使用している間でも、自由に使用できます。必要なのは、使用したいロガーで ILogProvider インターフェースを実装し、それをファクトリーに追加することだけです。