.Net6 Web Core API --- AOP -- log4net 封装 -- MySQL -- txt

目录

一、引入 NuGet 包

二、配置log4net.config  

三、编写Log4net封装类

四、编写日志记录类

五、AOP -- 拦截器 -- 封装

六、案例编写

七、结果展示


一、引入 NuGet 包

log4net 

Microsoft.Extensions.Logging.Log4Net.AspNetCore   

MySql.Data         ----  MySQL数据库需要

Newtonsoft.Json

Autofac

Autofac.Extensions.DependencyInjection

Autofac.Extras.DynamicProxy

二、配置log4net.config  

    注:当前网上有两种 log4net.config 配置文件, 一种是以<log4net>为根目录, 另一种以<configuration> 为根目录

<?xml version="1.0" encoding="utf-8"?><log4net><!--正常日志:::记录正常日志--><!-- appender 定义日志输出方式   将日志以回滚文件的形式写到MySQL数据库中。--><appender name="ADONetAppender" type="log4net.Appender.ADONetAppender"><!-- 代表缓存大小,在没达到缓存大小时,暂时不会存到数据库中, --><!-- 当程序关闭之后,会将未插入的信息加入到数据库中 --><bufferSize value="1" /><!--引入《MySql.Data》包--><param name="ConnectionType" value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" /><!--配置连接数据库的字符串--><param name="ConnectionString" value="server=localhost;database=TTTTT;uid=root;pwd=123456;"/><!--配置MySQL的插入语句--><param name="CommandText" value="insert into log4net(log_datetime,log_thread,log_level,log_logger,log_message) values(@log_datetime, @log_thread , @log_level, @log_logger, @log_message)" /><param name="Parameter"><param name="ParameterName" value="@log_datetime" /><param name="DbType" value="DateTime" /><param name="Layout" type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%d{yyyy'-'MM'-'dd HH':'mm':'ss}" /></param></param><param name="Parameter"><param name="ParameterName" value="@log_thread" /><param name="DbType" value="String" /><param name="Size" value="255" /><param name="Layout" type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%t" /></param></param><param name="Parameter"><param name="ParameterName" value="@log_level" /><param name="DbType" value="String" /><param name="Size" value="255" /><param name="Layout" type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%p" /></param></param><param name="Parameter"><param name="ParameterName" value="@log_logger" /><param name="DbType" value="String" /><param name="Size" value="255" /><param name="Layout" type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%c" /></param></param><param name="Parameter"><param name="ParameterName" value="@log_message" /><param name="DbType" value="String" /><param name="Size" value="4000" /><param name="Layout" type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%m" /></param></param></appender><!--正常日志:::记录正常日志--><!--按日期分割日志文件 一天一个--><!-- appender 定义日志输出方式   将日志以回滚文件的形式写到文件中。--><appender name="RollingFile" type="log4net.Appender.RollingFileAppender"><!-- 定义中文编码类型  UTF-8--><param name="Encoding" value="utf-8" /><!--定义文件存放位置--><file value="Log\log_"/><!--是否追加到文件--><appendToFile value="true"/><!--记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock"/><!--最多产生的日志文件数,超过则只保留最新的n个。设定值value="-1"为不限文件数--><maxSizeRollBackups value="-1"/><!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])--><rollingStyle value="Composite"/><datePattern value="yyyy\\yyyyMM\\yyyyMMdd'.txt'"/><!--是否只写到一个文件中--><staticLogFileName value="false"/><!--每个文件的大小。只在混合方式与文件大小方式下使用。超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志--><maximumFileSize value="100MB"/><!--计数类型为1,2,3…--><!--<param name="CountDirection" value="1"/>--><layout type="log4net.Layout.PatternLayout"><!--输出格式-样例:记录时间:2022-08-24 17:59:31,172    线程ID:[4]    日志级别:INFO  当前类:Log4NetDemo.MainClass  日志描述:创建连接。--><conversionPattern value="记录时间:%date  线程ID:[%thread]  日志级别:%-5level 当前类:%logger %newline日志描述:%message  %newline %newline"/></layout></appender><!--错误日志:::记录错误日志--><!--按日期分割日志文件 一天一个--><!-- appender 定义日志输出方式   将日志以回滚文件的形式写到文件中。--><appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender"><!-- 定义中文编码类型  UTF-8--><param name="Encoding" value="utf-8" /><!--定义文件存放位置--><file value="Log\error_"/><!--是否追加到文件--><appendToFile value="true"/><!--记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock"/><!--最多产生的日志文件数,超过则只保留最新的n个。设定值value="-1"为不限文件数--><maxSizeRollBackups value="-1"/><!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])--><rollingStyle value="Composite"/><datePattern value="yyyy\\yyyyMM\\yyyyMMdd'.txt'"/><!--是否只写到一个文件中--><staticLogFileName value="false"/><!--每个文件的大小。只在混合方式与文件大小方式下使用。超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志--><maximumFileSize value="100MB"/><!-- layout 控制Appender的输出格式,也可以是xml  一个Appender只能是一个layout--><layout type="log4net.Layout.PatternLayout"><!--每条日志末尾的文字说明--><!--输出格式 模板--><!-- <param name="ConversionPattern"  value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 记录类:%logger   操作者ID:%property{Operator} 操作类型:%property{Action}%n  当前机器名:%property%n当前机器名及登录用户:%username %n  记录位置:%location%n 消息描述:%property{Message}%n   异常:%exception%n 消息:%message%newline%n%n" />--><!--样例:2008-03-26 13:42:32,111 [10] INFO  Log4NetDemo.MainClass [(null)] - info--><!--<conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别: %-5level %n错误描述:%message%newline %n"/>--><conversionPattern value="%n==========%n【日志级别】%-5level%n【记录时间】%date%n【执行时间】[%r]毫秒%n【错误位置】%logger 属性[%property{NDC}]%n【错误描述】%message%n【错误详情】%newline"/></layout><filter type="log4net.Filter.LevelRangeFilter,log4net"><levelMin value="ERROR" /><levelMax value="FATAL" /></filter></appender><!--DEBUG:::记录DEBUG日志--><!--按日期分割日志文件 一天一个--><!-- appender 定义日志输出方式   将日志以回滚文件的形式写到文件中。--><appender name="DebugAppender" type="log4net.Appender.RollingFileAppender"><!-- 定义中文编码类型  UTF-8--><param name="Encoding" value="utf-8" /><!--定义文件存放位置--><file value="Log\debug_"/><!--是否追加到文件--><appendToFile value="true"/><!--记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock"/><!--最多产生的日志文件数,超过则只保留最新的n个。设定值value="-1"为不限文件数--><maxSizeRollBackups value="-1"/><!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])--><rollingStyle value="Composite"/><datePattern value="yyyy\\yyyyMM\\yyyyMMdd'.txt'"/><!--是否只写到一个文件中--><staticLogFileName value="false"/><!--每个文件的大小。只在混合方式与文件大小方式下使用。超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志--><maximumFileSize value="100MB"/><!-- layout 控制Appender的输出格式,也可以是xml  一个Appender只能是一个layout--><layout type="log4net.Layout.PatternLayout"><!--输出格式-样例:记录时间:2022-08-24 17:59:31,172    线程ID:[4]    日志级别:INFO  当前类:Log4NetDemo.MainClass  日志描述:创建连接。--><conversionPattern value="记录时间:%date  线程ID:[%thread]  日志级别:%-5level 当前类:%logger %newline日志描述:%message  %newline %newline"/></layout><filter type="log4net.Filter.LevelRangeFilter,log4net"><levelMin value="DEBUG" /><levelMax value="WARN" /></filter></appender><root><!--日志等级:OFF > FATAL > ERROR > WARN > INFO > DEBUG  > ALL--><level value="ALL" /><appender-ref ref="ADONetAppender" /><appender-ref ref="RollingFile" /><appender-ref ref="ErrorAppender" /><appender-ref ref="DebugAppender" /></root></log4net>

