私の API は、さまざまなタイプのコンシューマーによってアクセスされます。外部アプリケーションと Web インターフェイス経由のユーザーがあります。
例を挙げて説明します。つまり、メソッド呼び出しで、誰が、または何がアクセスしたかをログに記録したいと思います。
外部アプリケーションの場合、次のようにログに記録したいと思います (テンプレートを使用):
"[{Caller}] {Timestamp:HH:mm:ss} [{Level}] (RequestId:{RequestId} | Key:{Key} | AppVersion:{Version}) {Message}{NewLine}{Exception}"
ユーザーがトリガーしたアクションの場合、次のようなログを記録したいと思います。
"[{Caller}] {Timestamp:HH:mm:ss} [{Level}] FullName:{FullName} | Organization:{Organization} | AppVersion:{Version}) {Message}{NewLine}{Exception}"
両方のタイプのメソッド呼び出し元が からアクセスされますがThread.CurrentPrincipal.Identity
、それぞれが異なるカスタム プロパティを使用して、異なるタイプの ID を実装します。
私のコードは次のようになります。
public void DoSomething()
{
Log.Information("DoSomething called");
}
ロガーを次のように構成した場合:
var logger = new LoggerConfiguration()
.Enrich.WithProperty("Version", appVersion)
.Enrich.WithProperty("Caller", caller)
.Enrich.With(new MyEnricher())
.WriteTo.ColoredConsole(outputTemplate: "[{Caller}] {Timestamp:HH:mm:ss} [{Level}] FullName:{FullName} | Organization:{Organization} | AppVersion:{Version}) {Message}{NewLine}{Exception}")
.CreateLogger();
外部アプリケーション (スレッド ID) によってトリガーされて呼び出された場合、Key と RequestId は表示されません。
MyEnricher
私はロガーに追加しましたが、次のようなものです:
public class MyEnricher : ILogEventEnricher
{
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
var identity = Thread.CurrentPrincipal.Identity;
if (identity is ExternalIdentity)
{
var externalIdentity = Thread.CurrentPrincipal.Identity as ExternalIdentity;
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("Key", externalIdentity.Key));
logEvent.AddOrUpdateProperty(propertyFactory.CreateProperty("RequestId", externalIdentity.RequestId));
}
else
{
var userIdentity = Thread.CurrentPrincipal.Identity as UserIdentity;
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("FullName", userIdentity.FullName));
logEvent.AddOrUpdateProperty(propertyFactory.CreateProperty("Organization", userIdentity.OrganizationName));
}
}
オンラインのドキュメントと例から把握できる限り、ロギング テンプレートは、実際に作成される前の、ロガーを構成する瞬間にのみ設定されます。エンリッチャーは読み取り専用 (getter のみ) であるため、LogEvent 経由でエンリッチャーにアクセスして変更できませんでした。
メッセージのフォーマットの可能性は認識していますが、これはこの特定のケースで探しているものではありません。
外部アプリへのアクセスについて、ログに表示したい最終結果は次のようなものです。
2016 年 1 月 17 日 10:11:42.524 [API] 10:11:40 [情報] (RequestId: 123 | キー: XXX-1 | AppVersion:1.2.1) DoSomething が呼び出されました
そして、ユーザーのためにログに記録されたとき:
2016 年 1 月 17 日 11:12:42.524 [WEB] 11:12:40 [情報] (FullName: Anonymous | Organization: MyOrg | AppVersion:1.2.1) DoSomething と呼ばれる
私の質問は、テンプレートにログインするために、さまざまなプロパティを持つさまざまな種類のイベントを (可能であれば) ログに記録 (およびログで確認) するにはどうすればよいですか? その場で実行時にテンプレートを操作することは可能ですか? 両方または他の多くの可能なイベント タイプからのすべての可能なトークンと、それらのプロパティが 1 か所で定義されたテンプレートを持ちたくありません (いずれかのケースでそれらの多くが空白になっています)。