大叹号 發表於 2025-3-5 10:05:20

强大的 .NET 日志库Serilog详解

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">1. 日志级别</a></li><li><a href="#_label1">2. 日志输出</a></li><li><a href="#_label2">3. 日志格式</a></li><li><a href="#_label3">4. 安装</a></li><li><a href="#_label4">5. 基础使用示例</a></li><li><a href="#_label5">6. 日志级别示例</a></li><li><a href="#_label6">7. 消息模板</a></li><li><a href="#_label7">8. 日志属性</a></li><li><a href="#_label8">9. 文件输出配置</a></li><li><a href="#_label9">10. 结构化日志记录</a></li><li><a href="#_label10">11. 日志过滤</a></li><li><a href="#_label11">12. 扩展与自定义输出器</a></li><li><a href="#_label12">13. 总结</a></li></ul></div><p>Serilog 是一个功能强大的日志记录库,专为 .NET 平台设计。它提供了丰富的 API 和可插拔的输出器及格式化器,使得开发者能够轻松定制和扩展日志记录功能。在本文中,我们将探索 Serilog 的基础知识、API 使用、配置和一些常见的示例。</p>
<p class="maodian"><a name="_label0"></a></p><h2>1. 日志级别</h2>
<p>Serilog 支持多个日志级别,按照严重性从高到低排列如下:</p>
<ul><li>Fatal: 程序无法继续运行,必须立即解决的问题。</li><li>Error: 发生了错误,需要处理。</li><li>Warning: 警告,需关注但不必立即处理。</li><li>Information: 提供有用的消息,通常用于调试。</li><li>Debug: 调试信息,帮助开发者调试程序。</li><li>Verbose: 详细的日志信息,通常用于复杂问题的调试。</li></ul>
<p class="maodian"><a name="_label1"></a></p><h2>2. 日志输出</h2>
<p>Serilog 支持多种日志输出方式,包括:</p>
<ul><li><strong>Console</strong>: 输出到控制台。</li><li><strong>File</strong>: 输出到文件。</li><li><strong>Seq</strong>: 输出到日志收集器 Seq。</li><li><strong>Elasticsearch</strong>: 输出到 Elasticsearch。</li></ul>
<p>此外,Serilog 也支持自定义日志输出器。</p>
<p class="maodian"><a name="_label2"></a></p><h2>3. 日志格式</h2>
<p>Serilog 提供了多种格式化日志消息的方式:</p>
<ul><li><strong>简单文本格式</strong>:常见的日志输出格式。</li><li><strong>JSON 格式</strong>:适合结构化日志。</li><li><strong>Message Templates 格式</strong>:一种灵活的格式,允许在日志消息中插入占位符。</li></ul>
<p class="maodian"><a name="_label3"></a></p><h2>4. 安装</h2>
<p>Serilog 可以通过 NuGet 安装:</p>
<div class="jb51code"><pre class="brush:plain;">Install-Package Serilog</pre></div>
<p class="maodian"><a name="_label4"></a></p><h2>5. 基础使用示例</h2>
<p>在应用程序中使用 Serilog 十分简单。以下是一个简单的控制台日志输出示例:</p>
<div class="jb51code"><pre class="brush:csharp;">using Serilog;
class Program
{
    static void Main()
    {
      Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .WriteTo.Console()
            .CreateLogger();
      Log.Information("Hello, Serilog!");
      Log.CloseAndFlush();
    }
}</pre></div>
<p>此代码将在控制台输出 <code>Hello, Serilog!</code>。</p>
<p class="maodian"><a name="_label5"></a></p><h2>6. 日志级别示例</h2>
<p>Serilog 允许设置不同的日志级别。以下示例演示了如何记录各种级别的日志消息:</p>
<div class="jb51code"><pre class="brush:csharp;">using Serilog;
class Program
{
    static void Main()
    {
      Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Verbose()
            .WriteTo.Console()
            .CreateLogger();
      Log.Verbose("This is a verbose log message.");
      Log.Debug("This is a debug log message.");
      Log.Information("This is an informational log message.");
      Log.Warning("This is a warning log message.");
      Log.Error("This is an error log message.");
      Log.Fatal("This is a fatal log message.");
      Log.CloseAndFlush();
    }
}</pre></div>
<p class="maodian"><a name="_label6"></a></p><h2>7. 消息模板</h2>
<p>Serilog 支持消息模板,允许开发者在日志中使用占位符。以下示例展示了如何使用消息模板:</p>
<div class="jb51code"><pre class="brush:csharp;">using Serilog;
class Program
{
    static void Main()
    {
      Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .WriteTo.Console(outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}")
            .CreateLogger();
      Log.Information("Hello, {Name}!", "Serilog");
      Log.CloseAndFlush();
    }
}</pre></div>
<p>上述代码将在控制台输出如下格式的日志:</p>
<blockquote><p>2023-09-15 22:23:54.576 +08:00 Hello, Serilog!</p></blockquote>
<p class="maodian"><a name="_label7"></a></p><h2>8. 日志属性</h2>
<p>Serilog 支持在日志中添加附加属性。以下示例展示了如何记录额外的信息:</p>
<div class="jb51code"><pre class="brush:csharp;">using Serilog;
class Program
{
    static void Main()
    {
      Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .WriteTo.Console()
            .CreateLogger();
      Log.Information("Processed {@Count} records in {Time} ms.", new { Count = 10, Time = 123 });
      Log.CloseAndFlush();
    }
}</pre></div>
<p>此代码会输出:</p>
<blockquote><p>Processed { Count: 10, Time: 123 } records in 0 ms.</p></blockquote>
<p class="maodian"><a name="_label8"></a></p><h2>9. 文件输出配置</h2>
<p>Serilog 允许将日志输出到文件,并通过 <code>rollingInterval</code> 设置日志滚动方式。以下示例展示了如何按天滚动文件并设置输出模板:</p>
<div class="jb51code"><pre class="brush:csharp;">Log.Logger = new LoggerConfiguration()
    .WriteTo.File(
      $"logs\\log-.txt",
      rollingInterval: RollingInterval.Day,
      outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}")
    .CreateLogger();
