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

ASP.NET Core 中依赖注入是一个很重要的环节。因为几乎所有的对象都是由它创建的(相关文章请参见《ASP.NET Core 沉思录 - ServiceProvider 的二度出生》)。因此整个日志记录的相关类型也被直接添加到了 IServiceCollection 中。今天我们将介绍各个接口/类型之间的关系,并找到介入日志记录功能的两个主要的入口。

ASP.NET Core 的日志功能结构

为什么当我们恰当对日志进行配置之后就可以记录日志呢。那是因为 Framework 一定已经将最关键的类型添加到了 IServiceCollection 中。在 ASP.NET Core 中,应用程序的启动一定会创建 WebHost 而创建 WebHost 一般会用到 WebHostBuilder。在 WebHostBuilder 创建过程中就将一些核心的日志记录相关类型添加到了 IServiceCollection 中。

前面我们介绍过,IServiceProvider 有两次创建过程,一次是在调用 WebHostBuilder.Build 时创建的 Hosting 相关的 IServiceProvider,另一次是在 WebHost.StartXxx 方法时创建的应用程序使用的 IServiceProvider。而日志相关类型第一次的 IServiceProvider 创建之前就已经添加到 IServiceCollection 中了。

在本文写作时,第一次 IServiceCollection 实例的创建是在 WebHostBuilder.BuildCommonServices 方法中,大概的流程是:

  • 创建 ServiceCollection

  • 调用 AddLogging 扩展方法

  • IOptions<>; 及其它形式、ILoggerFactoryILogger<>IConfiguratorIConfigureOptions 添加到 ServiceCollection 中。

  • 如果在配置 IWebHostBuilder 过程中调用过 ConfigureLogging 则调用相关委托添加或替换相关日志记录的类型。

