程序的记事本--log4net
這里面最重要的就是日志,那么你也就會非常好奇,這些日志是怎樣記錄的呢。偷偷的告訴你通常使用的是日志管理框架。
那么是不是也想在開發(fā)程序時開發(fā)出一個日志管理的模塊呢。不用著急以下就來介紹下怎樣做日志管理。
? ? ? ? 就我所知如今日志管理框架有多種如 Enterprise、NLog、CLog、Log4net,當(dāng)中Log4net功能強(qiáng)大適用于中大型的項目日志管理。NLog盡管功能較少可是它使用簡單。并且支持智能感應(yīng),另外Enterprise更是強(qiáng)大的沒的說,針對于大型系統(tǒng)開發(fā),當(dāng)然使用也比較困難。可是考慮到它們的使用資源及功能的強(qiáng)大,最后我們的項目確定了使用Log4net,所以接下來將會主要討論Log4net的主要用法。
一、Log4net組成及配置
? ? ? ? 從Log4net的API文檔中不難看出,事實上Log4net的開發(fā)過程還是蠻簡單的,并沒有想象中的那么復(fù)雜,并且在使用時僅僅須要加入對應(yīng)的配置節(jié)信息然后調(diào)用存儲方法就可以實現(xiàn)日志的存儲。詳細(xì)的結(jié)構(gòu)例如以下圖
? 1.1 組成具體解釋
? ? ? ? 上圖顯示了Log4net的主要由五個部分組成,分別為Logger。Appenders, Filters, Layouts 和Object Renders,當(dāng)中最基本的Appender命名空間中封裝了日志的存儲方式。也就是說通過配置Appender可以將日志輸出到運(yùn)行的類型中;Layout事實上是封裝了數(shù)據(jù)顯示的格式。通過配置Layout可以輸出指定模板的數(shù)據(jù)信息,它還可以控制數(shù)據(jù)的輸出類型(輸出xml還是文本類型);Object Renders非常重要。它可以控制數(shù)據(jù)的自己定義輸出,log4net將會依照用戶定義的標(biāo)準(zhǔn)輸出日志。
? 1.2 配置方法
? ? ? ? 在使用log4net時首先須要配置日志存儲方式,然后在代碼中調(diào)用LogManager類的靜態(tài)方法GetLog保存對象的對象的信息。當(dāng)中配置信息能夠?qū)懙絚onfig文件內(nèi)。也能夠自己定義一個xml文檔。把詳細(xì)的配置節(jié)信息寫到xml文件就可以。二、用法
? ? ? ?log4net有多重存儲級別,依照日志信息的情況大致分為了5類。它們各自是Error錯誤日志、Fatal嚴(yán)重錯誤日志、Info一般信息日志、Debug調(diào)試信息日志和Warn警告信息日志,在日志管理時能夠依照日志的級別來考慮存放的方式,對于嚴(yán)重日志往往是系統(tǒng)的重大問題,此時能夠考慮存到server數(shù)據(jù)庫中,其他的一些日志能夠考慮存儲到文件里,能夠提高server性能。接下來將會介紹它的幾種用法。
? ? 2.1 日志輸出到DataBase
? ? ? ? 把日志輸出到數(shù)據(jù)庫中也是非常多系統(tǒng)常常使用的日志存儲方法,在小數(shù)據(jù)量的處理過程中將日志保存到數(shù)據(jù)庫中是可行的。可是假設(shè)須要處理的日志數(shù)據(jù)量較大那么這樣的存儲方法就會減少數(shù)據(jù)庫的性能,所以在存儲日志時謹(jǐn)慎使用這樣的方式,建議涉及到系統(tǒng)重大問題時採用此種存儲方式。這樣會提升數(shù)據(jù)庫的性能。
詳細(xì)配置例如以下:
<appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender"><bufferSize value="1"></bufferSize><connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /><connectionString value="Data Source=.;Initial Catalog=Test;Integrated Security=True;Pooling=False" /><commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message]) VALUES (@log_date, @thread, @log_level, @logger, @message)" /><parameter><parameterName value="@log_date" /><dbType value="DateTime" /><layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}" /></parameter><parameter><parameterName value="@thread" /><dbType value="String" /><size value="255" /><layout type="log4net.Layout.PatternLayout" value="%thread" /></parameter><parameter><parameterName value="@log_level" /><dbType value="String" /><size value="50" /><layout type="log4net.Layout.PatternLayout" value="%level" /></parameter><parameter><parameterName value="@logger" /><dbType value="String" /><size value="255" /><layout type="log4net.Layout.PatternLayout" value="%logger" /></parameter><parameter><parameterName value="@message" /><dbType value="String" /><size value="4000" /><layout type="log4net.Layout.PatternLayout" value="%message" /></parameter> </appender>? ? ? ?另外剛開始學(xué)習(xí)的人在寫入數(shù)據(jù)庫時可能會有非常多問題。最基本的是不能寫入數(shù)據(jù)。這主要是因為connectionType和connectionString的原因。要又一次檢查改動才干夠,尤其是connectionType中sqlconnection的版本號問題,假設(shè)不能成功寫入數(shù)據(jù)往往就是它造成的。
? ?2.2 日志輸出到File
? ? ? 另外我們也能夠?qū)?shù)據(jù)輸出到文件里,用戶能夠自己定義文件輸出的類型,通過datePattern標(biāo)簽來設(shè)置存儲文件的類型及文件名稱,詳細(xì)例如以下配置所看到的:<log4net><!--定義輸出到文件里--><appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender"><file value="D:\" /><appendToFile value="true" /><rollingStyle value="Date" /><maxSizeRollBackups value="30" /><datePattern value="yyyy-MM-dd'.log'" /><staticLogFileName value="false" /><layout type="log4net.Layout.PatternLayout"><conversionPattern value="{%level}%date{MM/dd HH:mm:ss} - %message%newline" /></layout></appender><root><!--文件形式記錄日志--><appender-ref ref="RollingLogFileAppender" /> </root></log4net>
? ?2.3 日志輸出到Console
? ? ? ?輸出到控制臺中已經(jīng)不陌生,在windows操作系統(tǒng)中常常可以看到錯誤信息,這樣的方式可以非常直觀的告訴用戶錯誤的情況及原因,可是這樣的方式僅僅是緩存級別的,系統(tǒng)又一次啟動時錯誤信息就會被刪除。所以在使用此種方法時應(yīng)配合著上面說到的方法來綜合存儲日志。增強(qiáng)系統(tǒng)的健壯性。<log4net><!--定義輸出到控制臺命令行中--><appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"><layout type="log4net.Layout.PatternLayout"><conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" /></layout></appender><root><!--控制臺控制顯示日志--><appender-ref ref="ConsoleAppender" /> </root></log4net>
? ? 2.4 日志輸出到Event
? ? ? ?上面介紹了幾種經(jīng)常使用的輸出方式,當(dāng)然log4net還有很多其它的輸出方式。這里再介紹一種輸出到WindowsEvent的方法,這樣的方法將會把錯誤信息輸出到Windows事件中,盡管不經(jīng)常使用,但也能夠作為一種日志的存儲方式。<log4net><!--定義輸出到windows事件中--><appender name="EventLogAppender" type="log4net.Appender.EventLogAppender"><layout type="log4net.Layout.PatternLayout"><conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" /></layout></appender><!--定義日志的輸出媒介,以下定義日志以四種方式輸出。
也能夠以下的依照一種類型或其它類型輸出。--> <root> <!--Windows事件日志--> <appender-ref ref="EventLogAppender" /> </root> </log4net>
?通過使用上面的配置文件可以將日志輸出到指定的類型中,可是想要輸出日志并不僅僅是使用上面的配置,另外須要在代碼中調(diào)用方法來記錄日志,詳細(xì)例如以下:
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using log4net; using log4net.Appender;[assembly: log4net.Config.XmlConfigurator(Watch = true)] namespace ConsoleApplication1 {class Program{static void Main(string[] args){ILog log = log4net.LogManager.GetLogger(typeof(Program));//記錄錯誤日志log.Error("error", new Exception("發(fā)生了一個異常"));//記錄嚴(yán)重錯誤log.Fatal("fatal", new Exception("發(fā)生了一個致命錯誤"));//記錄一般信息log.Info("info");//記錄調(diào)試信息log.Debug("debug");//記錄警告信息log.Warn("warn");Console.WriteLine("日志記錄完成。
"); Console.Read(); } } }
? ? ? 在測試時上面的全部形式的配置輸出都能夠使用GetLogger方法來存儲存儲日志信息。
? ?Note:代碼中有這么一句:[assembly: log4net.Config.XmlConfigurator(Watch = true)](在須要使用log4net的類的namespace處),假設(shè)沒有這句就會在調(diào)試時得到例如以下留言中所說的“程序調(diào)試起來時isDebugEnable"的情況。
三、log4net保存NHibernate日志信息
? ? ? ?在使用NHibernate時經(jīng)常須要分析SQL語句,可是NHibernate默認(rèn)的是不輸出SQL Script的。那么如何才干查看它生成的SQL呢?最好還是使用下log4net吧,log4net能夠輸出NHibernate的執(zhí)行情況。能夠通過配置來實現(xiàn)輸出全部Level的NHibernate的日志信息,詳細(xì)的配置方法例如以下,這里將配置文件放到了外置的xml中。<?xml version="1.0" encoding="utf-8" ?> <log4net debug="true"> <appender name="rollingFile" type="log4net.Appender.RollingFileAppender,log4net"> <param name="File" value="D:\log\log.txt"/> <param name="AppendToFile" value="false"/> <param name="RollingStyle" value="Date"/> <param name="StaticLogFileName" value="true"/> <layout type="log4net.Layout.PatternLayout"> <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" /> </layout> </appender> <logger name="NHibernate" additivity="true"> <level value="ERROR"/> <appender-ref ref="DebugAppender" /> </logger> <logger name="NHibernate.SQL" additivity="true"> <level value="DEBUG"/> <appender-ref ref="DebugAppender" /> </logger> <logger name="NHibernate.AdoNet.AbstractBatcher" additivity="true"> <level value="DEBUG"/> <appender-ref ref="DebugAppender" /> </logger> <root> <!-- levels: DEBUG, INFO, WARN, ERROR, FATAL --> <level value="DEBUG"/> <level value="INFO"/> <level value="WARN"/> <level value="ERROR"/> <level value="FATAL "/> <appender-ref ref="rollingFile"/> </root> </log4net>
? ? 這里將log4net的配置信息放到了一個單獨的xml文件里。所以須要在執(zhí)行時將配置信息加入到log4net的配置類中。它的配置往往在Global文件的Application_Start事件中加入配置,例如以下代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Security; using System.Web.SessionState; using Medici.Etam.Data.NHibernateSessionManagement; using NHibernate; using NHibernate.Context;namespace Medici.Etam.WebService {public class Global : System.Web.HttpApplication{private static log4net.ILog logger = log4net.LogManager.GetLogger("Logger");protected void Application_Start(object sender, EventArgs e){//if the log4net is a lone file then it should be configlog4net.XmlConfigurator.Configure(new FileInfo("D:\\Code\\Etam\\ETAM\\ETAM_Webservice_T16_V1.1\\Data\\log4net.cfg.xml")); }} }
? ?
結(jié)語
? ? log4net的日志存儲功能非常強(qiáng)大,它對日志信息做了具體的分類,總共劃分為5類。在存儲日志的時候能夠依據(jù)情況來選擇性的存儲,并依據(jù)級別選擇存儲方式。另外類似的這樣的日志框架還有NLog、CLog等,能夠依據(jù)具體的日志情況來選擇使用日志存儲的框架。? ??
總結(jié)
以上是生活随笔為你收集整理的程序的记事本--log4net的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: About Instruments
- 下一篇: 阿里云前端周刊 - 第 11 期