保持优质文档是 Serilog 的优先事项。如果你发现文档中有缺失或不准确的内容,或者希望通过添加主题或教程来扩展 wiki,请通过问题追踪系统告知我们。
为什么选择Serilog?
与许多其他 .NET 库一样,Serilog 提供了基本的诊断日志记录功能,支持文件、控制台等多种方式。它易于设置,具有简洁的 API,并且可以在最新的 .NET 平台之间移植。
与其他 .NET 日志库不同,Serilog 传递的参数不会被破坏性地转换为文本格式。相反,它们会作为结构化数据被保留,可以以文档形式写入 NoSQL 数据存储中。
var input = new { Latitude = 25, Longitude = 134 };
var time = 34;
log.Information("Processed {@SensorInput} in {TimeMS:000} ms", input, time);
Serilog 消息模板使用一种简单的领域特定语言(DSL),扩展了常规 .NET 格式字符串。属性在消息模板中命名,并与提供给日志方法的参数按位置匹配。
这个示例记录了两个属性:SensorInput 和 TimeMS,以及日志事件。
在 JSON 格式中,示例中捕获的属性将如下所示:
{ "SensorInput": { "Latitude": 25, "Longitude": 134 }, "TimeMS": 34 }
在 SensorInput 前面的 @ 操作符指示 Serilog 保留传入对象的结构。如果省略这个操作符,Serilog 会识别简单类型,如字符串、数字、日期和时间、字典以及可枚举类型;其他对象会使用 ToString() 方法转换为字符串。可以使用 $ 操作符强制进行字符串化,代替 @ 操作符。
TimeMS 后面的 :000 部分是标准 .NET 格式字符串,影响属性的呈现方式(而不是捕获方式)。Serilog 附带的标准控制台接收器将把上述消息呈现为:
09:14:22 [Information] Processed { Latitude: 25, Longitude: 134 } in 034 ms
从 NuGet 安装
核心日志记录包是 Serilog。支持的平台包括 .NET/.NET Core、.NET Framework 4.5+、Windows(8/WinRT/Universal+)和 Windows Phone 8+。
$ dotnet add package Serilog
$ dotnet add package Serilog.Sinks.Console
浏览 NuGet 上的 Serilog 标签,查看可用的 sinks、扩展和相关的第三方包。
类型位于 Serilog 命名空间。
using Serilog;
通过 LoggerConfiguration 创建根日志记录器。
using var log = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();
这通常在应用程序启动时完成,并将日志记录器保存以供应用程序类后续使用。如果需要,可以创建和独立使用多个日志记录器。
log.Information("Hello, Serilog!");
Serilog 的全局、静态可访问日志记录器通过 Log.Logger 设置,可以使用 Log 类上的静态方法调用。
Log.Logger = log;
Log.Information("The global logger has been configured");
配置和使用 Log 类是一种可选的便利性,方便库采用 Serilog。Serilog 本身的日志记录管道不要求任何静态/进程范围的状态,因此直接使用 Logger/ILogger 也是可以的。
示例应用程序
下面的完整示例展示了在一个简单的控制台应用程序中进行日志记录,事件会发送到控制台以及带有日期戳的滚动日志文件。
1.创建一个新的控制台应用程序项目
2.安装核心 Serilog 包、控制台接收器(sink)和文件接收器(sink)
在项目目录中的 shell 提示符下,输入:
$ dotnet add package Serilog
$ dotnet add package Serilog.Sinks.Console
$ dotnet add package Serilog.Sinks.File
3.在 Program.cs 中添加以下代码
using System;
using Serilog;
class Program
{
static async Task Main()
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console()
.WriteTo.File("logs/myapp.txt", rollingInterval: RollingInterval.Day)
.CreateLogger();
Log.Information("Hello, world!");
int a = 10, b = 0;
try
{
Log.Debug("Dividing {A} by {B}", a, b);
Console.WriteLine(a / b);
}
catch (Exception ex)
{
Log.Error(ex, "Something went wrong");
}
finally
{
await Log.CloseAndFlushAsync();
}
}
}