基于.NetCore3.1系列 —— 日志记录之自定义日志组件
一、前言
在上一篇中,我们通过学习了解在.net core 中内置的日志记录中的几大核心要素,在日志工厂记录器(ILoggerFactory)中实现将日志记录提供器(ILoggerProvider)对象都可以集成到Logger对象组合中,这样的话,我们就可以通过基于ILoggerProvider自定义日志记录程序集成到Logger中,再创建写日志定义Ilogger,自定义日志记录器实现日志的输出方式,这样实现自定义日志记录工具。
在这个过程中,日志记录器ILogger中的Log()方法会记录执行日志,通过在ILoggerFactory产生的是ILogger类型(也就是我们最终使用的Logger),其Log()方法是依次调用Logger中包含的LoggerInformation[]数组中的ILogger。而ILoggerProvider产生的为各类不同的XxxLogger(也就是上面说的Logger中的LoggerInformation数组包含的如ConsoleLogger、DebugLogger),其Log()方法是把日志写到具体的目标上去,所以我们自定义的日志程序也可以在日志记录器工厂中实现添加日志程序,达到将日志写到具体目标的作用。
所以下文我们通过自定义的方式实现ILogger、ILoggerProvider两个接口来实现我们自己想要的日志记录程序,实现自定义输出目标方式。(下文只是简单的根据接口自定义实现输出日志记录到控制台的demo)

二、开始
2.1 自定义Logger
创建一个自定义Logger,目的是将指定的等级日志输出到控制台。所以我们创建一个ExtensionLogger的类,指定输出的日志等级。所以在这之前,我们需要配置一下输入日志的等级,因此我们需要增加一个等级的配置类ExtensionsConfiguration。
在ExtensionsConfiguration中,
public class ExtensionsConfiguration
{
/// <summary>
/// 日志等级
/// </summary>
public LogLevel LogLevel { get; set; } = LogLevel.Warning;
}
再自定义日志记录类ExtensionLogger,实现接口ILogger,
public class ExtensionsLogger : ILogger
{
private readonly ExtensionsConfiguration _config;
public ExtensionsLogger(ExtensionsConfiguration extensionsConfiguration)
{
_config = extensionsConfiguration;
}
public IDisposable BeginScope<TState>(TState state)
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return logLevel == _config.LogLevel;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state,
Exception exception, Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
Console.WriteLine($" {logLevel} - {eventId.Id} : " + formatter(state, exception));
}
}
根据ILogger接口实现,其中实现Log()接口方法,将日志输出到指定目标,这里是输出到控制台,在设置了日志等级的情况条件下,当满足条件后,才能输出对应的日志。
2.2 自定义LoggerProvider
在创建了日志输出记录后,我们同时需要提供一个日志程序来增加和创建上面的Logger记录,所以我们通过自定义日志提供器类ExtensionsLoggerProvider,实现ILoggerProvider类。
public class ExtensionsLoggerProvider : ILoggerProvider
{
private readonly ExtensionsConfiguration _config;
public ExtensionsLoggerProvider(ExtensionsConfiguration extensionsConfiguration)
{
_config = extensionsConfiguration;
}
public ILogger CreateLogger(string categoryName)
{
return new ExtensionsLogger(_config);
}
public void Dispose()
{
}
}
基于ILoggerProvider接口实现自定义类,实现方法CreateLogger,来创建上面的日志记录。
2.3 使用
在Startup.cs中,通过Configure方法调用配置日志记录。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env , ILoggerFactory loggerFactory)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// 注入ILogggerFactory,然后配置参数
//添加日志等级
loggerFactory.AddProvider(new ExtensionsLoggerProvider(new ExtensionsConfiguration { LogLevel= LogLevel.Warning }));
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
在此之前,我们可以清空默认的配置,然后根据日志等级,在控制台中输出对应的日志记录。
2.4 效果
在等级为Information情况下,输出效果如下:

