log4net自定义字段写入SqlServer数据库 ASP.net
首先申明,本示例经过本作者亲自试验通过,可以运行
第一步 编写log4net配置文件 此处为Log.xml,该文件放在与Web.config平级的位置
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/> </configSections> <!--日志模块配置--> <log4net> <root> <!--Highest: OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL :Lowest --> <level value="ALL"></level> </root> <logger name="InfoLogger"> <level value="INFO"/> <appender-ref ref="ADONetAppender" /> </logger> <!--访问日志记录形式--> <appender name="ADONetAppender" type="log4net.Appender.AdoNetAppender"> <param name="bufferSize" value="1" /> <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <connectionString value="server=....;database=.....;user id =sa;password=...."/> <param name="commandText" value="INSERT INTO T_ACCESS_LOG ([PUBLIC_KEY],[INTERFACE],[IP]) VALUES (@PUBLIC_KEY,@INTERFACE,@IP)" />
<!--用存储过程的话是下面这种写法-->
<!--<param name="CommandType" value="StoredProcedure" />
<param name="commandText" value="SP_T_ACCESS_LOG" />--> <parameter> <parameterName value="@PUBLIC_KEY" /> <dbType value="String" /> <size value="100" />
<!--这里的Utilities是程序里的命名空间--> <layout type="Utilities.CustomLayout,Utilities"> <conversionPattern value="%property{PublicKey}" /> </layout> </parameter> <parameter> <parameterName value="@INTERFACE" /> <dbType value="String" /> <size value="200" /> <layout type="Utilities.CustomLayout,Utilities"> <conversionPattern value="%property{Interface}" /> </layout> </parameter> <parameter> <parameterName value="@IP" /> <dbType value="String" /> <size value="50" /> <layout type="Utilities.CustomLayout,Utilities"> <conversionPattern value="%property{IP}" /> </layout> </parameter> </appender> </log4net> </configuration>
第二步 加载log4net配置文件,即这个Log.xml,一共有两个位置需要改动
第一个位置 Web应用程序下的AssemblyInfo.cs,加上一句代码
[assembly: log4net.Config.DOMConfigurator(ConfigFile = "Log.xml", Watch = true)]
第二个位置 Global.asax
//在应用程序启动时运行的代码 log4net.Config.XmlConfigurator.Configure();
第三步 编写想要插入到数据库的实体类LogMessage.cs,本示例实体类中的所有字段均为自定义字段
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Utilities { public class LogMessage { public LogMessage() { } public LogMessage(string publicKey,string interFace, string Ip) { this._publickey = publicKey; this._interface = interFace; this._ip = Ip; } private string _publickey; public string PublicKey { get { return _publickey; } set { _publickey = value; } } private string _interface; public string Interface { get { return _interface; } set { _interface = value; } } private string _ip; public string IP { get { return _ip; } set { _ip = value; } } } }
第四步 编写最关键也是最核心的两个类CustomPatternConverter.cs,CustomLayout.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using log4net.Layout.Pattern; using System.Reflection; namespace Utilities { public class CustomPatternConverter:PatternLayoutConverter { protected override void Convert(System.IO.TextWriter writer, log4net.Core.LoggingEvent loggingEvent) { if (Option != null) { WriteObject(writer, loggingEvent.Repository, GetPropertyValue(Option, loggingEvent)); } else { // Write all the key value pairs WriteDictionary(writer, loggingEvent.Repository, loggingEvent.GetProperties()); } } /// <summary> /// 通过反射获取传入的日志对象的某个属性的值 /// </summary> /// <param name="property"></param> /// <returns></returns> private object GetPropertyValue(string property, log4net.Core.LoggingEvent loggingEvent) { object propertyValue = string.Empty; PropertyInfo propertyInfo = loggingEvent.MessageObject.GetType().GetProperty(property); if (propertyInfo != null) { propertyValue = propertyInfo.GetValue(loggingEvent.MessageObject, null); } return propertyValue; } } }
using System; using System.Collections; using System.Linq; using System.Text; using System.Threading.Tasks; using log4net.Layout; using log4net.Layout.Pattern; using log4net.Util; using log4net.Core; namespace Utilities { public class CustomLayout : PatternLayout { public CustomLayout() { this.AddConverter("property", typeof(CustomPatternConverter)); } } }
第五步 调用log4net,此处我分为了一个工具类和实际调用的例子
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Diagnostics; using log4net; namespace Utilities { public static class LogHelper { private static ILog InfoLogger = log4net.LogManager.GetLogger("InfoLogger"); public static void WriteInfo(LogMessage log) { if (InfoLogger.IsInfoEnabled) { InfoLogger.Info(log); } } } }
LogMessage mylog = new LogMessage(); mylog.PublicKey = "admin"; mylog.Interface = "DY/QueryNewsList"; mylog.IP = “127.0.0.1”; LogHelper.WriteInfo(mylog);
至此,整个流程就走通了,当然,很多时候,照着别人的示例来也经常会出现这样或那样的问题,这可怎么办呢?没关系,这个log4net是可以调试的,没错,它可以输出调试信息
启动log4net的内部调试,具体作法如下:
在Web.config中加入下列节点
<appSettings> <add key="log4net.Internal.Debug" value="true"/> </appSettings> <system.diagnostics> <trace autoflush="true"> <listeners> <add name="textWriterTraceListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="D:\log\log4net.txt" /> </listeners> </trace> </system.diagnostics>
然后,每跑完一次,你就可以去D:\log\log4net.txt文件里查看调试信息,分析下那些Error打头的条目,你就知道你错在哪儿了
最后转载的同学们,记得标明一下出处~