Serilog 多个文件appsettings.json

问题描述 投票:0回答:6

我正在尝试配置 serilog 以写入多个文件,但没有任何运气。 使用此配置,它只写入第二个文件?

{
  "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();
c# serilog
6个回答
8
投票

我找到了解决方案。为 appsettings.json、ErrorLog 和 AuditLog 创建了单独的部分。

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

现在我可以创建 2 个独立的记录器:

            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();

            var errorSection = errorLogConfiguration.GetSection("ErrorLog");
            var auditSection = errorLogConfiguration.GetSection("AuditLog");

            _log = new LoggerConfiguration()
                .ReadFrom
                .ConfigurationSection(errorSection)
                .CreateLogger();

            _auditLog = new LoggerConfiguration()
                .ReadFrom
                .ConfigurationSection(auditSection)
                .CreateLogger();

哪个更适合我的需要。


7
投票

由于 Serilog 和任何接收器的简单文档而苦苦挣扎了几天之后,这最终对我有用,无需创建任何单独的记录器:

"Serilog": {
    "Using": [ "Serilog.Sinks.Async" ],
    "MinimumLevel": "Verbose",
    "Enrich": [ "FromLogContext", "WithDemystifiedStackTraces" ],
    "WriteTo:Information": {
        "Name": "Async",
        "Args": {
            "Configure": [
                {
                    "Name": "RollingFile",
                    "Args": {
                        "RestrictedToMinimumLevel": "Information",
                        "Formatter": "FOOINC.API.Configuration.Logging.CustomRenderedCompactJsonFormatter, FOOINC.API.Configuration",
                        "PathFormat": "_logs\\info\\info-log.json"
                    }
                }
            ]
        }
    },
    "WriteTo:Error": {
        "Name": "Async",
        "Args": {
            "Configure": [
                {
                    "Name": "RollingFile",
                    "Args": {
                        "RestrictedToMinimumLevel": "Error",
                        "Formatter": "FOOINC.API.Configuration.Logging.CustomRenderedCompactJsonFormatter, FOOINC.API.Configuration",
                        "PathFormat": "_logs\\errors\\error-log.json"
                    }
                }
            ]
        }
    }
}

希望这对任何人都有帮助!!


5
投票

我的发现是经过一段时间的错误、重试并由于缺乏有关 Serilog 的文档而几乎放弃。他们在 GitHub 上有足迹:https://github.com/serilog/serilog-filters-expressions/issues/27。几乎每个线程都会得出相同的结论:您必须创建一个 SUBLOGGER。这是我的实现。对于此实现,您需要以下插件:

  • Serilog 过滤器
  • Serilog 接收器
  • Serilog 异步

    "Serilog": {
    "Using": [ "Serilog.Sinks.File" ],
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },
    "WriteTo:Information": { //this name here can be changed
      "Name": "Logger", //this name here is essential
      "Args": {
        "configureLogger": {
          "Filter": [
            {
              "Name": "ByIncludingOnly",
              "Args": {
                "expression": "@Level = 'Information'"
              }
            }
          ],
          "WriteTo": [
            {
              "Name": "Async", //i use async plugin from serilog
              "Args": {
                "configure": [
                  {
                    "Name": "File",
                    "Args": {
                      "path": "Logs/Log_.txt",
                      "formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog",
                      "rollingInterval": "Day",
                      "retainedFileCountLimit": 7
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    },
    

3
投票

通过配置文件进行记录器设置的文档很少。任何人都可以帮忙 - 只是使用记录器设置的示例。在示例中 - 所有日志都写入一个sample.txt。记录对某个 API / api/health 的调用 - 在单独的文件中,并且不包含在 example.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;
    }
}

3
投票

我从我发现的博客中得到了一个很酷的解决方案。它确实表现得很有魅力。如果发生任何问题请告诉我。我还与大家分享博客https://www.techrepository.in/blog/posts/writing-logs-to- Different-files-serilog-asp-net-core。另外,为了过滤日志,您需要使用 Serilog.Eexpressions nuget 包。 希望你能从这里得到你想要的东西

"Serilog": {
"Using": [ "Serilog.Sinks.File", "Serilog.Expressions"  ],
"MinimumLevel": {
  "Default": "Debug"
},
"WriteTo": [
  {
    "Name": "Logger",
    "Args": {
      "configureLogger": {
        "Filter": [
          {
            "Name": "ByIncludingOnly",
            "Args": {
              "expression": "@l = 'Error' or @l = 'Fatal' or @l = 'Warning'"
            }
          }
        ],
        "WriteTo": [
          {
            "Name": "File",
            "Args": {
              "path": "../logs/error_.log",
              "outputTemplate": "{Timestamp:o} [{Level:u3}] ({SourceContext}) {Message}{NewLine}{Exception}",
              "rollingInterval": "Day"
            }
          }
        ]
      }
    }
  },
  {
    "Name": "Logger",
    "Args": {
      "configureLogger": {
        "Filter": [
          {
            "Name": "ByIncludingOnly",
            "Args": {
              "expression": "@l = 'Information' or @l = 'Debug'"
            }
          }
        ],
        "WriteTo": [
          {
            "Name": "File",
            "Args": {
              "path": "../logs/debug_.log",
              "outputTemplate": "{Timestamp:o} [{Level:u3}] ({SourceContext}) {Message}{NewLine}{Exception}",
              "rollingInterval": "Day"
            }
          }
        ]
      }
    }
  }
]},

第 1 步:安装所需的软件包

确保您安装了必要的 Serilog 软件包。您将需要:

Serilog
Serilog.Sinks.File
Serilog.Expressions

说明:

  • Serilog
    部分
    :配置Serilog的接收器和设置。
  • Using
    :列出正在使用的 Serilog 包。
  • MinimumLevel
    :设置默认日志级别。
  • WriteTo
    :定义日志应该写入的位置以及写入条件。
    • 第一个配置块:将
      Error
      Fatal
      Warning
      消息记录到
      error_.log
    • 第二个配置块:将
      Information
      Debug
      消息记录到
      debug_.log
  • Filter
    :使用Serilog的过滤功能,根据表达式仅包含特定的日志级别。
  • WriteTo
    File Sink
    :指定日志的文件路径和输出格式。

-1
投票

我对这个问题做了一些测试。好消息是您的配置有效。您的错误文件可能未创建,因为没有记录错误。

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");
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.