【问题标题】:Serilog : choose which sink to log at runtimeSerilog :选择在运行时记录哪个接收器
【发布时间】:2021-01-08 11:40:50
【问题描述】:

我将在 .net 标准 2.0 库中实现 Serilog。 我正在寻找一种方法来选择每个日志行应该使用哪个接收器。

假设我们在配置(控制台和文件)中定义了 2 个接收器:

    Log.Logger = new LoggerConfiguration()
        .MinimumLevel.Debug()
        .WriteTo.Console()
        .WriteTo.File("c:\\temp\\SerilogTets.txt")
        .CreateLogger();

在此之后,我们将编写一条日志规则:

Log.Information("Hello, world!");  //<- how can we define which sink we want to use

我正在寻找一种方法来定义应该为哪些接收器记录这些行:

  • 控制台和文件
  • 仅限控制台
  • 仅文件

不依赖于它是什么日志级别。

提前谢谢你!

亲切的问候, 库尔特

【问题讨论】:

  • 您可以通过在配置中指定过滤条件来做到这一点。应用程序代码不应该对接收器有任何了解。这违背了使用日志库的初衷——将应用程序代码与日志接收器分离。
  • 此外,如果您不解释选择一个或另一个水槽的标准是什么,就无法告诉您如何选择水槽。
  • @PanagiotisKanavos 说了什么,请参阅stackoverflow.com/questions/46516359/…
  • 感谢您的快速回复。主要原因是:出于安全原因,我们确实只想将数据记录到日志文件中。其他日志信息可能会记录到应用程序洞察中。更重要的是,我们希望能够选择我们想要推动应用洞察力和不推动什么。
  • 这就是记录器配置中的过滤功能。您可以按类别和额外的上下文属性指定过滤器

标签: c# .net-standard serilog sink


【解决方案1】:

在 Serilog 中,您可以通过sub-loggers 使用filters 或通过Serilog.Sinks.Map 进行这种分离,使用context properties 来决定哪个记录器将包含或排除某些消息。

下面的例子定义了所有的日志事件都将被写入控制台和文件,默认情况下,但是如果日志事件在日志上下文中有一个名为FileOnly的属性,它不会被写入控制台,同样如果日志事件有一个名为ConsoleOnly的属性,它不会被写入文件。

using Serilog;
using Serilog.Context;
using Serilog.Filters;
// ...

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Verbose()
    .Enrich.FromLogContext()
    .WriteTo.Logger(c =>
        c.Filter.ByExcluding(Matching.WithProperty("FileOnly"))
            .WriteTo.Console())
    .WriteTo.Logger(c =>
        c.Filter.ByExcluding(Matching.WithProperty("ConsoleOnly"))
            .WriteTo.File("C:\\Temp\\SerilogTests.txt"))
    .CreateLogger();

// Writes to both Console & File
Log.Information("Hello, world! (Console and File)");

using (LogContext.PushProperty("ConsoleOnly", value: true))
{
    // Writes only to the Console
    Log.Information("Hello, world! (Console)");
}

using (LogContext.PushProperty("FileOnly", value: true))
{
    // Writes only to the File
    Log.Information("Hello, world! (File Only)");
}

Log.CloseAndFlush();

注意:理想情况下,您会想出更通用的更好的属性名称,这样当您在应用程序中编写日志时,它不必知道任何关于“控制台”或“文件”的信息。例如您可以拥有一个名为 SecretClassified 的属性,并根据此属性的存在与否决定在何处写入日志。

给日志事件添加属性有多种方式,包括在你Log.Information时直接在消息模板中添加属性等,如上例通过LogContext.PushProperty和viLog.ForContext

您可以在此处查看过滤、子记录器和 Serilog.Sinks.Map 的其他示例:

【讨论】:

  • 感谢您的回答。我之前确实找到了这个,但我遇到的问题是它还会在日志文件中记录(控制台)和(仅文件)。
  • @KurtColemonts 我不确定我理解你的意思。你想用更多细节更新你的问题吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-17
  • 2014-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多