Serilog简单使用指南

Serilog是.net平台上的一个记录程序诊断信息的日志框架,主要工作内容是决定将日志内容以何种格式保存到外部存储介质中(可以是控制台、文件、数据库和第三方日志服务)。除此之外还有NLog和Log4Net等类似的日志框架。

Serilog的优点是在云服务厂商中有支持Serilog的插件可以直接使用,而且支持将日志信息直接输出到第三方的日志服务中(ELK、ES等);而且支持输出日志内容到多种外部存储介质中;支持记录结构化的数据(将对象以“属性名称:属性值”键值对的形式记录到日志中),支持配置消息输出模板等。

本文主要介绍Serilog的简单使用,如果想深入学习的话,建议去看看官方文档。

1、引入Serilog包;

根据想把日志内容输出到哪里引用对应的Serilog.Sink.XXX包;

如果想使用异步的写入日志可以引入Serilog.Sinks.Async包;

(有个Serilog.AspNetCore的包是专门用于ASP.NET Core应用的,但在此处我还是使用一般的包,反正它也同样适用 .NET CORE。)

2、在Program.cs文件中进行配置:

Serilog支持使用代码的方式进行配置;也支持通过配置文件(appsetting.json、web.config)的方式进行配置(需要安装额外的Nuget包 Serilog.Settings.Configuration),但是这种方式并不是所有Serilog的功能都支持,因为是简单使用,故此出只介绍使用代码进行配置。

(1)最简单的方式是使用全局静态类Log进行配置,只需配置一次就可以在应用全局使用同一个Logger来进行日志记录:

1  Log.Logger = new LoggerConfiguration()
2             .MinimumLevel.Debug()
3             .WriteTo.Console()
4             .WriteTo.File("logs/myapp.txt", rollingInterval: RollingInterval.Day)
5             .CreateLogger();

上面的代码使用LoggerConfiguration.CreateLogger()创建了一个静态的、全局可访问的logger;

①使用 MinimumLevel.Debug() 设置了最低日志级别,Tracer\Verbose<Debug<Information<Warning<Error<Fatal,低于该级别的日志内容将不会被记录;

②使用WriteTo.Console()设置日志内容输出到控制台中;

③使用WriteTo.File 设置日志内容输出到文件中,方法参数path可以设置日志文件所在的路径、

rollingInterval设置日志文件生成间隔(每天、每小时、每月生成一个日志文件,避免单个日志文件过大)、

rollOnFileSizeLimit设置每个日志文件的大小限制、

restrictedToMinimumLevel 单独设置该sink(接收器:控制台接收器、文件接收器等)的最低日志级别,注意级别必须比logger上MinimumLevel设置高、

outputTemplate 设置记录日志内容的输出模板,代表日志内容以何种格式输出到外部;默认为"{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}"。

 

(2)使用依赖注入的方式来进行配置,通过使用AddSerilog方法注入相关的服务,然后在需要记录日志的地方,通过ILogger<T>的方式注入使用;

1 //注册serilog
2 builder.Services.AddSerilog(cfg =>
3 {
4     cfg.Enrich.With(new ThreadIdEnricher());
5     cfg.MinimumLevel.Information()
6     .WriteTo.File("Logs/log.txt", rollingInterval: RollingInterval.Day, restrictedToMinimumLevel: LogEventLevel.Information)
7     .WriteTo.File("Logs/Errors/log.txt", rollingInterval: RollingInterval.Day, restrictedToMinimumLevel: LogEventLevel.Error);
8 });

产生的日志内容如下:

3、Serilog中包含有中间件,对每个http request都会进行更加智能的日志记录,它对.NET CORE内置的request日志记录操作进行了相应的优化,把多个日志事件合并到一起,减少了资源的占用。

1     var app = builder.Build();
2 
3     app.UseSerilogRequestLogging(); // <-- Add this line
4 
5     // Other app configuration

 

4、官方更推荐使用消息模板的方式记录日志内容,类似 logger.Information("This is a message from  {name}","ZhangSan");

Serilog的消息模板是对.NET 格式字符串标准的超集,所以任何string.format可以接受的字符串格式,都适用于消息模板。

