发布于2026-07-23 阅读(0)
扫一扫,手机访问
要说 .NET 生态里最受欢迎的日志库,Serilog 绝对排得上号。它设计得相当精巧——API 丰富、架构灵活,输出端和格式化器都是可插拔的,开发者几乎可以按需定制。下面就从基础概念开始,一步步把它拆开看看。
Serilog 按严重程度把日志分为六个级别,从高到低排列:
Serilog 原生支持多种输出目标(也就是 Sink),用得比较多的有:
当然,如果这些都不够用,还可以自己写一个自定义输出器。
Serilog 提供了几种格式化日志消息的方式:
通过 NuGet 直接安装就行:
Install-Package Serilog
用 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! 这条信息。
设置不同的最小级别,就能控制哪些日志会被输出。下面的例子把级别降到 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();
}
}
消息模板是 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!
除了简单的占位符,你还可以在日志里附加更复杂的属性——比如用匿名对象:
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.
把日志写到文件里也很常见。通过 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 的文件,非常便于按日期归档。
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"}
有时候只想输出特定级别的日志,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 级别的消息,其他级别的都被过滤掉了。
如果内置的 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();
这样一来,日志输出的目的地、格式都可以完全由你掌控。
Serilog 在 .NET 日志领域能做到如此受欢迎,不是没有道理的。它提供了丰富的输出方式、灵活的格式化选项,以及强大的可扩展性。无论是简单的控制台输出,还是复杂的结构化日志和自定义 Sink,它都能轻松应对。希望这篇文章能帮你更顺畅地用好这个库。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8