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目錄下。)
再寫入資料庫之前,首先看一下,將要寫入的資料庫表的結構。
表名是test_log
再看看我們自訂的訊息類。
public class LogContent<br /> {<br /> public string Reason{get;set;}<br /> public string Name { get; set; }<br /> }
萬事具備,只欠東風了,下面就是設定檔了。
<?xml version="1.0" encoding="utf-8" ?><br /><configuration><br /> <configSections><br /> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/><br /> </configSections><br /> <log4net><br /> <root><br /> <level value="All" /><br /> <appender-ref ref="AdoNetAppender"/><br /> </root><br /> <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender"><br /> <bufferSize value="1" /><br /> <connectionType value="System.Data.SqlClient.SqlConnection,System.Data, Version=1.0.3300.0, Culture=neutral,PublicKeyToken=b77a5c561934e089" /><br /> <connectionString value="database=xxx;server=xxx;User ID=sa;Password=xxx" /><br /> <commandText value="INSERT INTO test_log(記錄時間,訊息等級,訊息內容,使用者名稱稱) VALUES (@LogTime,@level,@Reason,@User)" /></p><p> <parameter><br /> <parameterName value="@LogTime" /><br /> <dbType value="DateTime" /><br /> <layout type="log4net.Layout.RawTimeStampLayout" /><br /> </parameter></p><p> <parameter><br /> <parameterName value="@level" /><br /> <dbType value="String" /><br /> <size value="50" /><br /> <layout type="log4net.Layout.PatternLayout" value="%level" /><br /> </parameter></p><p> <parameter><br /> <parameterName value="@Reason" /><br /> <dbType value="String" /><br /> <size value="100" /><br /> <layout type="TestLogNiu.MyLayout, TestLogNiu" ><br /> <param name="ConversionPattern" value="%property{Reason}"/><br /> </layout><br /> </parameter></p><p> <parameter><br /> <parameterName value="@User" /><br /> <dbType value="String" /><br /> <size value="20" /><br /> <layout type="TestLogNiu.MyLayout, TestLogNiu" ><br /> <param name="ConversionPattern" value="%property{Name}"/><br /> </layout><br /> </parameter></p><p> </appender><br /> </log4net><br /> </configuration>
到了這裡,程式還不能運行,對了,還少一個東西,那就是自訂的MyLayout呀,下面給出代碼。
using System;<br />using System.Collections.Generic;<br />using System.Linq;<br />using System.Reflection;<br />using System.Text;<br />using log4net.Layout;<br />using log4net.Layout.Pattern;</p><p>namespace TestLogNiu<br />{<br /> public class MyLayout : PatternLayout<br /> {<br /> public MyLayout()<br /> {<br /> this.AddConverter("property", typeof(MyMessagePatternConverter));<br /> }<br /> }</p><p> public class MyMessagePatternConverter : PatternLayoutConverter<br /> {<br /> protected override void Convert(System.IO.TextWriter writer, log4net.Core.LoggingEvent loggingEvent)<br /> {<br /> if (Option != null)<br /> {<br /> // Write the value for the specified key<br /> WriteObject(writer, loggingEvent.Repository, LookupProperty(Option, loggingEvent));<br /> }<br /> else<br /> {<br /> // Write all the key value pairs<br /> WriteDictionary(writer, loggingEvent.Repository, loggingEvent.GetProperties());<br /> }<br /> }<br /> /// <summary><br /> /// 通過反射擷取傳入的日誌對象的某個屬性的值<br /> /// </summary><br /> /// <param name="property"></param><br /> /// <returns></returns><br /> private object LookupProperty(string property, log4net.Core.LoggingEvent loggingEvent)<br /> {<br /> object propertyValue = string.Empty;<br /> PropertyInfo propertyInfo = loggingEvent.MessageObject.GetType().GetProperty(property);<br /> if (propertyInfo != null)<br /> propertyValue = propertyInfo.GetValue(loggingEvent.MessageObject, null);<br /> return propertyValue;<br /> }<br /> }<br />}<br />
代碼的調用
class Program<br /> {<br /> static void Main(string[] args)<br /> {<br /> log4net.Config.XmlConfigurator.Configure();</p><p> log4net.ILog log = log4net.LogManager.GetLogger(typeof(Program));<br /> log.Info(new LogContent{Reason = "這是一個測試",Name = "張三"});<br /> Console.ReadKey();</p><p> }<br /> }
運行結果。
大功告成啦。