这是该系列的第一篇文章:在ASP.NET Core 3.0中使用Serilog.AspNetCore。

  1. 第1部分-使用Serilog RequestLogging来简化ASP.NET Core的日志输出(本篇文章)

  2. 第2部分-使用Serilog记录所选的端点名称[敬请期待]

  3. 第3部分-使用Serilog.AspNetCore记录MVC属性[敬请期待]

作者:依乐祝

译文地址:https://www.cnblogs.com/yilezhu/p/12215934.html

原文地址:https://andrewlock.net/using-serilog-aspnetcore-in-asp-net-core-3-reducing-log-verbosity/

众所周知,ASP.NET Core的重要改变之一是把日志记录内置于框架中。这意味着您可以(如果需要)从自己的标准日志基础设施访问所有深层基础设施日志。缺点是有时您会收到太多的日志。

在这个简短的系列文章中,我将介绍如何使用Serilog的ASP.NET Core请求日志记录功能。在第一篇文章中,我将讲述如何将Serilog的RequestLoggingMiddleware添加到您的应用程序,以及它提供的好处。在后续文章中,我将描述如何进一步自定义行为。

我已经将这些帖子草拟了一段时间。从那时起,Serilog的创建者Nicholas Blumhardt就在ASP.NET Core 3.0中使用Serilog撰写了一篇详尽的博客文章。这是一篇非常详细(至少我认为是这样)的文章,我强烈建议您阅读。您可以在他的文章中找到我在本系列文章中谈论的大部分内容,所以请查看!

原生请求日志

在本节中,首先让我们创建一个标准的ASP.NET Core 3.0的Razor pages应用,当然你也可以直接使用dotnet new webapp命令来进行创建。这将创建一个标准Program.cs,如下所示:

 public class Program{public static void Main(string[] args){CreateHostBuilder(args).Build().Run();}public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();});}

还有一个Startup.cs,用于配置中间件管道,Configure如下所示:

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}else{app.UseExceptionHandler("/Error");// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.app.UseHsts();}app.UseHttpsRedirection();app.UseStaticFiles();app.UseRouting();app.UseAuthorization();app.UseEndpoints(endpoints =>{endpoints.MapRazorPages();});}

如果您运行该应用程序并导航至主页,则默认情况下,您会在控制台中看到每个请求都会产生许多的日志。以下日志是针对对主页的单个请求生成的(此后我还没有包括对CSS和JS文件的其他请求)(这是是开发环境请求出现的日志):

info: Microsoft.AspNetCore.Hosting.Diagnostics[1]Request starting HTTP/2 GET https://localhost:5001/
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]Executing endpoint '/Index'
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3]Route matched with {page = "/Index"}. Executing page /Index
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[101]Executing handler method SerilogRequestLogging.Pages.IndexModel.OnGet - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[102]Executed handler method OnGet, returned result .
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[103]Executing an implicit handler method - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[104]Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4]Executed page /Index in 221.07510000000002ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]Executed endpoint '/Index'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]Request finished in 430.9383ms 200 text/html; charset=utf-8

单个请求就是10条日志。现在,很清楚,它正在Development环境中运行,该环境默认情况下将Microsoft名称空间中的所有信息记录在“Information”或更高的级别。如果我们切换到Production环境,则默认模板会将Microsoft命名空间的日志过滤到“Warning” 。现在导航到默认主页会生成以下日志(这里注意,如果你现在使用ASP.NET Core3.1貌似Microsoft命名空间默认日志级别已经改为Warning):

是的,根本没有日志!上一次运行中生成的所有日志都位于Microsoft命名空间中,并且属于“Information”级别,因此将它们全部过滤掉。就个人而言,我觉得这有点麻烦。如果生产版本仅仅只是想记录一部分内容,而其他相关联的内容则不进行记录,这将会更有用的。

一种可能的解决方案是自定义应用于每个命名空间的过滤器。例如,您可以将Microsoft.AspNetCore.Mvc.RazorPages命名空间限制为“Warning”级别,而将更通用的Microsoft命名空间保留为“Information”级别。现在,您将获得精简后的日志集:

info: Microsoft.AspNetCore.Hosting.Diagnostics[1]Request starting HTTP/2 GET https://localhost:5001/
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]Executing endpoint '/Index'
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]Executed endpoint '/Index'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]Request finished in 184.788ms 200 text/html; charset=utf-8

