在上两篇文章(链接1和链接2)中,我们通过一个简易 demo 了解到了一个简单的日志记录类库所需要的功能,即一条日志有哪些数据,以及如何通过一次记录的方式将同一条日志消息记录到多个日志媒介中。在本文中,针对 Serilog,我们从以下几个方面来了解 Serilog 核心功能需求和用法,并为下一篇正式开始探究源码准备相关工作。(系列目录)
Serilog 核心功能#
目前,在 Asp.net core 中,对于日志记录库,除了微软官方准备的 Microsoft.Extensions.Logging 外,Serilog 也算是一个最常用的日志记录的类库。作为一类最常用的日志记录库,Serilog 具有良好的扩展性,其组织所维护的60多个项目均是为 Serilog 提供额外功能的扩展类库。为更好地了解源码具体在做什么,我们需要对 Serilog 有一个最基本的功能了解。
1. Serilog 将日志信息记录到哪里?#
Serilog 将日志记录媒介称之为 Sink,在 Serilog 组织维护的类库中,有各种各样的 Sink,比如说写入控制台的 ConsoleSink 以及写入文件的 FileSink 等。这些 Sink 的包名通常命名为 Serilog.Sinks.XXX。
那么 Serilog 如何向多个 Sinks 中写入日志呢?下面给出一个向控制台和文件写入日志的列例子。在此之前,我们需要向所在项目添加三个包:
- Serilog
- Serilog.Sinks.Console
- Serilog.Sinks.File
添加完三个包之后,通过以下调用方式即可将日志写入到控制台和文件中。
var log = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File("./log.txt")
.CreateLogger();
log.Information("Hello world.");
log.Error("Hello world, again.");
如果大家对之前的 Demo 了解的话,那么会觉得这段代码非常的熟悉。LoggerConfiguration类似于先前的LogBuilder,通过CreateLogger函数来创建对应的日志记录器,调用Console和File函数类似于先前的AddConsole以及AddFile方法,其输入参数的个数和形式都完全一样。但不同的是这些函数在WriteTo对象上调用而不是LoggerConfiguration上做调用,这一点和先前的 Demo 不一样,不过这一点并不影响我们的理解。再往后,日志的记录是通过Information和Error函数来调用,而LogDemo 中采用LogInformation和LogError函数记录日志。
上图显示的是 Serilog 向控制台中记录的日志信息,可以看到,其最终记录的日志信息和 LogDemo 差不多,均是日志时间+等级+消息。
2. Serilog 向 Sink 中具体写入了什么?#
在之前的 LogDemo 中,我们一直认为日志消息本质上就是一字符串。将日志记录下来就是将相关信息组合成字符串并写入到对应 Sink 中,这是非结构化日志记录库常用的做法。然而,这种使用方式有两个问题:
2.1 日志消息不能附带数据。日志消息附带数据有非常多的好处,比如说,如果类库具有自动解析数据的能力,那么我们