Serilog源码解析——使用方法 (2)

这个功能非常的方便,比如说,我们在日志记录的时候还需要记录当前上下文的用户名称。一种简单的办法是将用户名称放在消息字符串中,但这样处理的方法会在每次记录一条日志都需要手动填写相关数据和模板。更好的一种操作是,将用户名称这个数据项放在日志事件中,就像日志时间和等级一样,在合适的位置自动记录而不是每次调用。

var log = new LoggerConfiguration() .Enrich.WithProperty("User", "Dave") .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] [{User}] {Message:lj}{NewLine}{Exception}") .CreateLogger(); log.Information("Hello world."); // 输出: [21:44:04 INF] [Dave] Hello world.

在 Serilog 中,这种向日志事件中添加数据的行为叫 Enrichment,对应数据对象是 Enricher。Enrichment 是 Serilog 在数据方面一个具有强大扩展性的功能,通过向 Serilog 日志记录时塞入新数据,并在日志模板中进行使用,可以大大降低了调用时代码的重复性,且减少了遗漏的可能。比如说,有的人希望每次日志记录都记录当前运行的线程信息、进程信息以及环境变量数据等,通过添加相应的 Enricher 可以达到无需过多关心这些值而直接记录。甚至,像这些较为常用的 Enrichers,官方组织早已给出了相应的扩展包:

Serilog.Enrichers.Thread:附带当前处理的进程信息

Serilog.Enrichers.Process:附带当前处理的线程信息

Serilog.Enrichers.Environment:附带当前的环境信息

3. Serilog 该不该记录这条日志

对于一条日志记录,很多时候,我们并不是要求每条都记录下来,往往是需要丢弃一些日志。这看起来似乎挺反直觉的,数据是重要的,不应该隐式地丢弃某些数据,但是,在实际应用中这样的需求确实是合理的,有时候我们仅希望记录最为重要的日志而不是全部的日志信息。

日志的过滤有两种形式,一种是在将日志记录到各个 Sink 前需要过滤一遍,这种通常是全局过滤。另一种则是每个 Sink 对象有其自己的过滤方式,通常是局部过滤。这里通过两个例子说明。

全局过滤

全局过滤应用场景是日志记录器会记录海量的日志,通常大部分是等级非常低的日志,这类日志往往在开发时候有用,运行期间不应该再输出出来。这种情况下,我们需要设置最小日志输出等级为Information即可。其使用方式如下:

var log = new LoggerConfiguration() .WriteTo.Console() .MinimumLevel.Information() .CreateLogger(); log.Debug("Test here."); // 没有任何输出

另外,全局的过滤条件也可以很复杂,甚至我们可以将之前的 Enricher 结合在一起,比如说,在原先带有用户名的 Enricher 中,我们希望只记录用户名为 Lily 的日志,其他用户名都不记录。这里ForContext也是一种添加 Enricher 的方法,和之前不同的是,它将 Enricher 添加到子Logger中,即所添加的数据只有log1和log2有,log中并没有。

var log = new LoggerConfiguration() .Filter.ByIncludingOnly(Matching.WithProperty("User", "Lily")) // 添加过滤条件 .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] [{User}] {Message:lj}{NewLine}{Exception}") .CreateLogger(); var log1 = log.ForContext("User", "Lily"); log1.Information("Log successed."); // 输出 var log2 = log.ForContext("User", "Dave"); log2.Information("Log failed."); // 不输出 局部过滤

同样地,Serilog 允许我们将日志的过滤条件从全局设置缩小到对某个 Sink 的过滤,即只有指定的 Sink 具有过滤日志的功能。

var log = new LoggerConfiguration() .WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Debug) .WriteTo.File("log.txt") .CreateLogger(); log.Information("Hello world."); // 在Console中没有记录,在File中被记录 4. Serilog中的日志记录器的配置

从上述几个问题中可以看到,所有的日志记录器都是通过LogConfiguration对象的相关属性执行配置后通过CreateLogger方法而生成的。因为在之前都已经或多或少提到,这里就不细谈了。值得一提的是 Serilog 不光提供了代码文本的设置方法(即通过调用某个函数执行设置),还提供了一套通过配置字符串的设置方法,这种方法较为动态,且不需要写固定的代码流程而只需要提供相关配置文件,具体处理流程在后续再提。

Serilog 源码准备

好了,终于开始接触 Serilog 的源码了。这部分主要准备好源码,以便为了后续的学习。

准备源码

Serilog 的地址为 https://github.com/Serilog/Serilog 。我们打开 Windows terminal,通过下面命令将其下载下来。

git clone https://github.com/Serilog/Serilog

下载完成后我们就可以看到Serilog文件夹。然后命令行进入该文件夹。

cd ./Serilog

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfddg.html