Problem
世の中にロギングライブラリはたくさんあります。有名どころでは log4net, NLog とかです。
単純にこれらのロギングライブラリをアプリにリンクすると、万が一ロギングライブラリに問題が生じたり、ログの出力先をWebServiceに投げたい、とかなったらログ出力を記述している個所を全部書き換える必要があります。
(NLogはWebServiceとかDatabaseへ出力することもできますが…)
なので、これらのライブラリとの依存性を減らすべく、ラップするなりします。ましてや、Dependency Injectionならなおさらです。
でも、ここで気づきます。
あれ?ログに出力される呼び出し元メソッド名が全部ラッパーになる\(^o^)/
Solution
幸いにして、log4net、NLogともに解決策があります。
問題は、ログ出力メソッドの呼び出し元を正しく出力することです。
通常は、各ライブラリのメソッドをダイレクトに呼び出しているメソッドのクラスが基点になります。
ですが、ラッパーをかましている場合は、ライブラリのログ出力メソッドを呼び出している箇所との間にラッパーが存在します。
NLogの場合
1 | public interface ILogService |
上がラッパーになります。
ポイントは、Logメソッドになります。
第一引数にラッパークラスの型を渡します。これにより、呼び出し元のメソッドを本来の意図した場所に訂正できます。
スタックトレースを辿っていき、第一引数に渡したクラスの直前の箇所を呼び出し元として判定しているのでしょう。
使い方は下記のようになります。
1 | public sealed class TestService |
ログを出力したいクラスのコンストラクタでILogFactoryService.Createメソッドを呼び出し、ILogServiceを生成します。
実際には内部でNLogのロガーが生成されていますが、それらを隠蔽しています。
log4net
同じように、Logメソッドでラッパーを指定します。
詳細は下記を参照。