.Net6 Core Web API 配置 log4net + MySQL

目录

[一、导入NuGet 包](#一、导入NuGet 包)

[二、添加配置文件 log4net.config](#二、添加配置文件 log4net.config)

三、创建MySQL表格

四、Program全局配置

五、帮助类编写

六、效果展示


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

一、导入NuGet 包

---- log4net 基础包

---- Microsoft.Extensions.Logging.Log4Net.AspNetCore 扩展包

---- MySql.Data 数据库包

二、添加配置文件 log4net.config

需改数据库的字符串

XML 复制代码
<?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表格

sql 复制代码
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全局配置

cs 复制代码
// 全局配置 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));
});

五、帮助类编写

cs 复制代码
/// <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);
}
cs 复制代码
/// <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; }
}

六、效果展示

cs 复制代码
/// <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

如有错误,烦请批评指正

相关推荐
Sunyanhui12 小时前
牛客网 SQL36查找后排序
数据库·sql·mysql
fkdw3 小时前
C# Newtonsoft.Json 反序列化派生类数据丢失问题
c#·json
老王笔记3 小时前
MHA binlog server
数据库·mysql
2401_871213304 小时前
mysql高阶语句
数据库·mysql
浅尝辄止;5 小时前
C# 异步编程
c#
liyongqiangcc6 小时前
了解 ASP.NET Core 中的中间件
.net
山山而川粤6 小时前
网络安全宣传系统|Java|SSM|JSP|
java·开发语言·后端·学习·mysql
_汤姆大叔7 小时前
MySQL 高级操作全解析
数据库·mysql
呼啦啦啦啦啦啦啦啦8 小时前
【MySQL篇】聚合查询,联合查询
数据库·mysql