这些日志中包含一些有用的信息-URL,HTTP方法,时间信息,端点等-并且没有太多冗余。但是,仍然令人讨厌的是它们是四个单独的日志消息。(还是很多,如果能精简成一条日志记录是不是会好很多)

这是Serilog RequestLoggingMiddleware旨在解决的问题-为请求中的每个步骤创建单独的日志相反,它是创建一个包含所有相关信息的“摘要”日志消息。

将Serilog添加到应用程序

使用Serilog RequestLoggingMiddleware 的一个前提条件就是您正在使用Serilog!在本节中,我将介绍将Serilog添加到ASP.NET Core应用程序中。如果您已经安装了Serilog,请跳至下一部分。

首先安装Serilog.AspNetCore NuGet软件包,再加上控制台和Seq接收器【这是一个漂亮的可视化日志UI】,以便我们可以查看日志。您可以通过运行以下命令从命令行执行此操作:

dotnet add package Serilog.AspNetCore
dotnet add package Serilog.Sinks.Seq

现在该用Serilog替换默认日志了。您可以通过多种方式执行此操作,但是建议的方法是在Program.Main 执行其他任何操作之前先配置记录器。这与ASP.NET Core通常使用的方法背道而驰,但建议用于Serilog。当然这会导致您的的Program.cs文件变得更长:

