【问题标题】:How to add two logger files in .net core using LoggerFactory如何使用 LoggerFactory 在 .net 核心中添加两个记录器文件
【发布时间】:2018-10-10 12:34:36
【问题描述】:
public class Startup
{
    public IConfiguration Configuration { get; } 

    public void ConfigureServices(IServiceCollection services)
    {   
        loggerFactory.AddFile(logFilePath1);
        services.AddSingleton<ILoggerFactory>(loggerFactory);

        loggerFactory.AddFile(logFilePath2);
        services.AddSingleton<ILoggerFactory>(loggerFactory);
    }
}

startup.cs 类中,我创建了两个记录器。既然它有两个记录器,我如何在控制器中设置 Ilogger 数据?可以用正常的方式吗?或者在控制器中记录时是否有任何不同的方式来传递记录器文件名?

【问题讨论】:

  • 提供minimal reproducible example,这将有助于我们更好地了解您的要求。正如目前所写的那样,很难准确地说出你在问什么。请参阅How to Ask 页面以获得澄清此问题的帮助。

标签: asp.net asp.net-core


【解决方案1】:

好的,因此您希望在一个控制器中拥有两个不同的记录器,并且希望这两个记录器记录到不同的文件中。 .NET Core 日志记录对这种情况没有很好的支持,因此它需要一些技巧来实现这一点。每当我发现自己在我正在使用的框架中遇到很多阻力时,我都会重新考虑我正在尝试做的事情是否是个好主意,以及我是否应该使用另一个框架,所以你可能想要做相同。考虑到这一点,这里有一种实现您想要的方法。

记录器可以通过一个类别来识别。在您的情况下,您希望单个控制器具有两个不同的记录器,因此您必须使用 ILoggerFactory 创建记录器(您可以使用通用的 ILogger&lt;T&gt; 接口,但它变得有点奇怪,因为您需要两种不同类型的 @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");
    }
}

记录器的类别是Logger1Logger2

默认情况下,每个记录器都会记录到所有已配置的提供程序。您希望一个类别的记录器记录到一个提供者,而另一个类别的记录器记录到另一个提供者。

虽然您可以创建基于类别、提供程序和日志级别的过滤器,但问题是您希望对这两个类别使用相同的提供程序。提供者由其类型标识,因此您无法创建针对特定提供者实例的规则。如果您为文件提供者创建规则,它将影响所有配置的文件提供者。

这就是黑客攻击的开始:您必须创建自己的提供程序类型,这些类型链接到文件才能过滤每个文件。

.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 - 实际上实现了确保两个不同类别的日志消息正确路由到两个不同类别的预期结果提供者。如果添加了第三个提供者,它将不受这些过滤器的影响,并且来自这两个类别的消息将由第三个提供者记录。

【讨论】:

  • 嘿@Martin,我想你问错了。 OP 想要一种方法来存储为两个不同文件配置的日志。
  • @Manoz:我同意这个问题很容易出错。当我阅读但如何在控制器中设置 Ilogger 数据?时,我将此解释为有关如何在控制器中获取ILogger 实例的问题。我不得不承认,我不明白您所说的 为两个不同的文件配置的存储日志。 坦率地说,我很惊讶您似乎如此确定如何解释原始问题显然可以用多种方式来解释。
  • Martin,当我看到 OP 在startup.cs 中注册了两个文件路径时,我的感觉是。可能这就是让我感到困惑的地方。
  • @Manoz:你必须运用一些猜测来回答这个问题,我的猜测肯定不会比你的好。希望提问者澄清一下。
  • “你必须运用一些猜测来回答这个问题” – 这听起来像是一个完美的理由来关闭投票这个问题不清楚。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-11
  • 2021-02-13
  • 2017-06-16
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
  • 2018-07-31
相关资源
最近更新 更多