.Net6 Core Web API 配置 log4net + MySQL

目录

一、导入NuGet 包

二、添加配置文件  log4net.config 

三、创建MySQL表格

四、Program全局配置

五、帮助类编写

六、效果展示


小编没有使用依赖注入的方式。

一、导入NuGet 包

        ----  log4net        基础包   
        ----  Microsoft.Extensions.Logging.Log4Net.AspNetCore          扩展包
        ----  MySql.Data        数据库包

二、添加配置文件  log4net.config 

需改数据库的字符串

<?xml version="1.0" encoding="utf-8"?>
<configuration>
	<configSections>
		<!-- 读取<log4not>节点 -->
		<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
	</configSections>

	<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">
			<!--定义文件存放位置-->
			<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    行号:%L
			日志描述:创建连接失败。-->
			<conversionPattern value="记录时间:%date    线程ID:[%thread]    日志级别:%-5level %n
							当前类:%logger		行号:%L  %n
							日志描述:%message%newline %n"/>
			</layout>
		</appender>

		<!--错误日志:::记录错误日志-->
		<!--按日期分割日志文件 一天一个-->
		<!-- appender 定义日志输出方式   将日志以回滚文件的形式写到文件中。-->
		<appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender">
			<!--定义文件存放位置-->
			<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">
			<!--定义文件存放位置-->
			<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">
				<!--每条日志末尾的文字说明-->
				<!--输出格式 模板-->
				<!-- <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【日志级别】%-2level
                                  %n【记录时间】%date
                                  %n【执行时间】[%r]毫秒
                                  %n【debug位置】%logger 属性[%property{NDC}]
                                  %n【debug描述】%message"/>
			</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>

</configuration>

三、创建MySQL表格

CREATE TABLE `log4net` (
`log_datetime` datetime DEFAULT NULL,
`log_thread` varchar(255) DEFAULT NULL,
`log_level` varchar(255) DEFAULT NULL,
`log_logger` varchar(255) DEFAULT NULL,
`log_message` varchar(4000) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

四、Program全局配置

// 全局配置 log4net
ILoggerRepository repository = LogManager.CreateRepository("LogRepository");
// 读取配置文件
XmlConfigurator.Configure(repository, new FileInfo("Log4/log4net.config"));
// log错误日志配置
builder.Services.AddControllers(options =>
{
    options.SuppressAsyncSuffixInActionNames = false;
    options.Filters.Add(typeof(GlobalExceptionsFilter));
});

五、帮助类编写

/// <summary>
/// 日志帮助实现类
/// </summary>
public class LoggerHelper<TClass>
{
    private static readonly ILog Log = LogManager.GetLogger("LogRepository", typeof(TClass));

    
    public static void Debug(string msg) => Log.Debug(msg);
    
    public static void Info(string msg) => Log.Info(msg);
    
    public static void Warn(string msg) => Log.Warn(msg);
    
    public static void Error(string msg) => Log.Error(msg);
    
    public static void Fatal(string msg) => Log.Fatal(msg);
}
/// <summary>
/// 全局异常错误日志
/// // log错误日志配置
/// builder.Services.AddControllers(options =>
/// {
///     options.SuppressAsyncSuffixInActionNames = false;
///     options.Filters.Add(typeof(GlobalExceptionsFilter));
/// });
/// </summary>
public class GlobalExceptionsFilter : IExceptionFilter
{
    private readonly IWebHostEnvironment _env;
 
    public GlobalExceptionsFilter(IWebHostEnvironment env)
    {
        _env = env;
    }
    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 进行错误日志记录
        LoggerHelper<Exception>.Error(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; }
}

六、效果展示

/// <summary>
/// 测试代码
/// </summary>
[HttpGet]
public string Index()
{
    LoggerHelper<FirstController>.Info("WWWWWWW");
    LoggerHelper<Student>.Info("PPPP");
    throw new Exception("RRRRRRRR");
    return "OK";
}


\bin\Debug\net6.0\Log

如有错误,烦请批评指正

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C#学习笔记】值类型(1)

虽然拥有编程基础的人可以很快地上手C#&#xff0c;但是依然需要学习C#的特性和基础。本系列是本人学习C#的笔记&#xff0c;完全按照微软官方文档编写&#xff0c;但是不适合没有编程基础的人。 文章目录 .NET 体系结构Hello&#xff0c;World类型和变量&#xff08;重要&…

Flink之JDBC Sink

这里介绍一下Flink Sink中jdbc sink的使用方法,以mysql为例,这里代码分为两种,事务和非事务 非事务代码 import org.apache.flink.connector.jdbc.JdbcConnectionOptions; import org.apache.flink.connector.jdbc.JdbcExecutionOptions; import org.apache.flink.connector.…

opencv 31-图像平滑处理-方框滤波cv2.boxFilter()

方框滤波&#xff08;Box Filtering&#xff09;是一种简单的图像平滑处理方法&#xff0c;它主要用于去除图像中的噪声和减少细节&#xff0c;同时保持图像的整体亮度分布。 方框滤波的原理很简单&#xff1a;对于图像中的每个像素&#xff0c;将其周围的一个固定大小的邻域内…

vue3和typescript_组件

1 components下新建myComponent.vue 2 页面中引入组件&#xff0c;传入值&#xff0c;并且绑定事件函数。 3

【Valgrind】如何使用Valgrind监控内存

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

计算机视觉与图形学-神经渲染专题-ConsistentNeRF

摘要 Neural Radiance Fields (NeRF) 已通过密集视图图像展示了卓越的 3D 重建能力。然而&#xff0c;在稀疏视图设置下&#xff0c;其性能显着恶化。我们观察到&#xff0c;在这种情况下&#xff0c;学习不同视图之间像素的 3D 一致性对于提高重建质量至关重要。在本文中&…

【LeetCode每日一题】——766.托普利茨矩阵

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【题目进阶】八【解题思路】九【时间频度】十【代码实现】十一【提交结果】 一【题目类别】 矩阵 二【题目难度】 简单 三【题目编号】 766.托普利茨矩阵 四【题目描述…

【测试开发】Mq消息重复如何测试?

本篇文章主要讲述重复消费的原因&#xff0c;以及如何去测试这个场景&#xff0c;最后也会告诉大家&#xff0c;目前互联网项目关于如何避免重复消费的解决方案。 Mq为什么会有重复消费的问题? Mq 常见的缺点之一就是消息重复消费问题&#xff0c;产生这种问题的原因是什么呢…

16、外部配置源与外部配置文件及JSON配置

外部配置源与外部配置文件及JSON配置 application.properties application.yml 这些是配置文件&#xff0c; 命令行配置、环境变量配置、系统属性配置源&#xff0c;这些属于配置源。 外部配置源的作用&#xff1a; Spring Boot相当于对Spring框架进行了封装&#xff0c;Spri…

webrtc的回声消除延迟时间估算

叫回声消除的延迟时间估算不太合理&#xff0c;这里核心就是估算调用webrtc的条件边界&#xff0c;都知道webrtc回声消除的生效的前提就是一定要拿到远端声音的信息&#xff0c;然后拿近端声音和远端声音对齐&#xff0c;从近端声音中&#xff0c;结合远端声音模拟出远端声音在…

Windows用户如何安装新版本cpolar内网穿透超详细教程

Windows用户如何安装新版本cpolar内网穿透 文章目录 Windows用户如何安装新版本cpolar内网穿透 在科学技术高度发达的今天&#xff0c;我们身边充斥着各种电子产品&#xff0c;这些电子产品不仅为我们的工作带来极大的便利&#xff0c;也让生活变得丰富多彩。我们可以使用便携的…

[Python] Pylance 插件打开 Python 的类型检查

安装 Python 插件 2.打开一个 Python 文件 可以看到右下角有一个花括号和 Python 字样&#xff0c;点击花括号&#xff08;不是 Python 字样&#xff09;打开类型检查即可&#xff1a;

酷开系统 | 酷开科技,让数据变得更有价值!

身处信息时代&#xff0c;我们每个人时刻都在生成、传递和应用数据&#xff0c;数据已经成为了现代社会中宝贵的资源之一&#xff0c;而在人工智能领域&#xff0c;数据更是被称为人工智能的“燃料”。 而在AI的发展中&#xff0c;只有拥有高质量、多样性且充分代表性的数据集…

java 定时任务不按照规定时间执行

这里写目录标题 使用异步启动可能出现的问题排查代码中添加的定时任务步骤是否正确排查是否任务阻塞&#xff0c;如果定时任务出现异常阻塞后&#xff0c;将不会在次执行java中多个Scheduled定时器不执行为了让Scheduled效率更高&#xff0c;我们可以通过两种方法将定时任务变成…

vxworks文件系统分析

参考https://www.freebuf.com/articles/endpoint/335030.html 测试固件 https://service.tp-link.com.cn/detail_download_7989.html 固件提取 binwalk解压固件&#xff0c;在第一部分即为要分析的二进制文件&#xff0c;可以拖进ida分析 设置为arm小端字节序&#xff0c;点…

【HarmonyOS】性能优化之低代码开发加载多张轮播图

【关键字】 HarmonyOS、低代码开发、Swiper组件、性能优化、分页加载 写在前面 目前使用DevEco Studio的低代码工具开发元服务时&#xff0c;通过实际测试发现&#xff0c;Swiper组件加载多张轮播图时加载显示耗时较长&#xff08;实际测试网络状态一般的情况下显示耗时达到8…

ER系列路由器多网段划分设置指南

ER系列路由器多网段划分设置指南 - TP-LINK 服务支持 TP-LINK ER系列路由器支持划分多网段&#xff0c;可以针对不同的LAN接口划分网段&#xff0c;即每一个或多个LAN接口对应一个网段&#xff1b;也可以通过一个LAN接口与支持划分802.1Q VLAN的交换机进行对接&#xff0c;实现…

Stable Diffusion:网页版 体验 / AI 绘图

一、官网地址 Stable Diffusion Online 二、Stable Diffusion AI 能做什么 Stable Diffusion AI绘图是一种基于Stable Diffusion模型的生成式AI技术&#xff0c;能够生成各种类型的图像&#xff0c;包括数字艺术、照片增强和图像修复等。以下是一些可能的应用&#xff1a; …

怎么设置文件夹密码?文件夹密码设置方法合集

为文件夹设置密码可以有效地保护文件夹的数据安全&#xff0c;那么该怎么设置文件夹密码呢&#xff1f;下面我们来一起了解一下。 文件夹保护3000 想要简单快捷的为文件夹设置密码&#xff0c;那么&#xff0c;文件夹保护3000就是最佳的选择。它提供了3种文件夹保护方式&#…

IDEA项目实践——创建Java项目以及创建Maven项目案例、使用数据库连接池创建项目简介

系列文章目录 IDEA上面书写wordcount的Scala文件具体操作 IDEA创建项目的操作步骤以及在虚拟机里面创建Scala的项目简单介绍 目录 系列文章目录 前言 一 准备工作 1.1 安装Maven 1.1.1 Maven安装配置步骤 1.1.2 解压相关的软件包 1.1.3 Maven 配置环境变量 1.1.4 配…