ASP.NET Core 日志框架:Serilog
source link: http://beckjin.com/2020/02/14/aspnet-log-serilog/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
在 ASP.NET Core 日志模型 中对日志整体实现方式进行了介绍,通过使用内置日志记录器来实现日志的输出路径。而在实际项目开发中,使用第三方日志框架来记录日志也是非常多的,首先一般基础的内置日志记录器在第三方日志框架中都有实现,然后很多第三方日志框架在功能上更强大和丰富,能满足我们更多的项目分析和诊断的需求。
本文主要介绍 Serilog 这个日志框架的使用,它是目前比较突出和受欢迎的一个日志框架。 Serilog
在日志记录上采用 json
的格式,方便日志的快速查询与过滤。
默认日志行为
在使用 Serilog
之前我们先看看 ASP.NET Core API 项目默认的日志输出行为。创建基于 ASP.NET Core 3.1 的 API 项目后启动,默认访问会 weatherforecast
接口,然后可以从控制台和调试窗口看到如下输出日志 ( ASP.NET Core API 项目模板默认集成了 Console
和 Debug
日志记录器 ):
日志输出等级在配置文件中有默认设置参数, appsettings.Development.json
(开发环境)和 appsettings.json
(生产环境)的 Logging
节点。下面以 appsettings.Development.json
为例:
{ "Logging": { "LogLevel": { "Default": "Debug", "System": "Information", "Microsoft": "Information" } } }
开发环境下默认输出 Debug
及以上等级日志, System
和 Microsoft
开头的日志 Information
及以上等级会输出,所以从上面的截图看到大批 Info
日志。
Serilog 使用
和内置日志记录器一样, Serilog
也有自己的日志记录器组件,NuGet 包命名上基本都是 Serilog.Sinks.xxx
的形式,如: Serilog.Sinks.Console
、 Serilog.Sinks.File
、 Serilog.Sinks.Seq
、 Serilog.Sinks.ElasticSearch
等,接下来先以 Serilog.Sinks.Console
为例。
- 安装
Serilog.Settings.Configuration
(读取配置)、Serilog.Sinks.Console
(日志输出到控制台) NuGet 包 ; -
配置文件添加
Serilog
配置,WriteTo
指定输出目标位置,它是一个数组类型,所以可以指定多个目标位置,这里暂时只指定输出到控制台:{ "Serilog": { "MinimumLevel": { "Default": "Debug" }, "WriteTo": [ { "Name": "Console" } ] } }
-
Program.cs 添加
UseSerilog
,设置配置信息:public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseSerilog((context, logger) => { logger.ReadFrom.Configuration(context.Configuration); }); webBuilder.UseStartup<Startup>(); });
-
在 Startup.cs 的
Configure
请求管道中添加UseSerilogRequestLogging
:public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseSerilogRequestLogging(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
-
日志输出效果如下:
由于日志总是输出一堆,并不能区分什么日志来自
Serilog
,其实Serilog
输出的日志是非常简洁的,只有HTTP GET ...
这一条,其他都是 AspNetCore 本身输出的。
日志输出简化
为了使日志输出更简洁,我们可以设置不输出 AspNetCore Info 日志,只需在 Serilog
配置节点中设置 AspNetCore 日志输出级别为 Warning
:
{ "Serilog": { "MinimumLevel": { "Default": "Debug", "Override": { "Microsoft.AspNetCore": "Warning" } }, "WriteTo": [ { "Name": "Console" } ] } }
日志属性扩展
这部分我们将增加使用 Serilog.Sinks.Seq
日志记录器,不过在使用前需要先安装 Seq ,和 ElasticSearch
类似,主要提供日志存储和查询,安装非常简单,这里不再赘述,参考 Windows or Docker 。
Seq
服务启动后修改配置文件,在 WriteTo
节点内增加 Seq
的配置参数:
"WriteTo": [ { "Name": "Console" }, { "Name": "Seq", "Args": { "serverUrl": "http://localhost:5341/" } } ]
在 Seq
中查看日志如下,基于 ParentId
、 RequestId
、 TraceId
可实现链路跟踪:
手动记录的日志如下:
虽然通过之前的配置使一次请求中系统日志只保留了一条,但相比之下可能丢失了一些重要信息,如: endpoint
、 contentType
等,所以我们需要在日志体上增加一些扩展属性,做到数量少但内容丰富。
前面在 Startup 的 Configure
方法中添加过 UseSerilogRequestLogging
,该方法还支持更多的参数配置,通过指定 EnrichDiagnosticContext
委托方法的实现向 IDiagnosticContext
对象中添加扩展属性,这些扩展属性将会作用于请求日志体中。( Serilog.AspNetCore
已将接口 IDiagnosticContext
作为单例添加到了 DI 容器中,可以在任何类中通过其 Set
方法添加扩展属性 )
public static class LogUtil { public static void EnrichDiagnosticContext(IDiagnosticContext diagnosticContext, HttpContext httpContext) { var request = httpContext.Request; diagnosticContext.Set("Host", request.Host); diagnosticContext.Set("ContentType", httpContext.Response.ContentType); var endpoint = httpContext.GetEndpoint(); if (endpoint is object) { diagnosticContext.Set("EndpointName", endpoint.DisplayName); } } }
app.UseSerilogRequestLogging(opts => { opts.EnrichDiagnosticContext = LogUtil.EnrichDiagnosticContext; });
在 Seq
中查看日志如下,已包含添加的扩展属性:
参考链接:
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK