天天看點

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>