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

这是该系列的第一篇文章:在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中生成的更多基础结构日志,而不会丢失有用的信息。


好看你就点点我

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312178.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

net下的高性能轻量化半自动orm+linq的《SqlBatis》

一、项目介绍该项目内置单表linq操作&#xff0c;xml动态sql解析&#xff0c;词法分析&#xff0c;类型映射等功能。SqlMapper,用来处理sql与数据库操作&#xff0c;它设计的目标是支持mysql,sqlserver,sqllite,pgsql等.TypeMapper用于完成将数据库的字段类型映射到C#类型&…

如何快速融入团队(六)

作者&#xff1a;邹溪源&#xff0c;长沙资深互联网从业者&#xff0c;架构师社区特邀嘉宾&#xff01;一我总是在记忆深处探访那些拥有高效率团队的一切特征&#xff0c;并试图从纷繁复杂的记忆尘埃中找出一些共性&#xff0c;庆幸我已经习惯于通过阅读和思考来解读这些内容&a…

临近年关,修复ASP.NET Core因浏览器内核版本引发的单点登录故障

临近年关&#xff0c;咨询师提出360、搜狗急速浏览器无法单点登录到公司核心产品WD: 重定向过多。现象经过测试&#xff0c; 出现单点登陆故障的是搜狗、360等双核浏览器(默认使用Chrome内核)&#xff0c; 较新式的Edge、Chrome、Firefox均未出现此障碍。Developer tool监测不到…

Asp.Net Core 已支持 gRPC-Web !!

grpc-dotnet 项目在 PR #695 完成了 ASP.NET Core 服务与 .NET Core gRPC 客户端的 gRPC-Web 实现。虽然目前还是实验性项目&#xff0c;但是并不阻碍我们为之兴奋。下面我们来看看如何使用。gRPC-Web 简介gRPC-Web 允许从浏览器应用程序使用 gRPC&#xff0c;gRPC-Web 支持在新…

蓝桥杯2017初赛-打印大X-找规律

题目描述 小明希望用星号拼凑&#xff0c;打印出一个大X&#xff0c;他要求能够控制笔画的宽度和整个字的高度。 为了便于比对空格&#xff0c;所有的空白位置都以句点符来代替。 要求输入两个整数m n&#xff0c;表示笔的宽度&#xff0c;X的高度。 输入 输入存在多组数据 …

蓝桥杯2015决赛-方格填数-枚举 or dfs

题目描述 在2行5列的格子中填入1到10的数字。 要求&#xff1a;相邻的格子中的数&#xff0c;右边的大于左边的&#xff0c;下边的大于上边的。 如下图所示的2种&#xff0c;就是合格的填法。 请你计算一共有多少种可能的方案。 输出 请输出该整数&#xff0c;不要输出任何多…

【实战 Ids4】║ 在Swagger中调试认证授权中心

回家的路上照顾好自己哟~大家好&#xff0c;老张已经顺利到家啦&#xff0c;闲的无事写两篇文章冒个泡吧&#xff0c;其实写的内容都是群友提出来的问题&#xff0c;简单的我会在群里直接提供思路&#xff0c;麻烦的我就写个文章说明一下吧&#xff0c;也是自己的一个记录作用&…

linux 集群 java,Linux Tomcat 集群 利用记实1--搭建javaWeb运行情况

前段时候一向在搞linux&#xff0c;有很多多少工具只曩昔没有做过。影象不是那么深刻&#xff0c;此刻把历程记实下来&#xff0c;以备今后盘问。一&#xff1a;起首说一下我们的计划&#xff0c; 一共有六台办事器&#xff0c;此中两台安置Oracle 10g做数据库集群(这个不在这篇…

在 Blazor WebAssembly 中使用 gRPC-Web

对于单页面应用程序&#xff0c;gRPC-Web 是 JSON-over-HTTP 的一种方便、高性能的替代方案。如果你已经了解关于 gRPC 和 gRPC-Web 的一切&#xff0c;你可以跳到 添加 gRPC 服务到一个Blazor WebAssembly 应用程序 一节。如果你只是想要一些简单的 Blazor WebAssembly gRPC-…

【新书推荐】《ASP.NET Core微服务实战:在云环境中开发、测试和部署跨平台服务》 带你走近微服务开发...

《ASP.NET Core 微服务实战》译者序&#xff1a;https://blog.jijiechen.com/post/aspnetcore-microservices-preface-by-translator/“微服务”的概念在 2014 年正式提出之后&#xff0c;越来越多的团队开始用它来设计自己的业务系统&#xff0c;各种微服务框架和开发过程管理…

