天天看点

log4net配置写入SQL Server数据库(sqlserver-sqlclient) 并传入自定义业务对象 

http://www.cnblogs.com/Arlen/archive/2008/11/22/1338908.html

       本贴在原来帖子的基础上有些修改,经过本人的实际运行调试运行,本贴中的代码都可以直接复制使用。

       在项目中需要记录业务日志(即用户进行了什么操作,操作什么内容,什么时候,操作内容以结构化的方式存储,以方便以后数据挖掘)。

      系统采用了log4net来将业务日志记录到数据库中,反正在log4net中加个Appender就可以。由于业务需要记录的并不是简单的系统时间%date,级别%level,信息%message等字段,而是自定义的业务字段。发现记录日志的info,error,debug等方法可以传入object参数:log.info(object message)。于是到网上查找它是不是象我们预想的这样,传一个自定义的业务日志对象给info方法,它自动帮我得到该业务对象的字段的值。找了半天,答案是:不行。

仔细想了下,难道别人都不这样用吗?别人是怎么传入自定义业务对象?

虽然看起来已经没有什么必要,但还是自己做出了解决方案。

下面把配置方式及传入自定义业务对象的解决方案附上。

一、log4net针对sqlserver的配置方式:

(注:如果配置写入数据库,需要将System.Data.dll拷到bin目录下。)

再写入数据库之前,首先看一下,将要写入的数据库表的结构。

log4net配置写入SQL Server数据库(sqlserver-sqlclient) 并传入自定义业务对象 

表名是test_log

再看看我们自定义的消息类。

view plain copy to clipboard print ?

  1. public class LogContent  
  2.     {  
  3.        public string Reason{get;set;}  
  4.        public string Name { get; set; }  
  5.     }  

万事具备,只欠东风了,下面就是配置文件了。

到了这里,程序还不能运行,对了,还少一个东西,那就是自定义的MyLayout呀,下面给出代码。

代码的调用

 运行结果。

log4net配置写入SQL Server数据库(sqlserver-sqlclient) 并传入自定义业务对象 

大功告成啦。

view plain copy to clipboard print ?

  1. class Program  
  2. {  
  3.     static void Main(string[] args)  
  4.     {  
  5.         log4net.Config.XmlConfigurator.Configure();  
  6.         log4net.ILog log = log4net.LogManager.GetLogger(typeof(Program));  
  7.         log.Info(new LogContent{Reason = "这是一个测试",Name = "张三"});  
  8.         Console.ReadKey();  
  9.     }  
  10. }  

view plain copy to clipboard print ?

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Reflection;  
  5. using System.Text;  
  6. using log4net.Layout;  
  7. using log4net.Layout.Pattern;  
  8. namespace TestLogNiu  
  9. {  
  10.     public class MyLayout : PatternLayout  
  11.     {  
  12.         public MyLayout()  
  13.         {  
  14.             this.AddConverter("property", typeof(MyMessagePatternConverter));  
  15.         }  
  16.     }  
  17.     public class MyMessagePatternConverter : PatternLayoutConverter  
  18.     {  
  19.         protected override void Convert(System.IO.TextWriter writer, log4net.Core.LoggingEvent loggingEvent)  
  20.         {  
  21.             if (Option != null)  
  22.             {  
  23.                 // Write the value for the specified key  
  24.                 WriteObject(writer, loggingEvent.Repository, LookupProperty(Option, loggingEvent));  
  25.             }  
  26.             else  
  27.             {  
  28.                 // Write all the key value pairs  
  29.                 WriteDictionary(writer, loggingEvent.Repository, loggingEvent.GetProperties());  
  30.             }  
  31.         }  
  32.         /// <summary>  
  33.         /// 通过反射获取传入的日志对象的某个属性的值  
  34.         /// </summary>  
  35.         /// <param name="property"></param>  
  36.         /// <returns></returns>  
  37.         private object LookupProperty(string property, log4net.Core.LoggingEvent loggingEvent)  
  38.         {  
  39.             object propertyValue = string.Empty;  
  40.             PropertyInfo propertyInfo = loggingEvent.MessageObject.GetType().GetProperty(property);  
  41.             if (propertyInfo != null)  
  42.                 propertyValue = propertyInfo.GetValue(loggingEvent.MessageObject, null);  
  43.             return propertyValue;  
  44.         }  
  45.     }  
  46. }  

view plain copy to clipboard print ?

  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <configuration>  
  3.   <configSections>  
  4.     <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>  
  5.   </configSections>  
  6.   <log4net>  
  7.     <root>  
  8.       <level value="All" />  
  9.       <appender-ref ref="AdoNetAppender"/>  
  10.     </root>  
  11.     <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">  
  12.       <bufferSize value="1" />  
  13.       <connectionType value="System.Data.SqlClient.SqlConnection,System.Data, Version=1.0.3300.0, Culture=neutral,PublicKeyToken=b77a5c561934e089" />  
  14.       <connectionString value="database=xxx;server=xxx;User ID=sa;Password=xxx" />  
  15.       <commandText value="INSERT INTO test_log(记录时间,消息等级,消息内容,用户名称) VALUES (@LogTime,@level,@Reason,@User)" />  
  16.       <parameter>  
  17.         <parameterName value="@LogTime" />  
  18.         <dbType value="DateTime" />  
  19.         <layout type="log4net.Layout.RawTimeStampLayout" />  
  20.       </parameter>  
  21.       <parameter>  
  22.         <parameterName value="@level" />  
  23.         <dbType value="String" />  
  24.         <size value="50" />  
  25.         <layout type="log4net.Layout.PatternLayout" value="%level" />  
  26.       </parameter>  
  27.       <parameter>  
  28.         <parameterName value="@Reason" />  
  29.         <dbType value="String" />  
  30.         <size value="100" />  
  31.         <layout type="TestLogNiu.MyLayout, TestLogNiu" >  
  32.           <param name="ConversionPattern" value="%property{Reason}"/>  
  33.         </layout>  
  34.       </parameter>  
  35.       <parameter>  
  36.         <parameterName value="@User" />  
  37.         <dbType value="String" />  
  38.         <size value="20" />  
  39.         <layout type="TestLogNiu.MyLayout, TestLogNiu" >  
  40.           <param name="ConversionPattern" value="%property{Name}"/>  
  41.         </layout>  
  42.       </parameter>  
  43.     </appender>  
  44.   </log4net>   
  45.     </configuration>