三、编写Log4net封装类

public static class CustomLog4netExt
{public static void AddLog4netExt(this WebApplicationBuilder builder){// 添加 Log4net 配置文件builder.Logging.AddLog4Net("log4net.config");// log错误日志配置builder.Services.AddControllers(options =>{options.SuppressAsyncSuffixInActionNames = false;options.Filters.Add(typeof(GlobalExceptionsFilter));});}
}

四、编写日志记录类

全局报错监测类

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;namespace Log4Test.Log4;/// <summary>
/// 全局异常错误日志
/// </summary>
public class GlobalExceptionsFilter : IExceptionFilter
{private readonly IWebHostEnvironment _env;private readonly ILogger<GlobalExceptionsFilter> _logger;public GlobalExceptionsFilter(IWebHostEnvironment env, ILogger<GlobalExceptionsFilter> logger){_env = env;_logger = logger;}public void OnException(ExceptionContext context){var json = new JsonErrorResponse();json.Message = context.Exception.Message;//错误信息if (_env.IsDevelopment()){json.DevelopmentMessage = context.Exception.StackTrace;//堆栈信息}context.Result = new InternalServerErrorObjectResult(json);//采用log4net 进行错误日志记录_logger.LogError(WriteLog(json.Message, context.Exception));}/// <summary>/// 自定义返回格式/// </summary>/// <param name="throwMsg"></param>/// <param name="ex"></param>/// <returns></returns>public string WriteLog(string throwMsg, Exception ex){return string.Format("【自定义错误】:{0} \r\n" +"【异常类型】:{1} \r\n" +"【异常信息】:{2} \r\n" +"【堆栈调用】:{3}", new object[] { throwMsg,ex.GetType().Name, ex.Message, ex.StackTrace });}}public class InternalServerErrorObjectResult : ObjectResult
{public InternalServerErrorObjectResult(object value) : base(value){StatusCode = StatusCodes.Status500InternalServerError;}
}
//返回错误信息
public class JsonErrorResponse
{/// <summary>/// 生产环境的消息/// </summary>public string Message { get; set; }/// <summary>/// 开发环境的消息/// </summary>public string DevelopmentMessage { get; set; }
}

日常方法监测类

using Castle.DynamicProxy;
using Newtonsoft.Json;namespace LOG.Test;/// <summary>
/// 自定义 方法拦截器
/// </summary>
public class CustomInterceptor : IInterceptor
{private readonly ILogger<CustomInterceptor> _logger;public CustomInterceptor(ILogger<CustomInterceptor> logger){_logger = logger;}public void Intercept(IInvocation invocation){string result = $"开始执行-->\n方法名: {invocation.Method.Name}\n";foreach (var item in invocation.Arguments){result += $"入参---{JsonConvert.SerializeObject(item)}\n";}_logger.LogInformation(result);invocation.Proceed();_logger.LogInformation($"结束执行-->\n方法名: {invocation.Method.Name}\n" +$"返回结果---{JsonConvert.SerializeObject(invocation.ReturnValue)}\n");}
}

五、AOP -- 拦截器 -- 封装

using Autofac;
using Autofac.Extensions.DependencyInjection;
using Autofac.Extras.DynamicProxy;namespace LOG.Test;public static class CustomAOPExt
{public static void AddAOPExt(this WebApplicationBuilder builder){builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())  // 工厂替换,把Autofac整合进来.ConfigureContainer<ContainerBuilder>(containerBuilder =>{// 依赖注入containerBuilder.RegisterType<CustomInterceptor>(); containerBuilder.RegisterType<Student>().As<IStudent>().EnableClassInterceptors(); // 开启类拦截器 //containerBuilder.RegisterType<Student>().As<IStudent>().EnableInterfaceInterceptors(); // 开启接口拦截器});}
}

六、案例编写

// 在Program.cs 中// 添加 lg4net 扩展
builder.AddLog4netExt();
// 添加 AOP 扩展
builder.AddAOPExt();

创建 Student 和 IStudent  测试类和接口

 创建 一个 控制器

七、结果展示

 


如有错误,烦请批评指正

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

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

相关文章

K8S系列文章之 开源的堡垒机 jumpserver

一、jumpserver作为一款开源的堡垒机&#xff0c;不管是企业还是个人&#xff0c;我觉得都是比较合适的&#xff0c;而且使用也比较简单。 二、这里记录一下安装和使用过程。 1、安装&#xff0c;直接docker不是就行 version: 3 services:xbd-mysql:image: mysql:8.0.19restart…

离散化的两种实现方式【sort或者map】

离散化 定义 把无限空间中有限的个体映射到有限的空间中去&#xff0c;以此提高算法的时空效率。通俗的说&#xff0c;离散化是在不改变数据相对大小的条件下&#xff0c;对数据进行相应的缩小。 适用范围&#xff1a;数组中元素值域很大&#xff0c;但个数不是很多。 比如将…

命令行快捷键Mac Iterm2

原文:Jump forwards, backwards and delete a word in iTerm2 on Mac OS iTerm2并不允许你使用 ⌥← 或 ⌥→ 来跳过单词。 你也不能使用 ⌥backspace 来删除整个单词。 下面是在Mac OS上如何配置iTerm2以便能做到这一点的方法。 退格键 首先&#xff0c;你需要将你的左侧 ⌥…

基于Python++PyQt5马尔科夫模型的智能AI即兴作曲—深度学习算法应用(含全部工程源码+测试数据)

目录 前言总体设计系统整体结构图系统流程图 运行环境Python 环境PC环境配置 模块实现1. 钢琴伴奏制作1&#xff09;和弦的实现2&#xff09;和弦级数转为当前调式音阶3&#xff09;根据预置节奏生成伴奏 2. 乐句生成1&#xff09;添加音符2&#xff09;旋律生成3&#xff09;节…

JVM GC ROOT分析

GC root原理:通过对枚举GCroot对象做引用可达性分析,即从GC root对象开始,向下搜索,形成的路径称之为 引用链。如果一个对象到GC roots对象没有任何引用,没有形成引用链,那么该对象等待GC回收,换而言之,如果减少内存泄漏,也就是切断引用链,常见的GCRoot对象如下: 1、…

配置Picgo图床之COS、OSS、Github图床

简介 PicGo是一款开源的图片上传和管理工具&#xff0c;它提供了简单易用的界面和丰富的功能&#xff0c;方便用户上传、管理和分享图片。 以下是PicGo的一些主要特点和功能&#xff1a; 图片上传&#xff1a;PicGo支持将本地图片快速上传到云存储服务&#xff0c;如七牛云、…

深度学习(34)—— StarGAN(1)

深度学习&#xff08;34&#xff09;—— StarGAN&#xff08;1&#xff09; 文章目录 深度学习&#xff08;34&#xff09;—— StarGAN&#xff08;1&#xff09;1. 背景2. 基本思路3. 整体流程4. StarGAN v2(1) 网络结构(2) mapping network(3) style encoder(4)Loss 和之前…

【bug】记录一次使用Swiper插件时loop属性和slidersPerView属性冲突问题

简言 最近在vue3使用swiper时&#xff0c;突然发现loop属性和slides-per-view属性同时存在启用时&#xff0c;loop生效&#xff0c;下一步只能生效一次的bug&#xff0c;上一步却是好的。非常滴奇怪。 解决过程 分析属性是否使用错误。 loop是循环模式&#xff0c;布尔型。 …

Django之JWT库与SimpleJWT库的使用

Django之JWT库与SimpleJWT库的使用 JWTJWT概述头部(header)载荷(payload)签名(signature) Django使用JWT说明jwt库的使用安装依赖库配置settings.py文件配置urls.py文件创建视图配置权限 SimpleJWT库的使用安装SimpleJWT库配置Django项目配置路由创建用户接口测试身份认证自定义…

c++--二叉树应用

1.根据二叉树创建字符串 力扣 给你二叉树的根节点 root &#xff0c;请你采用前序遍历的方式&#xff0c;将二叉树转化为一个由括号和整数组成的字符串&#xff0c;返回构造出的字符串。 空节点使用一对空括号对 "()" 表示&#xff0c;转化后需要省略所有不影响字符…

SpringBoot集成百度人脸识别实现登陆注册功能Demo(二)

前言 上一篇SpringBoot集成百度人脸demo中我使用的是调用本机摄像头完成人脸注册&#xff0c;本次demo根据业务需求的不同我采用文件上传的方式实现人脸注册。 效果演示 注册 后端响应数据&#xff1a; 登录 后端响应数据&#xff1a; 项目结构 后端代码实现 1、BaiduAiUtil…

SQL 表别名 和 列别名

列表名 列表名之后 order by 可以用别名 也可以用原名&#xff0c; where 中不能用别名的 SQL语句执行顺序&#xff1a; from–>where–>group by -->having — >select --> order 第一步&#xff1a;from语句&#xff0c;选择要操作的表。 第二步&#xff1…

Bug的严重等级和优先级别与分类

一、 Bug的严重等级定义&#xff1a; 1、 Blocker 即系统无法执行、崩溃或严重资源不足、应用模块无法启动或异常退出、无法测试、造成系统不稳定。 严重花屏内存泄漏 用户数据丢失或破坏系统崩溃/死机/冻结模块无法启动或异常退出严重的数值计算错误功能设计与需求严重不符其…

每日一学:什么是 Harbor ?

目录 什么是 Harbor &#xff1f; 一、Harbor 的优势 二、Harbor 架构构成 三、Core services 这是 Harbor 的核心功能 什么是 Harbor &#xff1f; Harbor 是 VMware 公司开源的企业级 Docker Registry 项目&#xff0c;其目标是帮助用户迅速搭建一个企业级的 Docker Reg…

Spring MVCSpring Boot

文章目录 Spring MVC什么是MVC模式Spring MVC优点SpringMVC 运行流程SpringMVC组件SpringMVC常用的注解有哪些SpringMVC的拦截器和过滤器有什么区别&#xff1f;执行顺序是什么 SpringBoot对SpringBoot的理解Spring和SpringBoot的关系&#xff1f;SpringBoot有哪些核心注解Spri…

【PDF密码】PDF文件不能打印,为什么?

正常的PDF文件是可以打印的&#xff0c;如果PDF文件打开之后发现文件不能打印&#xff0c;我们需要先查看一下自己的打印机是否能够正常运行&#xff0c;如果打印机是正常的&#xff0c;我们再查看一下&#xff0c;文件中的打印功能按钮是否是灰色的状态。 如果PDF中的大多数功…

react icon ant简单使用

refer&#xff1a; 文字提示 Tooltip - Ant Design 1.首先保证已经引入了Ant 2.在组件&#xff08;页面&#xff09;引入tooltip import { Form, Tooltip } from antd; 3.在合适的位置使用tooltip&#xff1a; <span>寿命 <Tooltip title"这是寿命的说明&quo…

前端 select 标签如何创建下拉菜单?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 代码示例⭐ 代码讲解⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏…

【Linux】计算机网络的背景和协议分层

文章目录 网络发展协议何为协议网络协议协议分层OSI七层模型TCP/IP五层模型&#xff08;四层&#xff09; 基本通信流程mac地址和ip地址网络通信本质 网络发展 从一开始计算机作为一台台单机使用&#xff0c;到现在网络飞速发展&#xff0c;从局域网Lan建立起局域网&#xff0…

Vue3 第四节 自定义hook函数以及组合式API

1.自定义hook函数 2.toRef和toRefs 3.shallowRef和shallowReactive 4.readonly和shallowReadonly 5.toRaw和markRaw 6.customref 一.自定义hook函数 ① 本质是一个函数&#xff0c;把setup函数中使用的Composition API 进行了封装,类似于vue2.x中的mixin 自定义hook函数…