好的,因此您希望在一个控制器中拥有两个不同的记录器,并且希望这两个记录器记录到不同的文件中。 .NET Core 日志记录对这种情况没有很好的支持,因此它需要一些技巧来实现这一点。每当我发现自己在我正在使用的框架中遇到很多阻力时,我都会重新考虑我正在尝试做的事情是否是个好主意,以及我是否应该使用另一个框架,所以你可能想要做相同。考虑到这一点,这里有一种实现您想要的方法。
记录器可以通过一个类别来识别。在您的情况下,您希望单个控制器具有两个不同的记录器,因此您必须使用 ILoggerFactory 创建记录器(您可以使用通用的 ILogger<T> 接口,但它变得有点奇怪,因为您需要两种不同类型的 @987654323 @):
public class MyController : Controller
{
private readonly ILogger logger1;
private readonly ILogger logger2;
public Controller1(ILoggerFactor loggerFactory)
{
logger1 = loggerFactory.Create("Logger1");
logger2 = loggerFactory.Create("Logger2");
}
}
记录器的类别是Logger1和Logger2。
默认情况下,每个记录器都会记录到所有已配置的提供程序。您希望一个类别的记录器记录到一个提供者,而另一个类别的记录器记录到另一个提供者。
虽然您可以创建基于类别、提供程序和日志级别的过滤器,但问题是您希望对这两个类别使用相同的提供程序。提供者由其类型标识,因此您无法创建针对特定提供者实例的规则。如果您为文件提供者创建规则,它将影响所有配置的文件提供者。
这就是黑客攻击的开始:您必须创建自己的提供程序类型,这些类型链接到文件才能过滤每个文件。
.NET Core 不支持记录到文件,因此您需要第三方提供程序。您尚未指定使用哪个提供程序,因此在此示例中,我将使用 Serilog 文件接收器和允许您将 Serilog 记录器插入 .NET Core 日志记录框架的 Serilog 提供程序。
为了能够过滤提供者,您必须创建自己的提供者。幸运的是,这很容易通过从SerilogLoggerProvider 派生来完成:
class SerilogLoggerProvider1 : SerilogLoggerProvider
{
public SerilogLoggerProvider1(Serilog.ILogger logger) : base(logger) { }
}
class SerilogLoggerProvider2 : SerilogLoggerProvider
{
public SerilogLoggerProvider2(Serilog.ILogger logger) : base(logger) { }
}
这两个提供程序不添加任何功能,但允许您创建针对特定提供程序的过滤器。
下一步是创建两个不同的 Serilog 记录器,它们记录到不同的文件:
var loggerConfiguration1 = new LoggerConfiguration()
.WriteTo.File("...\1.log");
var loggerConfiguration2 = new LoggerConfiguration()
.WriteTo.File("...\2.log");
var logger1 = loggerConfiguration1.CreateLogger();
var logger2 = loggerConfiguration2.CreateLogger();
您通过调用扩展方法.ConfigureLogging 来配置您的登录Main:
.ConfigureLogging((hostingContext, loggingBuilder) =>
{
loggingBuilder
.AddProvider(new SerilogLoggerProvider1(logger1))
.AddFilter("Logger1", LogLevel.None)
.AddFilter<SerilogLoggerProvider1>("Logger1", LogLevel.Information)
.AddProvider(new SerilogLoggerProvider2(logger2))
.AddFilter("Logger2", LogLevel.None)
.AddFilter<SerilogLoggerProvider2>("Logger2", LogLevel.Information);
})
添加每个提供程序(与特定文件关联),然后为每个提供程序配置两个过滤器。我发现过滤器评估规则很难推理,但添加的两个过滤器 - 一个带有LogLevel.None,另一个带有LogLevel.Information - 实际上实现了确保两个不同类别的日志消息正确路由到两个不同类别的预期结果提供者。如果添加了第三个提供者,它将不受这些过滤器的影响,并且来自这两个类别的消息将由第三个提供者记录。