在Serilog内部对每个模板进行解析和缓存(有大小上限设置),类似下面的写法将字符串变量当作字符串传入,会降低性能和浪费缓存;

1 // Don't:
2 Log.Information("The time is " + DateTime.Now);

与之相对应的是,在记录日志消息的时候我们应该使用模板属性包含变量的方式,如下:

1 // Do:
2 Log.Information("The time is {Now}", DateTime.Now);

尽量使用PascalCase命名方式来命名模板属性以保持与Serilog的生态一致;更多的消息模板的内容可以查看 https://messagetemplates.org/

之后就可以在需要记录日志的地方使用 Log.Logger.Information 之类的方式直接使用;

5、两阶段初始化;

如果在ASP.NET CORE应用启动期间发生了异常,Serilog是没办法记录异常信息的,

第一种解决方法是可以采用首先使用全局静态类Log进行简单配置,然后用try catch语句将program.cs文件的代码包裹起来,记录应用启动期间发生的异常信息,最后使用 builder.Services.AddSerilog() 注入服务和配置信息;

但缺点是ASP.NET CORE应用的服务,包括appsettiong.json配置文件和依赖注入在此期间都还不可用。

 1 using Serilog;
 2 
 3 Log.Logger = new LoggerConfiguration()
 4     .WriteTo.Console()
 5     .CreateLogger();
 6 
 7 try
 8 {
 9     Log.Information("Starting web application");
10 
11     var builder = WebApplication.CreateBuilder(args);
12     builder.Services.AddSerilog(configuration=>{...... }); // <-- Add this line 
13     
14     var app = builder.Build();
15     app.MapGet("/", () => "Hello World!");
16 
17     app.Run();
18 }
19 catch (Exception ex)
20 {
21     Log.Fatal(ex, "Application terminated unexpectedly");
22 }
23 finally
24 {
25     Log.CloseAndFlush();
26 }

第二个解决方案是两阶段初始化;

在应用启动的时候,创建一个bootstrap的logger来记录启动期间异常信息,一旦启动完成后它立马会被配置好的logger替代;

1 using Serilog;
2 using Serilog.Events;
3 
4 Log.Logger = new LoggerConfiguration()
5     .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
6     .Enrich.FromLogContext()
7     .WriteTo.Console()
8     .CreateBootstrapLogger(); // <-- Change this line!

之后可以在注入Serilog服务的时候设置完整的配置信息,

 1  builder.Services.AddSerilog((service, cfg) =>
 2     {
 3         //在此处对Serilog进行配置
 4 
 5         //添加线程id
 6         cfg.Enrich.With(new ThreadIdEnricher());
 7 
 8         //重载AspNetCore内部默认的最低日志级别
 9         cfg.MinimumLevel.Override("Microsoft.AspNetCore.Hosting", LogEventLevel.Warning);
10         cfg.MinimumLevel.Override("Microsoft.AspNetCore.Mvc", LogEventLevel.Warning);
11         cfg.MinimumLevel.Override("Microsoft.AspNetCore.Routing", LogEventLevel.Warning);
12 
13         cfg.MinimumLevel.Information()
14         .WriteTo.File("Logs/log-.txt", rollingInterval: RollingInterval.Day, restrictedToMinimumLevel: LogEventLevel.Information, outputTemplate: _outputTemplate)
15         .WriteTo.File("Logs/Errors/log-.txt", rollingInterval: RollingInterval.Day, restrictedToMinimumLevel: LogEventLevel.Error, outputTemplate: _outputTemplate);
16     });

 

注意,之后配置的logger会完全替代掉之前创建的bootstraplogger,如果你也想在控制台输出日志内容的话,必须重新添加.writeToConsole配置;

以上就是本人对于Serilog这个日志记录框架简单使用的一点不成熟的见解,其中有可能包含错误的地方,希望各位指正和包含。 

 

引用文献:

https://github.com/serilog/serilog-aspnetcore#serilogaspnetcore---

https://github.com/serilog/serilog/wiki/Getting-Started

posted @ 2024-04-22 12:55  开心的菜鸟程序猿  阅读(1748)  评论(0编辑  收藏  举报