基于.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 ...
随机推荐
- Ethical Hacking - GAINING ACCESS(22)
CLIENT SIDE ATTACKS - BeEf Framework Browser Exploitation Framework allowing us to launch a number o ...
- Spring声明式事务快速上手
1.什么是事务 首先我们要知道什么是事务.知其然,才能知其所以然. 事务(Transaction)是一个业务,是一个不可分割的逻辑工作单元,基于事务可以更好的保证业务的正确性. 这么说可能有点难以理解 ...
- PyQt5多线程和定时器
多线程 一般情况单线程就可以很好的完成任务,但是对于GUI程序来说,单线程就不能完全满足需求.如果有耗时流程,在单线程的情况下,界面操作就会卡死,直到耗时操作完成,才会响应界面操作.为了解决这个问题, ...
- C++语法小记---同名覆盖
同名覆盖 子类中的同名成员会覆盖父类中的同名成员,但是在内存中仍然存在,只是无法直接访问,需要加上域名才能访问 子类中的同名函数会覆盖父类中的函数,复写是同名覆盖的一种特殊情况,只要不是多态场景,复写 ...
- .net core 自带分布式事务的微服务开源框架JMS
事务的统一性是微服务的一个重点问题,简洁有效的控制事务,更是程序员所需要的.JMS的诞生,就是为了更简单.更有效的控制事务. 先看一段调用微服务的代码: using (var ms = new JMS ...
- 【Logisim实验】构建立即数-随机存储器-寄存器的传送
关于Logisim Logisim在仿真软件行列中算是比较直观的软件了,它能做的事情有很多,唯一不足的是硬件描述语言的支持,总体上来说适合比较底层的仿真,依赖于Hex值,通过线路逻辑设计能够较好的 关 ...
- 【laravel】用户认证之----手动认证用户
模型 如果某个模型类需要用于认证,必须继承自 Illuminate\Foundation\Auth\User 基类,否则会报错.然后在这个模型类中使用 Notifiable Trait,里面提供了用户 ...
- Salt 系统初始化
目录 编辑states文件 1.DNS配置 dns.sls(在init目录下创建一个files文件,然后把resolv.conf放到文件下) [root@master init]# cat dns. ...
- zabbix修改默认密码
1.mysql -u root -p 2.desc users; 3.select userid,alias,passwd from users; 4.update users set passwd= ...
- jmeter单接口和多接口测试
@@@@@@@@@@@@@@@ # 路漫漫其修远 最近接触到了多接口串联,接口串联的技术会在其他帖子有说明,其核心技术点就是通过正则表达式和变量来实现接口的关联.目前为止呢笔者用到的地方还只有一个,就 ...