.Net6 Core Web API 配置 log4net + MySQL

news2025/1/17 9:00:14

目录

一、导入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

如有错误,烦请批评指正

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

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

相关文章

go逆向符号恢复

前言 之前一直没怎么重视&#xff0c;结果发现每次遇到go的题都是一筹莫展&#xff0c;刷几道题练习一下吧 准备 go语言写的程序一般都被strip去掉符号了&#xff0c;而且ida没有相关的签名文件&#xff0c;没办法完成函数名的识别与字符串的定位&#xff0c;所以第一步通常…

HCIP——BGP反射器及联邦

BGP反射器及联邦 一、路由反射器1、路由反射器的角色2、路由反射规则3、路由反射器下的防环Originator_IDCluster_List应用举例配置方法 二、联邦1、联邦概念2、联邦的配置 路由反射器和联邦是两种专门针对IBGP水平分割设计的解决方案&#xff0c;我们依次来看下这两种技术 一…

基于 Llama2 和 OpenVINO™ 打造聊天机器人

点击蓝字 关注我们,让开发变得更有趣 作者 | 英特尔 AI 软件工程师 杨亦诚 指导 | 英特尔 OpenVINO 布道师 武卓博士 排版 | 李擎 基于 Llama2 和 OpenVINO™ 打造聊天机器人 Llama 2是 Meta 发布了其最新的大型语言模型&#xff0c;Llama2 是基于 Transformer 的人工神经网络&…

SpringCloudAlibaba之Nacos服务的发现与注册中心(一)

一&#xff1a;搭建nacos服务 在windows上搭建&#xff1a; 下载nacos &#xff0c;我在本地下载的是2.1.0 Releases alibaba/nacos (github.com)https://github.com/alibaba/Nacos/releases SpringCloudAlibaba &#xff0c;SpringCoud及Spring Boot之间版本的对应关系在以…

大麦订单生成器 大麦一键生成订单截图

后台一键生成链接&#xff0c;独立后台管理 教程&#xff1a;修改数据库config/Conn 不会可以看源码里有教程 下载程序&#xff1a;https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3

ACID特性、CAP理论、BASE原则详解

一、ACID 事务&#xff08;transaction&#xff09;&#xff1a;用户定义的一系列执行SQL的操作&#xff0c;这些操作要么完全执行&#xff0c;要么都不执行。 关系型数据库中的事务具有ACID特性 原子性(Atomicity)一致性&#xff08;Consistency&#xff09;隔离性&#xf…

红外NEC通信协议

一、NEC简介 红外(Infrared&#xff0c;IR)遥控是一种无线、非接触控制技术&#xff0c;常用于遥控器、无线键盘、鼠标等设备之间的通信。IR协议的工作原理是&#xff0c;发送方通过红外线发送一个特定的编码&#xff0c;接收方通过识别该编码来执行相应的操作。 IR协议是指红外…

JDK, JRE和JVM之间的区别和联系

JDK, JRE和JVM是与Java编程语言相关的三个重要的概念&#xff0c;它们分别代表Java Development Kit&#xff08;Java开发工具包&#xff09;、Java Runtime Environment&#xff08;Java运行时环境&#xff09;和Java虚拟机&#xff08;Java Virtual Machine&#xff09;。它们…

PHP8的运算符-PHP8知识详解

运算符是可以通过给出的一或多个值&#xff08;用编程行话来说&#xff0c;表达式&#xff09;来产生另一个值&#xff08;因而整个结构成为一个表达式&#xff09;的东西。 PHP8的运算符有很多&#xff0c;按类型分有一元运算符、二元运算符、三元运算符。 一元运算符只对一…

Java类与对象详解(2)

this引用 为什么要有this引用 先来看一个日期类的例子&#xff1a; ​ public class Date {public int year;public int month;public int day;//设置日期方法public void setDay(int y, int m, int d){//这里隐藏了一个Date this参数year y;month m;day d;}public void …

广州银行信用卡中心:强化数字引擎安全,实现业务稳步增长

广州银行信用卡中心是全国城商行中仅有的两家信用卡专营机构之一&#xff0c;拥有从金融产品研发至销售及后期风险控制、客户服务完整业务链条&#xff0c;曾获“2016年度最佳创新信用卡银行”。 数字引擎驱动业务增长 安全左移降低开发风险 近年来&#xff0c;广州银行信用卡…

fetch的使用和实现跨域及与axios的区别

一、作用 和axios作用类似&#xff0c;用于请求接口。它是XMLHttpRequest的一种替代方案。 二、安装 因为fetch有兼容性问题&#xff0c;所以我们安装升级版 whatwg-fetch cnpm i whatwg-fetch -S 三、使用 四、fetch和axios的区别 1&#xff0c;fetch返回的是一个未处理…

华为OD机试真题 Java 实现【TLV格式】【2023 B卷 200分】,附详细解题思路

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…

聚焦 TimescaleDB VS TDengine 性能对比报告,IoT 场景下全面分析写入与查询

基于第三方基准性能测试平台 TSBS&#xff08;Time Series Benchmark Suite&#xff09; 标准数据集&#xff0c;TDengine 团队在 TSBS 的 IoT 场景中&#xff0c;预设了五种规模的卡车车队基础数据集&#xff0c;在相同的 AWS 云环境下对时序数据库&#xff08;Time Series Da…

【NLP概念源和流】 01-稀疏文档表示(第 1/20 部分)

一、介绍 自然语言处理(NLP)是计算方法的应用,不仅可以从文本中提取信息,还可以在其上对不同的应用程序进行建模。所有基于语言的文本都有系统的结构或规则,通常被称为形态学,例如“跳跃”的过去时总是“跳跃”。对于人类来说,这种形态学的理解是显而易见的。 在这篇介…

【FAQ】在Linux中使用curl访问EasyCVR,返回报错Unauthorized的原因排查

EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防视频监控的能力&#xff0c;比如&#xff1a;视…

【C++刷题】经典简单题第一辑

数字在升序数组中出现的次数 class Solution { public:int GetNumberOfK(vector<int>& nums, int k){size_t left 0;size_t right nums.size();size_t mid1 -1;/** 用二分法的思想寻找 k 的边界*/// 寻找 k 的左边界下标while(left < right){mid1 left (ri…

yolov3-spp 训练结果分析:网络结果可解释性、漏检误检分析

1. valid漏检误检分析 ①为了探查第二层反向找出来的目标特征在最后一层detector上的意义&#xff01;——为什么最后依然可以框出来目标&#xff0c;且mAP还不错的&#xff1f; ②如何进一步提升和改进这个数据的效果&#xff1f;可以有哪些优化数据和改进的地方&#xff1f;让…

5分钟学会你创建搜狗百科

搜狗百科属于微信生态里的平台&#xff0c;搜狗百科不仅在搜狗搜索中展示&#xff0c;且可以在微信搜索中展示。那么搜狗百科该怎么创建呢&#xff1f;下面小马识途营销顾问分享下搜狗百科词条创建的流程。 1、要创建搜狗百科词条&#xff0c;首先需要在搜狗百科官网上注册一个…

【前端入门之旅】HTML中元素和标签有什么区别?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 标签&#xff08;Tag&#xff09;⭐元素&#xff08;Element&#xff09;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&a…