商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > 强大的.NET日志库Serilog详解

强大的.NET日志库Serilog详解

  发布于2026-07-23 阅读(0)

扫一扫,手机访问

要说 .NET 生态里最受欢迎的日志库,Serilog 绝对排得上号。它设计得相当精巧——API 丰富、架构灵活,输出端和格式化器都是可插拔的,开发者几乎可以按需定制。下面就从基础概念开始,一步步把它拆开看看。

1. 日志级别

Serilog 按严重程度把日志分为六个级别,从高到低排列:

  • Fatal:程序已经无法继续跑,必须立刻处理。
  • Error:出了错误,需要介入修复。
  • Warning:值得警惕,但暂时不用动。
  • Information:提供一些有用的状态信息,通常用来跟踪流程。
  • Debug:调试用的,帮开发者定位问题。
  • Verbose:最详细的日志,适合排查复杂疑难。

2. 日志输出

Serilog 原生支持多种输出目标(也就是 Sink),用得比较多的有:

  • Console:直接打印到控制台。
  • File:写到文件里。
  • Seq:发送到日志收集平台 Seq。
  • Elasticsearch:写入 Elasticsearch 做集中存储和搜索。

当然,如果这些都不够用,还可以自己写一个自定义输出器。

3. 日志格式

Serilog 提供了几种格式化日志消息的方式:

  • 简单文本格式:最常见的纯文本输出。
  • JSON 格式:适合做结构化日志,便于后续解析。
  • Message Templates 格式:一种非常灵活的方式,支持在消息里嵌入占位符,既能保持可读性,又能做到结构化。

4. 安装

通过 NuGet 直接安装就行:

Install-Package Serilog

5. 基础使用示例

用 Serilog 写日志其实很简单。下面是一个最基础的控制台输出例子:

using Serilog;

class Program
{
    static void Main()
    {
        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .WriteTo.Console()
            .CreateLogger();

        Log.Information("Hello, Serilog!");

        Log.CloseAndFlush();
    }
}

运行之后,控制台就会打印出 Hello, Serilog! 这条信息。

6. 日志级别示例

设置不同的最小级别,就能控制哪些日志会被输出。下面的例子把级别降到 Verbose,然后依次记录了各个级别的消息:

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

7. 消息模板

消息模板是 Serilog 的一大亮点。你可以在日志中插入 {Name} 这样的占位符,运行时会被实际值替换:

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

输出效果类似这样:

2023-09-15 22:23:54.576 +08:00 [INF] Hello, Serilog!

8. 日志属性

除了简单的占位符,你还可以在日志里附加更复杂的属性——比如用匿名对象:

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

输出会把这个匿名对象的字段展开:

Processed { Count: 10, Time: 123 } records in 0 ms.

9. 文件输出配置

把日志写到文件里也很常见。通过 rollingInterval 可以控制文件按天滚动:

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

这样每天会生成一个类似 log-20230914.txt 的文件,非常便于按日期归档。

10. 结构化日志记录

Serilog 支持真正的结构化日志——你可以直接把一个对象整体写进去,它会自动序列化并保留结构:

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; }
}

输出结果会是一个 JSON 风格的字符串,保留所有属性和类型:

Weather forecast: {"Date":"2023-09-15T22:39:53.8634787+08:00","TemperatureC":22,"Summary":"Sunny","$type":"WeatherForecast"}

11. 日志过滤

有时候只想输出特定级别的日志,Serilog 的过滤器可以帮上忙。比如只保留 Error 及以上的消息:

using Serilog;
using Serilog.Events;

class Program
{
    static void Main()
    {
        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .WriteTo.Console()
            .Filter.ByIncludingOnly(logEvent => logEvent.Level >= LogEventLevel.Error)
            .CreateLogger();

        Log.Verbose("This is a verbose log message.");
        Log.Error("This is an error log message.");

        Log.CloseAndFlush();
    }
}

运行后,控制台只会输出 Error 级别的消息,其他级别的都被过滤掉了。

12. 扩展与自定义输出器

如果内置的 Sink 不够用,完全可以自己写一个。下面是一个自定义控制台输出器的例子:

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

然后通过扩展方法加入到配置链中:

Log.Logger = new LoggerConfiguration()
    .WriteTo.CustomConsole()
    .CreateLogger();

这样一来,日志输出的目的地、格式都可以完全由你掌控。

13. 总结

Serilog 在 .NET 日志领域能做到如此受欢迎,不是没有道理的。它提供了丰富的输出方式、灵活的格式化选项,以及强大的可扩展性。无论是简单的控制台输出,还是复杂的结构化日志和自定义 Sink,它都能轻松应对。希望这篇文章能帮你更顺畅地用好这个库。

本文转载于:https://www.jb51.net/aspnet/337030b64.htm 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注