前言
以bs项目中引入log4net为例。log4net存入数据库提供了基本的(时间、线程、等级、message)字段。 但是实际日志场景中可能需要统计IP、用户ID或者其他业务相关的信息记入日志。 需要重写log4net的部分方法来实现。本文展示使用log4net从0开始到记录自定义字段入库的过程。
关键代码在第三步
一. 数据库表
随便创建一个测试的表,有test1和test2两个字段,后续用log4net存入数据。
二. log4net基础配置
1.nuget搜索log4net并安装。
2.Global.asax全局配置
在Global.asax中添加 log4net.Config.XmlConfigurator.Configure();这句。如图。
三.创建自定义类
1.创建一个自己数据库里日志表的实体,方便传值、添加数据等。
我这里命名为BaseLog.cs, 字段为test1和test2 ,和数据库表对应
using System;
using System.ComponentModel;
namespace DataStatisticsApi.Log
{
/// <summary>
/// 日志基础类
/// </summary>
[Serializable]
public class BaseLog
{
public BaseLog()
{
}
///<summary>
///唯一标识符
///</summary>
[Description("测试1")]
public string test1
{
get; set;
}
///<summary>
///请求时间
///</summary>
[Description("测试2")]
public string test2
{
get; set;
}
}
}
2.增加数据库连接字符串属性
创建一个类,继承log4net的AdoNetAppender类。
using log4net.Appender;
using System.Configuration;
namespace DataStatisticsApi.Log
{
public class CustomAdoNetAppender : AdoNetAppender
{
/// <summary>
/// Á¬½Ó×Ö·û´®Ãû³Æ
/// </summary>
public new string ConnectionStringName
{
set
{
this.ConnectionString = ConfigurationManager.ConnectionStrings[value].ConnectionString;
}
}
}
}
3.增加一个自定义的日志类
创建一个类,作为一个自定义的日志。我这里叫DataLogAdoAppender, 同样继承自log4net的AdoNetAppender类。
在该类中写自己插入表的语句和参数,并在最后调用log4net的ActivateOptions方法初始化加载log4net配置。
using System;
using log4net.Appender;
using System.Data;
using log4net.Layout;
namespace DataStatisticsApi.Log
{
public class DataLogAdoAppender : CustomAdoNetAppender
{
public DataLogAdoAppender()
{
//System.Data.SqlClient
Type t = typeof(System.Data.SqlClient.SqlConnection);
string s = t.Assembly.FullName.ToString();
//数据连接类型
this.ConnectionType = $"System.Data.SqlClient.SqlConnection, {s}";
base.UseTransactions = false;
this.CommandType = CommandType.Text;
//sql语句
this.CommandText = @"INSERT INTO [dbo].[testLog]
([test1]
,[test2])
VALUES
(@test1
,@test2
)";
//填充参数
string parameterName = "test1";
this.AddParameter(new AdoNetAppenderParameter() { ParameterName = "@" + parameterName, DbType = DbType.String, Size = 50, Layout = new Layout2RawLayoutAdapter(new LogLayout("%" + parameterName)) });
parameterName = "test2";
this.AddParameter(new AdoNetAppenderParameter() { ParameterName = "@" + parameterName, DbType = DbType.String, Size = 200, Layout = new Layout2RawLayoutAdapter(new LogLayout("%" + parameterName)) });
base.ActivateOptions();
}
}
}
4.增加一个自定义的转换类
创建一个自定义转换类,把log4net对象转换成自定义日志类的字段属性。继承log4net的PatternLayout类,并重写ActivateOptions方法。
using System.IO;
using log4net.Core;
using log4net.Layout;
using log4net.Layout.Pattern;
namespace DataStatisticsApi.Log
{
public class LogLayout : PatternLayout
{
public LogLayout(string pattern)
: base(pattern)
{
}
public override void ActivateOptions()
{
this.AddConverter("test1", typeof(test1Converter));
this.AddConverter("test2", typeof(test2Converter));
base.ActivateOptions();
}
}
#region 转换
internal sealed class test1Converter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
BaseLog log = (BaseLog)loggingEvent.MessageObject;
if (log != null)
writer.Write(log.test1);
}
}
internal sealed class test2Converter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
BaseLog log = (BaseLog)loggingEvent.MessageObject;
if (log != null)
writer.Write(log.test2);
}
}
#endregion
}
四.log4net存库配置
在web.config中添加<log4net>节点
<log4net>
<!-- 业务日志-“数据库”记录器 -->
<appender name="DataLogAdoAppender" type="DataStatisticsApi.Log.DataLogAdoAppender">
<!-- 依赖的数据库链接名称 -->
<connectionStringName value="ConnectionString"/>
<!-- 缓存条数,到达value值时批量插入,1为每次都插入。实际环境根据日志量设置500或者更多-->
<bufferSize value="1"/>
</appender>
<root>
<level value="DEBUG" />
</root>
<!-- 自定义记录日志-->
<logger name="DataLogAdoAppenderLogger">
<!--信息级别仅限(FATAL)-->
<level value="INFO" />
<!--日志配置,ref对应appender配置-->
<appender-ref ref="DataLogAdoAppender" />
</logger>
</log4net>
在web.config中添加<connectionStrings>节点(数据库连接字符串)
<connectionStrings>
<add name="ConnectionString" connectionString="Data Source=1.1.1.3,1355; User ID=xxx; Password=xxx; Initial Catalog=dbName" providerName="System.Data.SqlClient" />
</connectionStrings>
五.Api测试
测试访问,日志数据成功入库
详细代码见github(后续上传)