代码请参见:WebHostBuilder.cs (https://github.com/aspnet/AspNetCore/blob/master/src/Hosting/Hosting/src/WebHostBuilder.cs) 以及LoggingServiceCollectionExtensions.cs (https://github.com/aspnet/Extensions/blob/master/src/Logging/Logging/src/LoggingServiceCollectionExtensions.cs)。

因此,以上提到的类型就是日志功能的核心类型了。梳理一下这些类型的依赖关系就可以弄清 ASP.NET Core 的日志功能结构了。

弄清一个结构需要关注两个部分的内容,第一个部分是声明上的依赖关系(静态),另一个部分是调用上的依赖关系(动态)。因此我们也会采用这种方式进行梳理。首先声明上的依赖关系如下:

640?wx_fmt=png

以上结构在运行时会创建三层 ILogger 实现

  • 最外面的一层就是我们使用的 ILogger<> 实现。它是由 IServiceProvider 直接创建的。

  • 第二层是 LoggerFactory 创建的 Logger,它是一个组合 Logger。

  • 第三层是由 ILoggerProvider 实现创建的负责具体记录日志的 ILogger 实现。这些 Logger 都会添加到第二层的组合 Logger 中。

而后,在日志记录时,正是按照这三层结构进行任务分发的。

介入日志功能的几个入口

在了解上述结构之后不难使用我们的具体实现替换默认的 .NET 日志记录结构。首先在使用上 ASP.NET Core 上使用的日志记录接口有两种,第一种即 ILoggerFactory,进而创建 ILogger。例如 这里。而另外一种则是直接使用 ILogger<>。因此我们的介入点有两个:

  • 直接替换 ILoggerFactory 的实现,这样可以完全定义自己的 Logger -> Sink 结构和过滤逻辑;但工作量较大。

  • 实现 ILoggerProvider,并将其添加到 IServiceCollection 中。这样可以复用现有的日志逻辑。

很多第三方日志库就是有选择的采用了上述一种或者两种方式。例如,以 Serilog 为例,它支持上述两种接口:

首先、我们可以使用 webHostBuilder.UseSerilog(...) 的方式将其纳入应用程序中。而这种方式使用第一种介入方法。具体代码请看:https://github.com/serilog/serilog-aspnetcore/blob/dev/src/Serilog.AspNetCore/SerilogWebHostBuilderExtensions.cs。

其次、我们可以使用 loggerBuilder.AddSerilog(...) 的方式将其纳入应用程序中。而这种方式使用第二种介入方法。具体代码请看:https://github.com/serilog/serilog-extensions-logging/blob/dev/src/Serilog.Extensions.Logging/SerilogLoggingBuilderExtensions.cs。

总结

日志记录有很多可以思考的地方,今天我们只关注 ASP.NET Core 中日志介入的入口。总结起来有两个主要入口:

  • 第一、直接替换 ILoggerFactory 实现;

  • 第二、实现具体的 ILoggerProvider 并将其添加到 IServiceCollection 中。

如果您觉得本文对您有帮助,也欢迎分享给其他的人。我们一起进步。欢迎关注我的博客(https://clrdaily.com)和微信公众号:

640?wx_fmt=jpeg



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

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

相关文章

C# 中的Async 和 Await 的用法详解

众所周知C#提供Async和Await关键字来实现异步编程。在本文中&#xff0c;我们将共同探讨并介绍什么是Async 和 Await&#xff0c;以及如何在C#中使用Async 和 Await。同样本文的内容也大多是翻译的&#xff0c;只不过加上了自己的理解进行了相关知识点的补充&#xff0c;如果你…

Docker的部署-包括网关服务(Ocelot)+认证服务(IdentityServer4)+应用服务

本文主要介绍通过Docker来部署通过.Net Core开发的微服务架构&#xff0c;部署的微服务主要包括统一网关&#xff08;使用Ocelot开发&#xff09;、统一认证&#xff08;IdentityServer4&#xff09;、应用服务&#xff08;asp.net core web api&#xff09;&#xff1b;本文不…

ASP.NET Core 实战:使用 Docker 容器化部署 ASP.NET Core + MySQL + Nginx

一、前言在之前的文章&#xff08;ASP.NET Core 实战&#xff1a;Linux 小白的 .NET Core 部署之路&#xff09;中&#xff0c;我介绍了如何在 Linux 环境中安装 .NET Core SDK / .NET Core Runtime、Nginx、MySQL&#xff0c;以及如何将我们的 ASP.NET Core MVC 程序部署到 Li…

VS2017 无法连接到Web服务器“IIS Express”终极解决方案

今天日了gou了&#xff0c;一大早打开VS2017的时候出现无法连接到Web服务器“IIS Express”的错误&#xff0c;然后必应了一下&#xff0c;再谷歌了一下找到的解决方法也都千篇一律&#xff0c;奈何都没能解决&#xff0c;最后通过静下心来的思考&#xff0c;尝试解决了问题&am…

Docker最全教程之使用.NET Core推送钉钉消息(二十)

前言上一篇我们通过实战分享了使用Go推送钉钉消息&#xff0c;由于技痒&#xff0c;笔者现在也编写了一个.NET Core的Demo&#xff0c;作为简单的对照和说明。最后&#xff0c;由于精力有限&#xff0c;笔者希望有兴趣的朋友可以分享下使用CoreRT将.NET Core编译成机器代码这块…

Average

Average 题意&#xff1a; 矩阵W的值可以通过数组a和b得到&#xff0c;W[i][j]a[i]b[j],现在求W的一个子矩阵&#xff0c;平均值最大&#xff0c;且子矩阵必须满足宽度至少是x&#xff0c;高度至少是y&#xff0c;计算最大平均值 题解&#xff1a; 那答案就变成了分别对a和b…

开箱即用Bumblebee独立部署搭建webapi网关详解

在之前的章节里都是讲述如何在程序中使用Bumblebee来构建一个Webapi网关&#xff1b;但这样显然有些麻烦&#xff0c;毕竟很多时候可能只需要一个简单负载处理&#xff0c;还需要写个程序针对服务进行编写代码或配置的确是比较麻烦的事情&#xff1b;如果有负载方面的调整还需要…

ASP.NET Core 文件系统

静态文件 目录浏览 默认页面 MIME类型配置 实战文件服务器 紧接上一讲 中间件 之后&#xff0c;今天来我们来讲一下关于 ASP.NET Core 中静态文件服务。什么是静态文件&#xff1f;先看一下下面例子&#xff08;在客户端浏览器中通过 url 路径访问了网站的一张图片&#xff09…

如何使用vs将asp.net core项目添加容器支持并发布docker镜像到私有dockerhub和添加k8s/helm管理...

这篇文章介绍一下&#xff0c;如何使用VS2017给asp.net core添加容器支持&#xff0c;并发布镜像到私有docker hub&#xff0c;然后用chart管理容器镜像的操作流程。话不多说&#xff0c;just do it.新建项目首先新建一个asp.net core项目&#xff0c;这里我新建一个WebApi默认…

[小技巧]EF Core中如何获取上下文中操作过的实体

原文地址&#xff1a;https://www.cnblogs.com/lwqlun/p/10576443.html作者&#xff1a;Lamond Lu 源代码&#xff1a;https://github.com/lamondlu/EFCoreFindSample背景介绍当我们在工作单元(UnitOfWork)中使用EF/EF Core的时候&#xff0c;为了要保持事务&#xff0c;一个用…

IdentityServer4-前后端分离之Vue

前言之前文章讲到如何使用Node.jsExpress构建JavaScript客户端&#xff0c;实现前后端分离。本节将介绍如何使用Vue实现前后端分离&#xff0c;文中介绍Vue的知识比较基础&#xff0c;适合新手学习。一、搭建Vue项目前提条件&#xff1a;安装nodejs、webpack和vue-cli。这个网上…

P1850 [NOIP2016 提高组] 换教室

P1850 [NOIP2016 提高组] 换教室 题意&#xff1a; 有2n个课安排在n个时间段上&#xff0c;每个时间段上都有两个一样的课同时在不同地方上&#xff0c;起初牛牛被所有课都被安排在Ci上课&#xff0c;另一节课在Di上课。牛牛现在想跟换到Di位置&#xff0c;它最多可以申请m节…

ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署(三

在上文ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署&#xff08;二&#xff09;中&#xff0c;我介绍了如何使用Azure DevOps为ASP.NET Core应用程序案例&#xff1a;tasklist搭建持续集成环境。在持续集成的过程中&#xff0c;Azure DevOps的Build Pipeline会下…

ASP.NET Core开源Web应用程序框架ABP

"作为面向服务架构(SOA)的一个变体,微服务是一种将应用程序分解成松散耦合服务的新型架构风格. 通过细粒度的服务和轻量级的协议,微服务提供了更多的模块化,使应用程序更容易理解,开发,测试,并且更容易抵抗架构侵蚀. 它使小型团队能够开发,部署和扩展各自的服务,实现开发的…

CodeForces 1517G Starry Night Camping(网络流最小割)

CodeForces 1517G Starry Night Camping problem 洛谷链接 solution 这个平行四边形的脑洞我™真的长见识了 本题最离谱的要求就是&#xff1a;平行四边形的一条边平行于 xxx 轴。 而往往这种离谱要求就是正解的途径。(((φ(◎ロ◎;)φ))) 首先不观察也能知道&#xff0c…

Acwing 307. 连通图

Acwing 307. 连通图 题意&#xff1a; 求 N 个节点的无向连通图有多少个&#xff0c;节点有标号&#xff0c;编号为 1∼N。 例如下列图示&#xff0c;三个节点的无向连通图共 4 个。 题解: 用py写 代码&#xff1a; def c(n, m):n int(n)m int(m)ret 1for i in range(…

Acwing 309. 装饰围栏

Acwing 309. 装饰围栏 题意&#xff1a; 有n个模板&#xff0c;长度分别是1到N&#xff0c;现在按照高低交错的方式排列模板&#xff0c;能到的很多种排列的方案。 每个方案都可以写作一个长度为N的序列&#xff0c;序列中的个元素是木板的长度&#xff0c;把这些序列按照字典…

CodeForces 901D Weighting a Tree(结论)

problem 洛谷链接 注意&#xff1a;保证 C[v]C[v]C[v] 的奇偶性与顶点 vvv 的度的奇偶性相同。 solution 先考虑树的情况。这是个经典问题了&#xff0c;从叶子往上推&#xff0c;对于一个点还差的边权就有这个点和其父亲的边来补足。最后判断根是否满足条件即可。 那么怎…

CF938E Max History

CF938E Max History 题意&#xff1a; 我们定义f(a)为&#xff1a; 1、开始时&#xff0c;f(a)0,M1。 2、对于每个2<i<n,如果a[M]<a[i],那么f(a)f(a)a[M],Mi。 现在对于一个给定的数组a&#xff0c;求其所有排列的f(a)之和&#xff0c;答案对1e97取模。 题解&am…

CodeForces 1491G Switch and Flip(结论)

problem 洛谷链接 solution 弱化版&#xff1a;如果不考虑翻面&#xff0c;那就是转化为若干个环的问题了。 这里我们尝试用同样的思路解决。 首先明确几个硬币一次交换后的等价情况&#xff0c;如图&#xff08;灰色表示反面&#xff09; &#xff08;u→vu\rightarrow …