// Additional required namespaces
using Serilog;
using Serilog.Events;namespace SerilogDemo
{public class Program{public static void Main(string[] args){// Create the Serilog logger, and configure the sinksLog.Logger = new LoggerConfiguration().MinimumLevel.Debug().MinimumLevel.Override("Microsoft", LogEventLevel.Information).Enrich.FromLogContext().WriteTo.Console().WriteTo.Seq("http://localhost:5341").CreateLogger();// Wrap creating and running the host in a try-catch blocktry{Log.Information("Starting host");CreateHostBuilder(args).Build().Run();}catch (Exception ex){Log.Fatal(ex, "Host terminated unexpectedly");}finally{Log.CloseAndFlush();}}public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).UseSerilog().ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();});}
}

尽管这样设置可能显得更为复杂,但是此设置可确保例如在appsettings.json文件格式错误或缺少配置文件的情况下仍会获取日志。如果现在运行您的应用程序,您将看到与我们最初相同的10条日志,只是格式略有不同:

[13:30:27 INF] Request starting HTTP/2 GET https://localhost:5001/
[13:30:27 INF] Executing endpoint '/Index'
[13:30:27 INF] Route matched with {page = "/Index"}. Executing page /Index
[13:30:27 INF] Executing handler method SerilogRequestLogging.Pages.IndexModel.OnGet - ModelState is Valid
[13:30:27 INF] Executed handler method OnGet, returned result .
[13:30:27 INF] Executing an implicit handler method - ModelState is Valid
[13:30:27 INF] Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
[13:30:27 INF] Executed page /Index in 168.28470000000002ms
[13:30:27 INF] Executed endpoint '/Index'
[13:30:27 INF] Request finished in 297.0663ms 200 text/html; charset=utf-8

现在,通过在应用程序生命周期的早期进行配置,我们的日志记录配置的更加健壮,但实际上尚未解决我们提出的问题。为此,我们将添加RequestLoggingMiddleware

切换到Serilog的 RequestLoggingMiddleware

RequestLoggingMiddleware被包含在Serilog.AspNetCore中,可以被用于为每个请求添加一个单一的“摘要”日志消息。如果您已经完成了上一节中的步骤,则添加这个中间件将变得很简单。在您的Startup类中,在您想要记录日志的位置使用UseSerilogRequestLogging()进行调用:

// Additional required namespace
using Serilog;public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{// ... Error handling/HTTPS middlewareapp.UseStaticFiles();app.UseSerilogRequestLogging(); // <-- Add this lineapp.UseRouting();app.UseAuthorization();app.UseEndpoints(endpoints =>{endpoints.MapRazorPages();});
}

与ASP.NET Core的中间件管道一样,顺序很重要。当请求到达RequestLoggingMiddleware中间件时,它将启动计时器,并将请求传递给后续中间件进行处理。当后面的中间件最终生成响应(或抛出异常),则响应通过中间件管道传递到请求记录器,并在其中记录了结果并写入概要日志信息。

Serilog只能记录到达中间件的请求。在上面的例子中,我已经在StaticFilesMiddleware之后添加了RequestLoggingMiddleware 。因此如果请求被UseStaticFiles处理并使管道短路的话,日志将不会被记录。鉴于静态文件中间件非常嘈杂,而且通常这是人们期望的行为(静态文件进行短路,不需要进行记录),但是如果您也希望记录对静态文件的请求,则可以在管道中serilog中间件移动到更早的位置。

如果我们再一次运行该应用程序,你还是会看到原来的10个日志消息,但你会看到一个额外的通过SerilogRequestLoggingMiddleware汇总的日志消息,倒数第二的消息:

# Standard logging from ASP.NET Core infrastructure
[14:15:44 INF] Request starting HTTP/2 GET https://localhost:5001/
[14:15:44 INF] Executing endpoint '/Index'
[14:15:45 INF] Route matched with {page = "/Index"}. Executing page /Index
[14:15:45 INF] Executing handler method SerilogRequestLogging.Pages.IndexModel.OnGet - ModelState is Valid
[14:15:45 INF] Executed handler method OnGet, returned result .
[14:15:45 INF] Executing an implicit handler method - ModelState is Valid
[14:15:45 INF] Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
[14:15:45 INF] Executed page /Index in 124.7462ms
[14:15:45 INF] Executed endpoint '/Index'# Additional Log from Serilog
[14:15:45 INF] HTTP GET / responded 200 in 249.6985 ms# Standard logging from ASP.NET Core infrastructure
[14:15:45 INF] Request finished in 274.283ms 200 text/html; charset=utf-8

关于此日志,有几点需要说明下:

  • 它在一条消息中包含您想要的大多数相关信息-HTTP方法,URL路径,状态代码,持续时间。

  • 显示的持续时间短于Kestrel在后续消息中记录的值。这是可以预期的,因为Serilog仅在请求到达其中间件时才开始计时,而在返回时停止计时(在生成响应之后)。

  • 在这两种情况下,使用结构日志记录时都会记录其他值。例如,记录了RequestId和SpanId(用于跟踪功能),因为它们是日志记录范围的一部分。您可以在登录到seq的请求的以下图像中看到这一点。

  • 默认情况下,我们确实会丢失一些信息。例如,不再记录终结点名称和Razor页面处理程序。在后续文章中,我将展示如何将它们添加到摘要日志中。

  • 如果想要通过``http://localhost:5341 访问UI,你可能需要下载seq进行安装。由于某种不知名的原因,可能下载会很慢。所以当然你也可以关注公众号“DotNetCore实战”然后回复关键字“seq”获取下载地址。

完成整理工作所剩下的就是过滤掉我们当前正在记录的信息级日志消息。在Program.cs中更新Serilog配置以添加额外的过滤器:

Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().MinimumLevel.Override("Microsoft", LogEventLevel.Information)// Filter out ASP.NET Core infrastructre logs that are Information and below.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning).Enrich.FromLogContext().WriteTo.Console().WriteTo.Seq("http://localhost:5341").CreateLogger();

通过最后的更改,您现在将获得一组干净的请求日志,其中包含每个请求的摘要数据:

[14:29:53 INF] HTTP GET / responded 200 in 129.9509 ms
[14:29:56 INF] HTTP GET /Privacy responded 200 in 10.0724 ms
[14:29:57 INF] HTTP GET / responded 200 in 3.3341 ms
[14:30:54 INF] HTTP GET /Missing responded 404 in 16.7119 ms

在下一篇文章中,我将介绍如何通过记录其他数据来增强此日志。

摘要

在本文中,我描述了如何使用Serilog.AspNetCore的请求日志记录中间件来减少为每个ASP.NET Core请求生成的日志数,同时仍记录摘要数据。如果您已经在使用Serilog,则非常容易启用。只需在您的Startup.cs文件中调用UseSerilogRequestLogging()

当请求到达此中间件时,它将启动计时器。当后续的中间件生成响应(或引发异常)时,响应将通过中间件管道返回到请求记录器,记录器记录结果并编写摘要日志消息。

添加请求日志记录中间件之后,您可以过滤掉默认情况下在ASP.NET Core 3.0中生成的更多基础结构日志,而不会丢失有用的信息。


好看你就点点我

如何利用Serilog的RequestLogging来精简ASP.NET Core的日志输出相关推荐

  1. Elasticsearch,Kibana,Logstash,NLog实现ASP.NET Core 分布式日志系统

    Elasticsearch,Kibana,Logstash,NLog实现ASP.NET Core 分布式日志系统 原文:Elasticsearch,Kibana,Logstash,NLog实现ASP. ...

  2. ASP.NET Core 解决控制台输出日志内容前面[40m等乱码字符

    在默认我写了一个 WPF 程序去做管理 ASP.NET Core 进程的日志的时候,重定向输出的内容里面每一行前面都添加了很多乱码字符串.其实这是 ASP.NET Core 控制台的颜色字符,解决方法 ...

  3. 如何在 ASP.Net Core 中使用 Serilog

    记录日志的一个作用就是方便对应用程序进行跟踪和排错调查,在实际应用上都是引入 日志框架,但如果你的 日志文件 包含非结构化的数据,那么查询起来将是一个噩梦,所以需要在记录日志的时候采用结构化方式. 将 ...

  4. ASP.NET Core 日志框架:Serilog

    在 ASP.NET Core 日志模型 中对日志整体实现方式进行了介绍,通过使用内置日志记录器来实现日志的输出路径.而在实际项目开发中,使用第三方日志框架来记录日志也是非常多的,首先一般基础的内置日志 ...

  5. ASP.NET Core 沉思录 - 结构化日志

    在 <ASP.NET Core 沉思录 - Logging 的两种介入方法>中我们介绍了 ASP.NET Core 中日志的基本设计结构.这一次我们来观察日志记录的格式,并进一步考虑如何在 ...

  6. ASP.NET Core ---日志

    一.日志记录:  1.日志的作用: 程序中记录日志一般有两个目的,故障定位和显示程序运行状态.好的日志记录方式可以提供足够多定位问题的依据. 2.日志的等级: 有良好工作习惯的人,工作的时候会将领导交 ...

  7. 一套标准的ASP.NET Core容器化应用日志收集分析方案

    点击上方蓝字 给一个关注吧 讲故事 关注我公众号的朋友,应该知道我写了一些云原生应用日志收集和分析相关的文章,其中内容大多聚焦某个具体的组件: 超级有用的TraceId,快点用起来吧! 如何利用NLo ...

  8. ASP.NET Core 沉思录 - Logging 的两种介入方法

    ASP.NET Core 中依赖注入是一个很重要的环节.因为几乎所有的对象都是由它创建的(相关文章请参见<ASP.NET Core 沉思录 - ServiceProvider 的二度出生> ...

  9. ubuntu16.4下用jexus部署asp.net core rtm

    今天说下ubuntu 下部署asp.net core,不需要安装.net core sdk,自带运行时方式部署,利用jexus服务器转发请求到asp.net core. 1.部署准备环境 vmware ...

最新文章

  1. spring 依赖注入
  2. 2021年JVM生态中哪些是流行的、热门的、趋势是什么
  3. PHPRunner(网页制作工具)v10.3中文版
  4. 详解随机神经网络结构搜索 (SNAS)
  5. 亲测有用的音乐推荐网站
  6. 稳定婚姻问题:Gale–Shapley算法
  7. 工作379-回调日期补0操作
  8. POJ 1321 棋盘问题(回溯)
  9. 3dmax镜像后模型线条乱了_3dMax入门教程来啦!小白赶紧收藏!
  10. 高级PHP应用程序漏洞审核技术
  11. python接口自动化(二十八)--html测试 报告——下(详解)
  12. Android实现浮层的上下滑动(支持内部加入View)
  13. SpringBoot系列: 所有配置属性和官方文档
  14. 计算机组成原理--白中英版 全部知识点
  15. Viso各版本网盘免费下载
  16. 分子量-算法竞赛习题3-2:给出一种物质的分子式(不带括号),求分子量。本题中的分子式只包含4种原子,分别为C, H, O, N,原子量分别为12.01, 1.008, 16.00, 14.01。
  17. 各大公司的大数据质量监控平台
  18. SV中的浅拷贝和深拷贝
  19. “网上下单”生活神技能,寄快递在线下单、查快递实时物流信息
  20. 微信公众号消息text换行问题

热门文章

  1. 3-07. 求前缀表达式的值(25) (ZJU_PAT数学)
  2. web网页的表单排版利器--960css
  3. android bitmap drawable 互转
  4. zoj2271 Chance to Encounter a Girl(DP)
  5. 经典正则表达式(转)
  6. c语言编手机蓝牙软件的代码,51单片机C语言的简易蓝牙锁代码
  7. 如何获取 Teams Meeting 的上下文信息
  8. 如何在Microsoft Word中插入签名
  9. python基础一 day6 文件操作
  10. 《简明 PHP 教程》00 开篇