这个就是我们通过自定义的方式实现的按日志等级输出的记录。
三、拓展
3.1 写入本地文件
第一步:为LoggerFactory扩张一个方法,提供增加日志写文件方式的入口。相关的配置来自appsettings.json
第二步:实现我们的logger提供程序,实现ILoggerProvider接口,关键方法CreateLogger,创建真正写日志的logger。对当前的logger可以做适当的缓存,配置logger
第三步:实现我们的logger,实现ILogger接口。真正将log写入file。
这里可以参考网友的资料 :.Net Core Logger 实现log写入本地文件系统
四、总结
上文中,我们通过自定义的方式实现了根据日志等级将日志记录输出到指定目标的方式,在这种基础上,我们可以根据具体的需求做完善修改,实现自己的日志记录输出方式。
除了我们通过自定义的方式之外,我们也可以借用第三方日志框架组件程序进行使用,根据拓展方法进行调用,在后续中我们会使用第三方日志记录程序来实现日志记录的输出。
如果有不对的或不理解的地方,希望大家可以多多指正,提出问题,一起讨论,不断学习,共同进步。
本文项目源码下载
基于.NetCore3.1系列 —— 日志记录之自定义日志组件的更多相关文章
- 基于.NetCore3.1系列 —— 日志记录之初识Serilog
一.前言 对内置日志系统的整体实现进行了介绍之后,可以通过使用内置记录器来实现日志的输出路径.而在实际项目开发中,使用第三方日志框架(如: Log4Net.NLog.Loggr.Serilog.Sen ...
- 基于.NetCore3.1系列 —— 认证授权方案之授权揭秘 (下篇)
一.前言 回顾:基于.NetCore3.1系列 -- 认证授权方案之授权揭秘 (上篇) 在上一篇中,主要讲解了授权在配置方面的源码,从添加授权配置开始,我们引入了需要的授权配置选项,而不同的授权要求构 ...
- 基于.NetCore3.1系列 ——认证授权方案之Swagger加锁
一.前言 在之前的使用Swagger做Api文档中,我们已经使用Swagger进行开发接口文档,以及更加方便的使用.这一转换,让更多的接口可以以通俗易懂的方式展现给开发人员.而在后续的内容中,为了对a ...
- 基于.NetCore3.1系列 —— 日志记录之日志配置揭秘
一.前言 在项目的开发维护阶段,有时候我们关注的问题不仅仅在于功能的实现,甚至需要关注系统发布上线后遇到的问题能否及时的查找并解决.所以我们需要有一个好的解决方案来及时的定位错误的根源并做出正确及时的 ...
- 基于.NetCore3.1系列 —— 日志记录之日志核心要素揭秘
一.前言 在上一篇中,我们已经了解了内置系统的默认配置和自定义配置的方式,在学习了配置的基础上,我们进一步的对日志在程序中是如何使用的深入了解学习.所以在这一篇中,主要是对日志记录的核心机制进行学习说 ...
- Flask系列(十)自定义Form组件
一.wtforms源码流程 1.实例化流程分析 # 源码流程 1. 执行type的 __call__ 方法,读取字段到静态字段 cls._unbound_fields 中: meta类读取到cls._ ...
- 如何定制.NET6.0的日志记录
在本章中,也就是整个系列的第一部分将介绍如何定制日志记录.默认日志记录仅写入控制台或调试窗口,这在大多数情况下都很好,但有时需要写入到文件或数据库,或者,您可能希望扩展日志记录的其他信息.在这些情况下 ...
- Spring aop+自定义注解统一记录用户行为日志
写在前面 本文不涉及过多的Spring aop基本概念以及基本用法介绍,以实际场景使用为主. 场景 我们通常有这样一个需求:打印后台接口请求的具体参数,打印接口请求的最终响应结果,以及记录哪个用户在什 ...
- SpringBoot系列(十三)统一日志处理,logback+slf4j AOP+自定义注解,走起!
往期精彩推荐 SpringBoot系列(一)idea新建Springboot项目 SpringBoot系列(二)入门知识 springBoot系列(三)配置文件详解 SpringBoot系列(四)we ...
随机推荐
- 牛客练习赛66A题解
思路 令 \(sq=\sqrt x\) ,则答案必然在 $ sq^2$ 和 $ (sq+1)^2 $ 之间,两者比较一下谁离 \(x\) 最近,就是答案了. 代码 #include <bits/ ...
- C++语法小记---string和int的相互转换
string和int的相互转换 string转int istringstream is(""); //构造输入字符串流,流的内容初始化为“12”的字符串 int i; is > ...
- springboot+redis做事件过期通知业务
springboot+redis做事件过期通知 博主也是初次体验,不足之处多多指教 我的业务场景 系统管理员要给维护员分配巡查路口设施的工作,由于路口比较多,管理员不知道哪些路口已经被分配了,况且过了 ...
- python-元类和使用元类实现简单的ORM
元类 面向对象中,对象是类的实例,即对象是通过类创建出来的,在python中,一切皆对象,同样,类也是一个对象,叫做类对象,只是这个类对象拥有创建其子对象(实例对象)的能力.既然类是对象,那么类是通过 ...
- SQL语句中带有EXISTS谓词的子查询的理解与使用
EXISTS:代表存在量词. 在SQL中,把具有全称量词的谓词查询问题转换成等价的存在量词的谓词查询予以实现. 如有三个表,Student(Sno,Sname),Course(Cno,Cname),S ...
- android 官方教程地址和一个中文教程
https://developer.android.google.cn/guide/components/fundamentals http://www.runoob.com/w3cnote/andr ...
- Spring集成CXF发布WebService并在客户端调用
Spring集成CXF发布WebService 1.导入jar包 因为官方下载的包里面有其他版本的sprring包,全导入会产生版本冲突,所以去掉spring的部分,然后在项目根目录下新建了一个CXF ...
- String常用处理方法
1.去空格 用于删除字符串的头尾空白符. 语法:public String trim() 返回值:删除头尾空白符的字符串. 删除所有空格 str.replace(" ", &quo ...
- 那些年拿过的shell之springboot jolokia rce
日穿扫描扫到一个spring boot actuator 可以看到有jolokia这个端点,再看下jolokia/list,存在type=MBeanFactory 关键字 可以使用jolokia-re ...
- UDP 网络程序-发送_接收数据
""" 创建udp连接 发送数据给 """ from socket import * # 创建udp套接字,使用SOCK_DGRAM udp ...