2017-11-30 39 views
2

最近私のASP.Netコアプロジェクトにログを追加しました。C#ASP.NET Core Serilogログにクラス名とメソッドを追加する

{タイムスタンプ:YYYY-MM-DD HH:MM:ss.fff ZZZ} [{レベル}] {メッセージ} {改行} {例外}現在のログは、この形式で.txtファイルに書き込みます例えば

2017年11月30日13:58:22.229 01:データベース内に作成された00 [情報]項目。

これは問題ありませんが、この.txtファイルに対して実行されているログのメソッド名とクラス名が必要です。クラスAは、B法とログこれを使用してデータベースに何かを書き込むとき例えば、私は

ClassA.MethodBのようなものを見たいと思います。項目は、データベース内に持っているログイン

すべてのクラスを作成しました

:そのロガーは、私は現在、Serilogを使用して、次のLoggerConfigurationを使用してい

public class ClassA 
{ 
    private readonly ILogger _log; 

    public ClassA(ILogger<ClassA> log){ 
     _log = log; 
    } 

    public void AddItemToDb(Item item){ 
     //Add item 
     //On success: 
     _log.LogInfo("Added item to db."); 
    } 
} 

のような彼らのコンストラクタに注入しました

ログにクラスとメソッドを追加するにはどうすればよいですか?

編集

私はそうのような.WriteTo.Rollingfile()メソッドにカスタムoutputTemplateを追加しました:、名前空間プラスログに追加されるクラスになった

"{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}) {Message}{NewLine}{Exception}") 

唯一の方法は、あなたのロガーの構成では、今

+0

「ILogger」はどのようなタイプですか? Serilogロガーですか?それとも、ASP.NET Coreロガーですか? – mason

+0

Microsoft.Extensions.Logging.ILogger – Jeroen

+0

https://github.com/serilog/serilog/issues/1084#issuecomment-358117004にコードサンプルが追加されました。 –

答えて

1

が不足している、あなたはenrich with the LogContextにする必要があります:

var logger = new LoggerConfiguration() 
    .MinimumLevel.Verbose() 
    .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) 
    .Enrich.FromLogContext() 
    .WriteTo.RollingFile(
     Configuration.GetValue<string>("LogFilePath") + "-{Date}.txt", 
     LogEventLevel.Information) 
    .CreateLogger(); 

しかし、正直なところ、メソッド名を記録するのかどうかは思い出せません。

+1

ドキュメントを見れば、残念なことにメソッド名を取得するための何かを見つけることができません – Jeroen

+0

名前空間のログを記録していたが、メソッドではないことに気付いたので、私の答えは間違っています。 –

+0

あなたは(LogContext.PushProperty( "方法"、MethodBase.GetCurrentMethod()。名)) {// あなたのログもの } '' ' –

1

私はJordan's答えとthis答えの組み合わせを使ってこの問題を解決しました。

Iはenrichmentを通してLOGCONTEXTを添加することにより、私のLoggerconfigurationを変更し、私はoutputTemplateに「方法」プロパティを追加した:

var logger = new LoggerConfiguration() 
    .MinimumLevel.Verbose() 
    .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) 
    .Enrich.FromLogContext() 
    .WriteTo.RollingFile(Configuration.GetValue<string>("LogFilePath") + "-{Date}.txt", LogEventLevel.Information, 
     outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{Method}) {Message}{NewLine}{Exception}") 
    .CreateLogger(); 

Enrich.FromLogContextはLOGCONTEXTを使用してoutputTemplateにプッシュされる特性を可能にします。 PushProperty()メソッド。この場合、 'method'プロパティ(outputTemplateの{Method}に注目してください)。非同期メソッドの

例:これは非同期メソッドのために正常に動作します

public static string GetActualAsyncMethodName([CallerMemberName]string name = null) => name; 

:GetActualAsyncMethodName()は次のように書かれている

using (LogContext.PushProperty("Method", new LogAsyncMethods().GetActualAsyncMethodName())) 
{ 
    _log.LogInformation("Log message."); 
} 

は今非非同期方法のために、これは正常に動作します:

using (LogContext.PushProperty("Method", System.Reflection.MethodBase.GetCurrentMethod().Name)) 
{ 
    _log.LogInformation("Changing of customer name succeeded"); 
} 

今すぐメソッド名がログに表示されています。 SourceContextは、ネームスペース+クラスを追加して添加することにより、それがもたらす「{メソッド}。」:ASP.NETコアは少し遅れていると

Namespace.ClassName.MethodName SeriLogを使用

+3

実行時にリフレクションを使用して現在のメソッドを取得するのは、コストがかかることに注意してください。シナリオに適応できる効率的な代替方法については、ここで説明します。https://stackoverflow.com/questions/29470863/serilog-output-enrich-all-messages-with-methodname-from-which-logententry -was-ca HTH! –

0

組み込みのロガーファクトリを使用している場合は、.NET F/W全体の背後にあります。あなたは、このような拡張メソッドのシリーズを書き込むことによってこの問題を解決することができます

public static class LoggerExtensions 
    { 
     public static void LogAppError<T>(this ILogger<T> logger, EventId eventId, Exception exception, string message, 
      [CallerMemberName] string memberName = "", 
      [CallerFilePath] string sourceFilePath = "", 
      [CallerLineNumber] int sourceLineNumber = 0) 
     { 
      using (var prop = LogContext.PushProperty("MemberName", memberName)) 
      { 
       LogContext.PushProperty("FilePath", sourceFilePath); 
       LogContext.PushProperty("LineNumber", sourceLineNumber); 
       logger.LogError(eventId, exception, message); 
      } 
     } 
} 

次のようなコードあなたからそれを呼び出す:

public PeopleController(ILogger<PeopleController> logger) 
{ 
    _logger.LogAppError("Ctor"); 
} 

これは、あなたがこのような出力テンプレートを持っていることを前提としています

private static string outputTemplate = 
    @"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}Message:{Message}{NewLine}in method {MemberName} at {FilePath}:{LineNumber}{NewLine}{Exception}{NewLine}"; 

拡張メソッドを呼び出すと、それぞれの属性によってメソッド、ファイル、および行番号が取得されます。 LogContextにプロパティをプッシュすると、そのプロパティとそれの後に追加されたプロパティを削除するIDisposableが返されます。したがって、usingステートメントで呼び出しをラップすることによって、LoggerでLogErrorメソッドが呼び出されると、プロパティはコンテキストから削除され、他のロギング呼び出しを汚染しません。

関連する問題