.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.mzph.cn/news/26777.shtml

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

相关文章

WPF上位机8——C#与MySQL

ADO.NET 数据库连接 数据插入、删除、更改 数据查询 带单个参数 带多个参数 using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Text; using System.Threading.Tasks;namespace Wp…

JVM、JRE、JDK三者之间的关系

JVM、JRE和JDK是与Java开发和运行相关的三个重要概念。 再了解三者之前让我们先来了解下java源文件的执行顺序&#xff1a; 使用编辑器或IDE(集成开发环境)编写Java源文件.即demo.java程序必须编译为字节码文件&#xff0c;javac(Java编译器)编译源文件为demo.class文件.类文…

nginx优化与防盗链

nginx优化&#xff1a; 1隐藏版本号&#xff1a; 方法一 修改配置文件方式 vim /usr/local/nginx/conf/nginx.conf http { include mime.types; default_type application/octet-stream; server_tokens off; vim /usr/local/nginx/conf/nginx.c…

Python入门自学进阶-Web框架——38、redis、rabbitmq、git

缓存数据库redis&#xff1a; NoSQL&#xff08;Not only SQL&#xff09;泛指非关系型的数据库。为了解决大规模数据集合多重数据类的挑战。 NoSQL数据库的四大分类&#xff1a; 键值&#xff08;Key-Value&#xff09;存储数据库列存储数据库文档型数据库图形&#xff08;…

【Linux 网络】网络层协议之IP协议

IP协议 IP协议所处的位置网络层要解决的问题IP协议格式分片与组装网段划分特殊的IP地址IP地址的数量限制私网IP地址和公网IP地址路由 IP协议所处的位置 IP指网际互连协议&#xff0c;Internet Protocol的缩写&#xff0c;是TCP/IP体系中的网络层协议。 网络层要解决的问题 网络…

Docker搭建zookeeper

问题背景 前言 本文参考自&#xff1a;docker-compose快速搭建Zookeeper集群还有一种更加详细更加全面的部署方式&#xff1a;Docker之docker-compose一键部署Zookeeper集群&#xff0c;但笔者还未验证&#xff0c;先记录下来 搭建 安装docker-ce 此处不赘述 安装docker-co…

javaweb监听和渲染技术

jsp入门使用 <% page import"java.io.PrintWriter" %> <%-- Created by IntelliJ IDEA.--%> <%-- User: 韩顺平--%> <%-- jsp的模板如何定制&#xff0c;一会再说明--%> <%-- To change this template use File | Settings | File T…

使用gpt对对话数据进行扩增,对话数据扩增,数据增强

我们知道一个问题可以使用很多方式问&#xff0c;但都可以使用完全一样的回答&#xff0c;基于这个思路&#xff0c;我们可以很快的扩增我们的数据集。思路就是使用chatgpt或者gpt4生成类似问题&#xff0c;如下&#xff1a; 然后我们可以工程化这个过程&#xff0c;从而快速扩…

【JAVA】数组

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;浅谈Java &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 数组 1. 数组的基本概念1.1 为什么要使用…

Spring Boot整合ES的两种方式

使用Spring Data Elasticsearch Starter 在Spring Boot中整合Elasticsearch的方式之一是使用Elasticsearch的官方Spring Data Elasticsearch Starter。该Starter提供了对Elasticsearch的高级集成&#xff0c;简化了配置和管理Elasticsearch客户端。 下面是使用Spring Data E…

网关 GateWay 的使用详解、路由、过滤器、跨域配置

一、网关的基本概念 SpringCloudGateway网关是所有微服务的统一入口。 1.1 它的主要作用是&#xff1a; 反向代理&#xff08;请求的转发&#xff09; 路由和负载均衡 身份认证和权限控制 对请求限流 1.2 相比于Zuul的优势&#xff1a; SpringCloudGateway基于Spring5中…

javascript:js介绍初体验和变量以及数据类型的使用。

目录 一.介绍 1概念 2作用 3组成 二.js初体验 1.js的书写位置 a.行间引入 b.内部引入 c.外部引入​编辑 2.js的注释 3.js的结束符 4.输入输出语句 输出语法 输入语法 三.变量及数据类型 ​ 1.字面量 2.变量 ​编辑 变量的使用 ​编辑 let和var的区别…

在 Linux 上以 All-in-One 模式安装 KubeSphere

官方文档&#xff1a;https://www.kubesphere.io/zh/docs/v3.3/quick-start/all-in-one-on-linux/ 操作系统 最低配置 Ubuntu&#xff1a; 16.04,18.04, 20.04, 22.04 2 核 CPU&#xff0c;4 GB 内存&#xff0c;40 GB 磁盘空间Debian Buste&#xff1a;Stretch 2 核 CPU&am…

【严重】Smartbi商业智能BI软件权限绕过漏洞

漏洞描述 Smartbi 是一款商业智能应用&#xff0c;提供了数据集成、分析、可视化等功能&#xff0c;帮助用户理解和使用他们的数据进行决策。 在 Smartbi 受影响版本中存在权限绕过问题&#xff0c;未授权的攻击者可以通过 RMI 的方式调用 getPassword 接口获取管理员 token …

jQuery知识

DOM知识 alert(我是弹窗); prompt(弹窗输入);Dom元素节点获取 方式一&#xff1a;通过 id 获取 一个 元素节点&#xff08;为什么是一个呢&#xff1f;因为 id 是唯一的&#xff09; var div1 document.getElementById("box1"); 方式二&#xff1a;通过 标签名 获…

conda 环境 numpy 安装报错需要 Microsoft Visual C++ 14.0

到公司装深度学校环境。项目较旧&#xff0c;安装依赖&#xff0c;一堆报错&#xff08;基于 conda 环境&#xff09;&#xff1a; numpy 安装报需要 C 14.0 No module named numpy.distutils._msvccompiler in numpy.distutils; trying from distutilserror: Microsoft Visu…

预测知识 | 预测模型变量重要性、可视化及论文撰写指南

预测知识 | 预测模型变量重要性、可视化及论文撰写指南 目录 预测知识 | 预测模型变量重要性、可视化及论文撰写指南变量重要性模型可视化论文撰写指南参考资料 变量重要性 关于预测模型变量重要性&#xff0c;大家一定熟悉不过。但如下图所示&#xff0c;其展示上可有进一步优…

网络安全进阶学习第十三课——SQL注入Bypass姿势

文章目录 一、等号被过滤二、substr、mid等被过滤三、逗号被过滤四、and/or被过滤五、空格被过滤五、其他绕过方式 一、等号被过滤 1、like&#xff0c;rlike语句&#xff0c;其中rlike是正则2、大于号>&#xff0c;小于号<3、符号<>&#xff1a;<>为不等于…

飞凌OKMX6ULL-C开发板试用

开箱体验 主要配件包括&#xff1a;USB Type-C调试线、电源线、主板。 资源下载 开发环境 飞凌提供了制作好的ubuntu18.04的镜像&#xff0c;直接到网盘下载解压即可&#xff0c;VMWare的安装可以参考网上教程&#xff0c;这里不赘述。安装好VMWare后直接打开解压出来的ubu…

高性能MySQL实战(一):表结构

大家好&#xff0c;我是 方圆。最近因需求改动新增了一些数据库表&#xff0c;但是在定义表结构时&#xff0c;具体列属性的选择有些不知其所以然&#xff0c;索引的添加也有遗漏和不规范的地方&#xff0c;所以我打算为创建一个高性能表的过程以实战的形式写一个专题&#xff…