Log.Information("This is a log message!");
Log.CloseAndFlush();</pre></div>
<p>这将创建类似于 <code>log-20230914.txt</code> 的文件,每天一个新文件。</p>
<p class="maodian"><a name="_label9"></a></p><h2>10. 结构化日志记录</h2>
<p>Serilog 支持结构化日志记录,这意味着可以将复杂的数据(如对象、集合等)以结构化的方式存储和输出。例如:</p>
<div class="jb51code"><pre class="brush:csharp;">using Serilog;
class Program
{
    static void Main()
    {
      var weather = new WeatherForecast
      {
            Date = DateTime.Now,
            TemperatureC = 22,
            Summary = "Sunny"
      };
      Log.Information("Weather forecast: {@Weather}", weather);
      Log.CloseAndFlush();
    }
}
public class WeatherForecast
{
    public DateTime Date { get; set; }
    public int TemperatureC { get; set; }
    public string Summary { get; set; }
}</pre></div>
<p>此代码将输出类似于:</p>
<blockquote><p>Weather forecast: {&quot;Date&quot;:&quot;2023-09-15T22:39:53.8634787+08:00&quot;,&quot;TemperatureC&quot;:22,&quot;Summary&quot;:&quot;Sunny&quot;,&quot;$type&quot;:&quot;WeatherForecast&quot;}</p></blockquote>
<p class="maodian"><a name="_label10"></a></p><h2>11. 日志过滤</h2>
<p>Serilog 允许使用过滤器控制输出。以下示例仅输出错误级别以上的日志:</p>
<div class="jb51code"><pre class="brush:csharp;">using Serilog;
class Program
{
    static void Main()
    {
      Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .WriteTo.Console()
            .Filter.ByIncludingOnly(logEvent =&gt; logEvent.Level &gt;= LogEventLevel.Error)
            .CreateLogger();
      Log.Verbose("This is a verbose log message.");
      Log.Error("This is an error log message.");
      Log.CloseAndFlush();
    }
}</pre></div>
<p>此代码只会在控制台输出错误和更高严重级别的日志。</p>
<p class="maodian"><a name="_label11"></a></p><h2>12. 扩展与自定义输出器</h2>
<p>Serilog 支持自定义输出器,允许开发者将日志输出到不同的目的地(例如 Elasticsearch、数据库等)。以下是一个创建自定义控制台输出器的例子:</p>
<div class="jb51code"><pre class="brush:csharp;">using Serilog;
using Serilog.Configuration;
using Serilog.Events;
public static class CustomConsoleSinkExtensions
{
    public static LoggerConfiguration CustomConsole(
      this LoggerSinkConfiguration sinkConfiguration,
      ITextFormatter formatter = null,
      LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum)
    {
      return sinkConfiguration.Sink(
            new CustomConsoleSink(formatter),
            restrictedToMinimumLevel);
    }
}
public class CustomConsoleSink : ILogEventSink
{
    private readonly ITextFormatter _formatter;
    public CustomConsoleSink(ITextFormatter formatter)
    {
      _formatter = formatter ?? throw new ArgumentNullException(nameof(formatter));
    }
    public void Emit(LogEvent logEvent)
    {
      var message = new StringWriter();
      _formatter.Format(logEvent, message);
      Console.WriteLine(message.ToString());
    }
}</pre></div>
<p>然后可以通过以下方式将其添加到日志配置中:</p>
<div class="jb51code"><pre class="brush:csharp;">Log.Logger = new LoggerConfiguration()
    .WriteTo.CustomConsole()
    .CreateLogger();</pre></div>
<p class="maodian"><a name="_label12"></a></p><h2>13. 总结</h2>
<p>Serilog 是一个功能强大的 .NET 日志库,支持丰富的日志记录方式、输出方式和格式化选项。它的可扩展性和灵活性使得开发者能够根据应用程序的需求定制日志记录方式。从简单的控制台日志到复杂的结构化日志和自定义输出器,Serilog 都能轻松应对。</p>
<p>希望本文对您理解 Serilog 和高效使用该库有所帮助!</p>
頁: [1]
查看完整版本: 强大的 .NET 日志库Serilog详解