如何利用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,一经查实,立即删除!

相关文章

蓝桥杯2015初赛-加法变乘法-枚举

题目描述 我们都知道&#xff1a;123 … 49 1225 现在要求你把其中两个不相邻的加号变成乘号&#xff0c;使得结果为2015 比如&#xff1a; 123…101112…272829…49 2015 就是符合要求的答案。 请你寻找另外一个可能的答案&#xff0c;并把位置靠前的那个乘号左边的数字提…

linux 如何赋值目录,Linux文件系统之目录的建立

一&#xff1a;前言在用户空间中&#xff0c;建立目录所用的API为mkdir().它在内核中的系统调用入口是sys_mkdir().今天跟踪一下函数来分析linux文件系统中目录的建立过程.二&#xff1a;sys_mkdir()Sys_mkdir()对应的代码如下&#xff1a;asmlinkage long sys_mkdir(const cha…

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

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

蓝桥杯2017初赛-迷宫-dfs

题目描述 X星球的一处迷宫游乐场建在某个小山坡上。它是由10x10相互连通的小房间组成的。 房间的地板上写着一个很大的字母。我们假设玩家是面朝上坡的方向站立&#xff0c;则&#xff1a; L表示走到左边的房间&#xff0c;R表示走到右边的房间&#xff0c;U表示走到上坡方向的…

ubuntu系统虚拟机linux系统,基于虚拟机的Linux操作系统安装(Ubuntu

《基于虚拟机的Linux操作系统安装(Ubuntu》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《基于虚拟机的Linux操作系统安装(Ubuntu(13页珍藏版)》请在人人文库网上搜索。1、实验报告1课程名称&#xff1a; Linux程序设计 实验名称&#xff1a;基于虚拟机的Linux操作系…

如何快速融入团队(六)

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

Linux 脚本修改ini,Shell脚本读取ini配置文件的实现代码2例

一、简单版参考stackoverflow的例子&#xff0c;改了一个出来&#xff1a;while IFS read var valdoif [[ $var \[*] ]]thensection$(echo $var | sed s/^\[\(.*\)\]$/\1/)elif [[ $val ]]thenif [ -z $section ];thendeclare "${var}$val"elsedeclare "${sec…

蓝桥杯2017初赛-油漆面积-枚举

题目描述 X星球的一批考古机器人正在一片废墟上考古。该区域的地面坚硬如石、平整如镜。 管理人员为方便&#xff0c;建立了标准的直角坐标系。 经过各种测量&#xff0c;每个机器人都会报告一个或多个矩形区域&#xff0c;作为优先考古的区域。 矩形的表示格式为(x1,y1,x2,y2…

临近年关,修复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的高度。 输入 输入存在多组数据 …

排查生产问题linux命令,排查问题所用到的一些Linux命令实践(不定期更新。。)...

一、前言线上问题排查可能是每个程序员都会经历的。在排查的过程中&#xff0c;往往会用到很多Linux命令&#xff0c;也会产生一些很实用的技巧。本博文通过分析一次线上问题排查的过程&#xff0c;把所有用到的命令串起来。每个Linux命令的参数往往会很多&#xff0c;下面对Li…

蓝桥杯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做数据库集群(这个不在这篇…

蓝桥杯2016初赛-网友年龄-枚举

题目描述 某君新认识一网友。 当问及年龄时&#xff0c;他的网友说&#xff1a;“我的年龄是个2位数&#xff0c;我比儿子大27岁,如果把我的年龄的两位数字交换位置&#xff0c;刚好就是我儿子的年龄” 请你计算&#xff1a;网友的年龄一共有多少种可能情况&#xff1f; 输出…

linux下yum安装pgsql,CentOS7使用yum安装PostgreSQL和PostGIS的方法

1.更新yum源CentOS7默认yum源的PostgreSQL版本过低&#xff0c;不适合在本版本上使用。在https://yum.postgresql.org/repopackages.php上找到适合CentOS7的RPM源&#xff0c;复制其url地址&#xff0c;使用yum安装。同时安装epel(Extra Packages for Enterprise Linux 7)&…

在 Blazor WebAssembly 中使用 gRPC-Web

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

蓝桥杯2016初赛-生日蜡烛-枚举

题目描述 某君从某年开始每年都举办一次生日party&#xff0c;并且每次都要吹熄与年龄相同根数的蜡烛。 现在算起来&#xff0c;他一共吹熄了236根蜡烛。 请问&#xff0c;他从多少岁开始过生日party的&#xff1f; 输出 请填写他开始过生日party的年龄数。 代码如下&#…

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

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