.net8使用log4.net并自定义日志表的字段
目的:使用log4net把日志写到数据库并增加自定义字段。
main中的配置
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
//开启日志,默认配置文件在根目录 ,名称叫:log4net.config
builder.Logging.AddLog4Net();
//自定义字段中的信息,配合log4net.config使用,我是用于记录程序模块名称的
log4net.GlobalContext.Properties["AppName"] = "TestPro";
//自定义全局错误类
var mvcBuilder = builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add(typeof(ClubExceptionFilterAttribute));
});
var app = builder.Build();
app.Run();
}
}
定义日志字段、转换类与解析类
using log4net;
using log4net.Layout;
using log4net.Layout.Pattern;
using log4net.Core;
using Google.Protobuf.WellKnownTypes;
using System.Reflection;
namespace LogDemo.App_Log
{
/// <summary>
/// 自定义日志字段
/// </summary>
public class Log4Model
{
/// <summary>
/// 操作用户名称
/// </summary>
public string? UserID { get; set; }
/// <summary>
/// 日志类型,自定义名称即可
/// </summary>
public string? OType { get; set; }
/// <summary>
/// 日志信息
/// </summary>
public string? Message { get; set; }
/// <summary>
/// 业务事件编号
/// </summary>
public string? EId { get; set; }
/// <summary>
/// 程序模块名称
/// </summary>
public string? AppName { get; set; }
}
/*转换 */
public class CardBossLayoutConverter : log4net.Layout.Pattern.PatternLayoutConverter
{
protected override void Convert(System.IO.TextWriter writer, LoggingEvent loggingEvent)
{
Log4Model? actionInfo = loggingEvent.MessageObject as Log4Model;
if (actionInfo == null)
{
writer.Write("");
}
else
{
switch (this.Option)
{
case "UserId":
case "userid":
writer.Write(actionInfo.UserID);
break;
case "otype":
case "OType":
writer.Write(actionInfo.OType);
break;
case "message":
case "Message":
writer.Write(actionInfo.Message);
break;
default:
writer.Write("");
break;
}
}
//方法2
//if (!string.IsNullOrEmpty(this.Option))
//{
// object? obj = loggingEvent.MessageObject;
// if (obj != null)
// {
// PropertyInfo? info = obj.GetType().GetProperty(this.Option);
// if (info != null)
// {
// object? cusMsg = info.GetValue(obj, null); writer.Write(cusMsg);
// }
// }
//}
}
}
/*自定义解释器*/
public class CustomPatternLayout : PatternLayout
{
public CustomPatternLayout()
{
/*
xml中写property也可以,这种方法也可以写入值,log4net.GlobalContext.Properties["AppName"] = "测试类型3";
log4net.ThreadContext.Properties["AppName"] = "My Custom Thread-Specific Info";
*/
this.AddConverter("logModel", typeof(CardBossLayoutConverter));
}
}
}
log4net.config配置
<?xml version="1.0" encoding="utf-8"?>
<log4net>
<appender name="DebugAppender" type="log4net.Appender.DebugAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<!--指定日记记录方式,以滚动文件的方式(文件记录)-->
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<!--日志路径-->
<file value="log\" />
<!--是否是向文件中追加日志-->
<appendToFile value="true" />
<!--log保留天数-->
<param name= "MaxSizeRollBackups" value= "10"/>
<!--每个文件最大3M-->
<param name="maximumFileSize" value="10MB" />
<!--日志根据日期滚动-->
<param name="RollingStyle" value="Date" />
<!--日志文件名格式为:logs_20230431.log-->
<param name="DatePattern" value=""logs_"yyyyMMdd".log"" />
<!--日志文件名是否是固定不变的-->
<param name="StaticLogFileName" value="true" />
<!--布局-->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %5level %logger.%method [%line] - 信息: %message%newline %exception" />
</layout>
</appender>
<!--数据库写入日志配置-->
<appender name="ToMySql" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<param name="ConnectionType" value="MySql.Data.MySqlClient.MySqlConnection,MySql.Data"/>
<param name="ConnectionString" value="server=localhost;database=数据库;Uid=root;Pwd=密码;port=3306;"/>
<commandText value="INSERT INTO 日志表名 (`date`,`thread`,`lev`,`logger`,`msg`,`exception`,`userid`,`otype`,`appname`,`eid`) VALUES (@log_date,@log_thread,@log_level,@log_logger,@log_message,@log_exception,@log_userid,@log_otype,@log_appname,@log_eid)" />
<parameter>
<parameterName value="@log_date"/>
<dbType value="DateTime"/>
<layout type="log4net.Layout.RawTimeStampLayout">
<conversionPattern value="%date"/>
</layout>
</parameter>
<parameter>
<parameterName value="@log_thread"/>
<dbType value="String"/>
<size value="255"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread"/>
</layout>
</parameter>
<parameter>
<parameterName value="@log_level"/>
<dbType value="String"/>
<size value="50"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level"/>
</layout>
</parameter>
<parameter>
<parameterName value="@log_logger"/>
<dbType value="String"/>
<size value="50"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger"/>
</layout>
</parameter>
<parameter>
<parameterName value="@log_message"/>
<dbType value="String"/>
<size value="4000"/>
<!--
由log4信息字段
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message"/>
</layout>-->
<!--自定义日志信息字段-->
<layout type="LogDemo.App_Log.CustomPatternLayout">
<conversionPattern value="%logModel{Message}"/>
</layout>
</parameter>
<!--用户抛出异常信息-->
<parameter>
<parameterName value="@log_exception" />
<dbType value="String" />
<layout type="log4net.Layout.ExceptionLayout">
<conversionPattern value="%exception"/>
</layout>
</parameter>
<parameter>
<parameterName value="@log_userid" />
<dbType value="String"/>
<layout type="LogDemo.App_Log.CustomPatternLayout">
<conversionPattern value="%logModel{UserId}"/>
</layout>
</parameter>
<parameter>
<parameterName value="@log_otype" />
<dbType value="String"/>
<layout type="LogDemo.App_Log.CustomPatternLayout">
<!--<conversionPattern value="%logModel{OType}"/>-->
<conversionPattern value="%logModel{OType}"/>
</layout>
</parameter>
<parameter>
<parameterName value="@log_appname" />
<dbType value="String"/>
<layout type="LogDemo.App_Log.CustomPatternLayout">
<!--<conversionPattern value="%logModel{OType}"/>-->
<conversionPattern value="%property{AppName}"/>
</layout>
</parameter>
<parameter>
<parameterName value="@log_eid" />
<dbType value="String"/>
<layout type="LogDemo.App_Log.CustomPatternLayout">
<conversionPattern value="%logModel{EId}"/>
</layout>
</parameter>
</appender>
<root>
<!-- levels: OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL -->
<level value="ALL"/>
<!--<appender-ref ref="DebugAppender" />
<appender-ref ref="RollingFile" />-->
<appender-ref ref="ToMySql" />
</root>
</log4net>
使用方法
private static readonly ILog _logger = LogManager.GetLogger(typeof(HomeController));
var model = new Log4Model() { Message = "调试信息", OType = "调试类型", UserID = "用户信息" };
_logger.Debug(model);
效果如下: