首先說說為什么要進行日志記錄。在一個完整的程序系統里面,日志系統是一個非常重要的功能組成部分。它可以記錄下系統所產生的所有行為,並按照某種規范表達出來。我們可以使用日志系統所記錄的信息為系統進行排錯,優化系統的性能,或者根據這些信息調整系統的行為。
Log4net是一個很著名的開源的日志記錄組件。官方網址為:http://logging.apache.org/log4net/ ,使用Log4net能夠很簡單的為我們的程序添加日志記錄功能。下面我們先通過一個網站例子來說明如何在.net中使用log4net。
第一步,
當然是添加log4net.dll的引用啦,我這里提供一個log4net的dll文件,懶得去官網下的可以到這里下http://www.vdisk.cn/down/index/7509396A7366
第二步,
在AssemblyInfo.cs文件中添加下面一句話:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Web.config", Watch = true)]
這句話的意思是log4net會自動尋找配置文件App.config或Web.config從而獲得並加載其中的配置信息。如果想log4net隨時監視配置文件以便重新加載的話就要這樣寫按照上面一樣寫(winform程序ConfigFile為App.config)。
第三步,
配置Web.config。

<configuration> <configSections> <!--注意:這里需要添加--> <section name="log4net" type="System.Configuration.IgnoreSectionHandler"/> </configSections> <connectionStrings> <add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient" /> </connectionStrings> <!--注意:這里需要添加--> <log4net> <!--定義輸出到文件中--> <appender name="LogFileAppender" type="log4net.Appender.FileAppender"> <!--定義文件存放位置--> <file value="C:\log.txt" /> <appendToFile value="true" /> <rollingStyle value="Date" /> <datePattern value="yyyyMMdd-HH:mm:ss" /> <layout type="log4net.Layout.PatternLayout"> <!--輸出格式--> <!--樣例:2008-03-26 13:42:32,111 [10] INFO Log4NetDemo.MainClass [(null)] - info--> <conversionPattern value="記錄時間:%date 線程ID:[%thread] 日志級別:%-5level 出錯類:%logger property:[%property{NDC}] - 錯誤描述:%message%newline" /> </layout> </appender> <!--定義輸出到控制台命令行中--> <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" /> </layout> </appender> <!--定義輸出到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> <!--定義輸出到數據庫中,這里舉例輸出到Access數據庫中,數據庫為C盤的log4net.mdb--> <appender name="AdoNetAppender_Access" type="log4net.Appender.AdoNetAppender"> <connectionString value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:log4net.mdb" /> <commandText value="INSERT INTO LogDetails ([LogDate],[Thread],[Level],[Logger],[Message]) VALUES (@logDate, @thread, @logLevel, @logger,@message)" /> <!--定義各個參數--> <parameter> <parameterName value="@logDate" /> <dbType value="String" /> <size value="240" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date" /> </layout> </parameter> <parameter> <parameterName value="@thread" /> <dbType value="String" /> <size value="240" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%thread" /> </layout> </parameter> <parameter> <parameterName value="@logLevel" /> <dbType value="String" /> <size value="240" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%level" /> </layout> </parameter> <parameter> <parameterName value="@logger" /> <dbType value="String" /> <size value="240" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%logger" /> </layout> </parameter> <parameter> <parameterName value="@message" /> <dbType value="String" /> <size value="240" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%message" /> </layout> </parameter> </appender> <!--定義日志的輸出媒介,下面定義日志以四種方式輸出。也可以下面的按照一種類型或其他類型輸出。--> <root> <!--文件形式記錄日志--> <appender-ref ref="LogFileAppender" /> <!--控制台控制顯示日志--> <appender-ref ref="ConsoleAppender" /> <!--Windows事件日志--> <!--<appender-ref ref="EventLogAppender" />--> <!-- 如果不啟用相應的日志記錄,可以通過這種方式注釋掉 <appender-ref ref="AdoNetAppender_Access" /> --> </root> </log4net> <system.web> <compilation debug="true" targetFramework="4.0" /> <httpModules> <add name="fileUpload" type="WebApplication3.ProcessFileModule"/> </httpModules> <authentication mode="Forms"> <forms loginUrl="~/Account/Login.aspx" timeout="2880" /> </authentication> <membership> <providers> <clear/> <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" /> </providers> </membership> <profile> <providers> <clear/> <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/> </providers> </profile> <roleManager enabled="false"> <providers> <clear/> <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" /> <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" /> </providers> </roleManager> <httpRuntime maxRequestLength="10240000"/> </system.web> <system.webServer> <modules runAllManagedModulesForAllRequests="true"/> </system.webServer> </configuration>
上面這段配置取自周公,配置的說明上面已經注釋的比較詳細了。
第四步,
在程序中記錄信息。我們在項目下Default.aspx的Page_Load方法加入如下代碼:
//獲得log4net實例 ILog log = log4net.LogManager.GetLogger("LogFileAppender"); log.Info("Default.aspx下面的PageLoad方法被執行");
然后運行項目,可以發現在c:\log4netfile.txt中已經記錄了一條日志信息:
記錄時間:2011-04-21 21:26:17,729 線程ID:[4] 日志級別:INFO 出錯類:LogFileAppender property:[(null)] - 錯誤描述:Default.aspx下面的PageLoad方法被執行
通過上面這幾步我想您已經能夠為程序創建一些簡單日志記錄功能了。下面我們再來詳細說說log4net其他的一些使用方法與特點。
這里我通過問答的形式來說明log4net的一些應用。
1.log4net總共有幾種記錄方式,每種方式該如何配置與使用?
Log4net目前支持的輸出方式包括:
1 AdoNetAppender
將日志記錄到數據庫中。可以采用SQL和存儲過程兩種方式。
2 AnsiColorTerminalAppender
在ANSI 窗口終端寫下高亮度的日志事件。
3 AspNetTraceAppender
能用asp.net中Trace的方式查看記錄的日志。
4 BufferingForwardingAppender
在輸出到子Appenders之前先緩存日志事件。
5 ConsoleAppender
將日志輸出到控制台。
6 EventLogAppender
將日志寫到Windows Event Log.
7 FileAppender
將日志寫到文件中。
8 LocalSyslogAppender
將日志寫到local syslog service (僅用於UNIX環境下).
9 MemoryAppender
將日志存到內存緩沖區。
10 NetSendAppender
將日志輸出到Windows Messenger service.這些日志信息將在用戶終端的對話框中顯示。
11 RemoteSyslogAppender
通過UDP網絡協議將日志寫到Remote syslog service。
12 RemotingAppender
通過.NET Remoting將日志寫到遠程接收端。
13 RollingFileAppender
將日志以回滾文件的形式寫到文件中。
14 SmtpAppender
將日志寫到郵件中。
15 TraceAppender
將日志寫到.NET trace 系統。
16 UdpAppender
將日志connectionless UDP datagrams的形式送到遠程宿主或以UdpClient的形式廣播。
|
可以看到目前支持的方式還是很多的,我這里調幾個認為常用的做個例子。
1.文件的方式我們上面已經講過了,這里不再做例子了。
2.數據庫方式:
首先,添加數據庫記錄appender
<appender name="AdoNetAppender_Access" type="log4net.Appender.AdoNetAppender"> <!--數據庫連接字符串--> <connectionString value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:log4net.mdb" /> <commandText value="INSERT INTO LogDetails ([LogDate],[Thread],[Level],[Logger],[Message]) VALUES (@logDate, @thread, @logLevel, @logger,@message)" /> <!--定義各個參數--> <parameter> <parameterName value="@logDate" /> <dbType value="String" /> <size value="240" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date" /> </layout> </parameter> <parameter> <parameterName value="@thread" /> <dbType value="String" /> <size value="240" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%thread" /> </layout> </parameter> <parameter> <parameterName value="@logLevel" /> <dbType value="String" /> <size value="240" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%level" /> </layout> </parameter> <parameter> <parameterName value="@logger" /> <dbType value="String" /> <size value="240" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%logger" /> </layout> </parameter> <parameter> <parameterName value="@message" /> <dbType value="String" /> <size value="240" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%message" /> </layout> </parameter> </appender>
然后建立c:log4net.mdb 數據庫,並在代碼中啟用數據庫記錄方式:
//獲得log4net實例 ILog log = log4net.LogManager.GetLogger("AdoNetAppender_Access"); log.Debug("Default.aspx下面的PageLoad方法被執行");
這樣日志就被記錄到數據庫中了。
2.log4net如何過濾我想要的日志信息,比如一個日志中只記錄程序錯誤日志?
這個需求可以通過配置filter來實現。具體操作如下:
全局方式:
這種方式會將級別應用於所有的日志輸入方式。具體操作為在root節點下添加:
<!--控制級別,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF 比如定義級別為INFO,則INFO級別向下的級別,比如DEBUG日志將不會被記錄 --> <!--如果沒有定義LEVEL的值,則缺省為DEBUG--> <level value="ERROR" />
這樣對於所有的日志記錄方式,所有地域ERROR級別的都不會被記錄了。
單獨配置級別方式:
該方式不會影響其他的日志輸入方式。方法如下為,在具體的appender下添加filter:
<filter type="log4net.Filter.LevelRangeFilter"> <param name="LevelMin" value="ERROR" /> <param name="LevelMax" value="Fatal" /> </filter>
這種方式可以配置記錄級別的方位,如果只需要記錄一種,則最大和最小設置一樣就行了。
3.你上面的日志輸出格式我不喜歡,如何在log4net中配置我想要的日志輸出格式?
log4net的輸入格式定義在每個appender的layout中。具體的有以下內置可選項:
%m(message):輸出的日志消息,如ILog.Debug(…)輸出的一條消息
%n(new line):換行
%d(datetime):輸出當前語句運行的時刻
%r(run time):輸出程序從運行到執行到當前語句時消耗的毫秒數
%t(thread id):當前語句所在的線程ID
%p(priority): 日志的當前優先級別,即DEBUG、INFO、WARN…等
%c(class):當前日志對象的名稱,例如:
%f(file):輸出語句所在的文件名。
%l(line):輸出語句所在的行號。
%數字:表示該項的最小長度,如果不夠,則用空格填充,如“%-5level”表示level的最小寬度是5個字符,如果實際長度不夠5個字符則以空格填充。
通過這些東西,你可以任意組合你喜歡的輸出格式內容。
4.有沒有方式控制程序自動按日期記錄日志信息,即每天的日志都在不同的日志文件中?
其實這種方式對應於一種特定的記錄方式:RollingFileAppender。這種方式也是基於文件記錄的,不過他提供更加靈活的日志記錄方式。具體說來他可以按日志文件的大小或者日志記錄的時間進行自動變換日志文件。
按每天不同的日期進行記錄分類:
<appender name="RollingLogFileAppenderEveryMin" type="log4net.Appender.RollingFileAppender"> <!--日志文件名開頭--> <file value="c:\logfile.txt" /> <!--是否追加到文件--> <appendToFile value="true" /> <!--變換的形式為日期--> <rollingStyle value="Date" /> <!--日期的格式,每分鍾換一個文件記錄--> <datePattern value="yyyyMMdd-HHmm" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" /> </layout> </appender>
按照日志文件的大小進行變換,通過這種方式可以有效降低日志文件體積膨脹的問題:
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender"> <!--日志文件名--> <file value="c:\log.txt"/> <!--是否在文件中追加--> <appendToFile value="true"/> <!--按照文件的大小進行變換日志文件--> <rollingStyle value="Size"/> <!--最大變換數量,如果超過這個數量則從第一個文件開始復寫--> <maxSizeRollBackups value="10"/> <!--最大文件大小,支持KB,MB,GB--> <maximumFileSize value="100KB"/> <!--日志文件名是否為靜態--> <staticLogFileName value="true"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/> </layout> </appender>
最后從網上找了一段寫日志的原則,感覺還是很好的:
【寫日志的原則】
Ⅰ.在catch后,把異常寫入日志.
Ⅱ.在調用第三方控件的開始和結束處.
Ⅲ.在連接數據庫的開始結束處.
Ⅳ.除非必要,不要在循環體中加入日志,否則一旦出問題可能導致日志暴增.
Ⅴ.在自己認為很重要的邏輯處寫入日志.