.NET Core验证ASP.NET密码

.NET Core验证ASP.NET密码随着 .NETCore的持续更新和完善&#xff0c;越来越多的机构已经选择或者升级为 .NETCore。但由于技术不完全相同&#xff0c;不可能所有应用/数据库都能无缝迁移&#xff0c;因此 ASP.NETCore和传统 ASP.NET之间多少会存在一些挑战&#xff0c;需要更多…

linux下I2C驱动发送IO时序,I2C驱动情景分析——怎样控制I2C时序

内核版本&#xff1a;linux-3.4.2源程序&#xff1a; linux-3.4.2\drivers\i2c\busses\I2c-s3c2410.c这次要解决的问题是&#xff1a;如何配置soc的I2C模块&#xff0c;输出想要的时序波形&#xff1f;关于Linux里I2C驱动的架构&#xff0c;在转载的文章讲得相当透彻(《linu…

蓝桥杯2017初赛-外星日历-数论

题目描述 某星系深处发现了文明遗迹。他们的计数也是用十进制。 他们的文明也有日历。日历只有天数&#xff0c;没有年、月的概念。 有趣的是&#xff0c;他们也使用了类似“星期”的概念&#xff0c;只不过他们的一个星期包含了9天&#xff0c;为了方便&#xff0c;这里分别记…

ubuntu14.04安装linux公社,Ubuntu 14.04下安装IT++

Ubuntu 14.04 下安装 IT(itpp)(官方二进制包安装版)温馨提示&#xff1a;虽然没有尝试&#xff0c;不过直接运行最后一步应该也可以成功。另外&#xff0c;既然有简单的方法&#xff0c;不到破不得以还是不要尝试麻烦的方法了。1、安装 FFTW3sudo apt-get install libfftw3-dev…

.NET CORE(C#) WPF 值得推荐的动画菜单设计

微信公众号&#xff1a;Dotnet9&#xff0c;网站&#xff1a;Dotnet9&#xff0c;问题或建议&#xff1a;请网站留言&#xff0c; 如果对您有所帮助&#xff1a;欢迎赞赏。.NET CORE(C#) WPF 值得推荐的动画菜单设计阅读导航本文背景代码实现本文参考源码1. 本文背景YouTube上老…

蓝桥杯2017初赛-k倍区间-前缀和

题目描述 给定一个长度为N的数列&#xff0c;A1, A2, … AN。 如果其中一段连续的子序列Ai, Ai1, … Aj(i < j)之和是K的倍数&#xff0c;我们就称这个区间[i, j]是K倍区间。 你能求出数列中总共有多少个K倍区间吗&#xff1f; 输入 第一行包含两个整数N和K。(1 < N, K …

【在路上3】大数据离线分析快递的派件时效

【在路上1】快递物流大数据的由来【在路上2】快递的运单轨迹几乎人人都用过快递&#xff0c;如果说用户最在意什么&#xff1f;那必然是谁家送得快&#xff01;这也是整个快递物流行业被诟病最多的地方。都知道顺丰送得快&#xff0c;但价格摆在那里&#xff0c;且它的市场份额…

DevExpress作为企业赞助商加入.NET基金会

.NET基金会是一个独立的非营利组织&#xff0c;于2014年成立&#xff0c;旨在围绕 .NET 不断增长的开源技术集合&#xff0c;促进开放开发和协作。它是商业和社区开发人员的论坛&#xff0c;通过促进开放性&#xff0c;社区参与和快速创新来增强.NET生态系统的未来。要使.NET 基…

如何快速融入团队(八)

作者&#xff1a;邹溪源&#xff0c;长沙资深互联网从业者&#xff0c;架构师社区特邀嘉宾&#xff01;一感慨时间流逝&#xff0c;韶华易老似乎是我们与生俱来的焦虑&#xff0c;仿佛每当过年的时候总会感觉&#xff0c;呀&#xff0c;我这一年似乎什么都没干呀。你看&#xf…

Docker:使用本地卷和tmpfs挂载

卷是为Docker容器保留数据的首选方法。在本文中&#xff0c;将展示如何创建和使用卷来实现持久性&#xff0c;以及如何使用tmpfs来实现临时存储。最简单的说&#xff0c;创建和安装由本地目录支持的卷如下所示&#xff1a;# make host directory mkdir -p /data# create docker…