web-dev-qa-db-ja.com

Serilog複数ファイルappsettings.json

まったく運がなくても、serilogを複数のファイルに書き込むように構成しようとしています。この構成では、2番目のファイルに書き込むだけですか?

{
  "AllowedHosts": "*",
  "Serilog": {
    "Using": [ "Serilog.Sinks.File" ],
    "MinimumLevel": "Debug",
    "WriteTo": [
      {
        "Name": "File",
        "Args": {
          "path": "c:\\temp\\audit-.log",
          "rollingInterval": "Day",
          "restrictedToMinimumLevel": "Information"
        }
      },
      {
        "Name": "File",
        "Args": {
          "path": "c:\\temp\\error-.log",
          "rollingInterval": "Day",
          "restrictedToMinimumLevel": "Error"
        }
      }
    ]
  }
}

または、appsettings.jsonとは異なる設定で多くのロガーをソフトウェアにロードする方法はありますか?このようなもの?

var errorLogConfiguration = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
    .AddEnvironmentVariables()
    .Build();

_log = new LoggerConfiguration()
    .ReadFrom
    .Configuration(errorLogConfiguration)
    .CreateLogger();
5
TuomasK

この問題についていくつかのテストを行いました。良いニュースは、設定が機能することです。エラーが記録されないため、エラーファイルはおそらく作成されません。

最初のメッセージがそのファイルに記録されると、Serilogはログファイルを作成します。この簡単なプログラムを実行し、エラーのログを(コメント解除)すると、これを確認できます。

class Program
{
    static void Main(string[] args)
    {
        var errorLogConfiguration = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("settings.json", optional: false, reloadOnChange: true)
            .Build();

        var log = new LoggerConfiguration()
            .ReadFrom
            .Configuration(errorLogConfiguration)
            .CreateLogger();
        log.Warning("Warning");
        log.Error("Error");
    }
}
0
Pretasoc

構成ファイルを介したロガー設定に関するドキュメントはほとんどありません。誰でも助けることができます-ロガーの設定を使用する例にすぎません。例では、すべてのログが1つのsample.txtに書き込まれます。特定のAPI/api/healthの呼び出しのログ-別のファイルにあり、sample.txtには含まれません。そしてサンプル広告-IMyLoggerは別のSampleMy.txtに書き込みます。多くのセクションを追加し、さまざまな基準でログを分割できます。ローカルログレベルを最小限に設定することをお勧めします。これらはグローバルレベルによって上書きされます。グローバルフィルターは、すべてのサブロガーからログを除外します(私は使用しません)。 PSは悪い英語でごめんなさい)

"Serilog": {
    "MinimumLevel": "Information", //<- global error level. Ovveride all local error level
    "WriteTo": [
      {
        "Name": "Console"
      },
      {
        "Name": "Logger",
        "Args": {
          "configureLogger": {
            "MinimumLevel": "Debug", // <- local error level. 
            //Only records with Information logging level will be written to the log file
           //but if ovveride global level to Debug, and dont override local error level -> it will still be global
            "WriteTo": [
              {
                "Name": "File",
                "Args": {
                  "path": "log\\SampleHealthCheck-.txt", //write health-check log in different file
                  "rollingInterval": "Day",
                  "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] [CorrId:{CorrelationId}] [Op:{OperationId}] [U:{UserName}] {Message:lj}{NewLine}{Exception}"
                }
              }
            ],
            "Filter": [
              {
                "Name": "ByIncludingOnly",
                "Args": {
                  "expression": "RequestPath like '%/api/health'"
                }
              }
            ]
          }
        }
      },
      {
        "Name": "Logger",
        "Args": {
          "configureLogger": {
            "MinimumLevel": "Debug",
            "WriteTo": [
              {
                "Name": "File",
                "Args": {
                  "path": "log\\SampleMy-.txt", //Write some log in different file. Control through code 
                  "rollingInterval": "Day",
                  "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] [CorrId:{CorrelationId}] [Op:{OperationId}] [U:{UserName}] {Message:lj}{NewLine}{Exception}"
                }
              }
            ],
            "Filter": [
              {
                "Name": "ByIncludingOnly",
                "Args": {
                  "expression": "SourceContext = 'MyProject.IMyLogger'"
                }
              }
            ]
          }
        }
      },
      {
        "Name": "Logger",
        "Args": {
          "configureLogger": {
            "MinimumLevel": "Information",
            "WriteTo": [
              {
                "Name": "File",
                "Args": {
                  "path": "log\\Sample-.txt", //all logs, without health-check
                  "rollingInterval": "Day",
                  "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] [CorrId:{CorrelationId}] [Op:{OperationId}] [U:{UserName}] {Message:lj}{NewLine}{Exception}"
                }
              }
            ],
            "Filter": [
              {
                "Name": "ByExcluding",
                "Args": {
                  "expression": "RequestPath like '%/api/health'"
                }
              }
            ]
          }
        }
      }
    ],
    "Enrich": [
      "WithProcessName"
    ],
    "Properties": {
      "Application": "Sample",
      "Environment": "Test"
    }
  }

public class MyCommandHandler : IRequestHandler<MyCommand, Unit>
{
    private readonly ILogger _myLogger;
    private static int _count;

    public MyCommandHandler()
    {
        _myLogger = Log.ForContext<IMyLogger>();
    }

    public async Task<Unit> Handle(MyCommand request, CancellationToken cancellationToken)
    {
        _count++;

        Log.Debug("MyCommandHandler Count call = {count}",_count ); //write sample.txt
        Log.Information("MyCommandHandler Count call = {count}",_count ); //write in sample.txt
        Log.Error("MyCommandHandler Count call = {count}",_count); //write in sample.txt

        _myLogger.Information("Log from IMyLogger", _count); //write in sample.txt and in sampleMy.txt

        return Unit.Value;
    }
}
0