原文地址 : http://www.cnblogs.com/wolf-sun/p/3347373.html#3009010
簡介
log4net庫是Apache log4j框架在Microsoft .NET平台的實現,是一個幫助程序員將日志信息輸出到各種目標(控制台、文件、數據庫等)的工具。
log4net是Apache軟件基金會Apache Logging Services工程的一部分。Apache日志服務工程致力於為程序調試和審計提供跨語言的日志服務。(f:百度百科)
原理
Log4net 是基於.NET開發的一款記錄日志開源組件。它通過一套XML配置的日志引擎,將日志分不同的等級,分別是:FATAL 、 ERROR、 WARN、 INFO 、 DEBUG、ALL(允許所有的日志請求)和OFF(拒絕所有的日志請求),缺省為DEBUG,前五個是不是很熟悉?可以看到和我們平常在調試應用程序的 出錯有點類似,在編譯器中也會留下如錯誤、警告之類的提示信息,它們的錯誤級別在不斷的降低。
log4net開源項目結構如圖所示:
通過查看源碼,log4net主要有5個核心部分組成,分別為Logger,Appenders, Filters, Layouts 和Object Renders,在配置文件中它們以節點的形式出現。
- Logger:主要負責日志的記錄,它記錄的方式有多種,可以是以文件、數據庫、控制台、郵件等多處方式;
- Appenders:主要負責記錄日志介質的方式,它的輸出方式主要包括:
-
- AdoNetAppender:將日志記錄到數據庫中。可以采用SQL和存儲過程兩種方式
-
AspNetTraceAppender:能用ASP.NET中跟蹤的方式查看記錄的日志。
-
BufferingForwardingAppender:在輸出到子Appenders之前先緩存日志事件。
- ColoredConsoleAppender:在終端的窗口寫下高亮度的日志事件。
- ConsoleAppender:將日志輸出到控制台。
-
- EventLogAppender:將日志寫到Windows操作系統的日志中去。
- FileAppender:將日志寫到文件中。
- ForwardingAppender:用來為一個Appender指定一組約束。
- MemoryAppender:將日志存到內存緩沖區。
- NetSendAppender:將日志輸出到Windows Messenger service,這些日志信息將在用戶終端的對話框中顯示。
- OutputDebugStringAppender:配置該Appender以向OutputDebugString API寫入日志。
- RemotingAppender:通過.NET Remoting將日志寫到遠程接收端。
- RollingFileAppender:將日志以回滾文件的形式寫到文件中。
- SmtpAppender:將日志寫到郵件中。
- SmtpPickupDirAppender:配置與SmtpAppender類似,但要把SmtpHost換為PickupDir。
- TraceAppender:將日志寫到.NET trace 系統。
- UdpAppender:將日志connectionless UDP datagrams的形式送到遠程宿主或以UdpClient的形式廣播。
以上有些輸出方式可能會經常用到(比如寫入文件和數據庫的方式),有些可能會不經常用到(郵件方式等),具體我們在下面舉例來說明。
3.Layouts:主要負責把記錄日志格式化輸出,顯示得格式主要如下:
%timestamp [%thread] %-5level %logger{2} %ndc - %message%newline
timestamp: 表示程序已經開始執行的時間。 單位[毫秒]。
Thread:執行當前代碼的線程。
Level:日志的級別。
Logger:日志相關請求的名稱。
Message:日志消息。
newline:換行。
案例一:文件記錄方式
首先引用Log4net.dll,然后在添加一個配置文件log4net.config(這里不將配置信息寫入web.config,個人覺得寫在一起實在太亂)中添加下面的配置信息(注意應和web.config處於相同的位置,即根目錄下):
<?xml version="1.0" encoding="utf-8"?> <configuration> <!--日志配置部分--> <configSections> <!--注冊lognet--> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/> </configSections> <log4net debug="false"> <root> <priority value="ALL"/> <appender-ref ref="TraceAppender"/> <appender-ref ref="ConsoleAppender"/> <appender-ref ref="RollingFileAppender"/> </root> <appender name="TraceAppender" type="log4net.Appender.TraceAppender"> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline"/> </layout> </appender> <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline"/> </layout> </appender> <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender"> <file value="Log\SysLog"/> <!--日志文件夾及文件名開頭--> <appendToFile value="true"/> <!--是否追加到文件--> <RollingStyle value="Date"/> <!--日期的格式--> <DatePattern value="yyyy-MM-dd"/> <!--文件名后面加上.log后綴,必須使用轉義字符--> <maximumFileSize value="1MB" /> <!--最大文件大小--> <StaticLogFileName value="false"/> <!--日志文件名是否為靜態--> <layout type="log4net.Layout.PatternLayout,log4net"> <param name="ConversionPattern" value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline"/> <param name="Header" value=" ------------------網站運行過程中產生的錯誤-------------------------- "/> <param name="Footer" value=" -----------------測試:GZQ------------------------------------- "/> </layout> </appender> </log4net> <!--End站點日志配置部分--> </configuration>
%d, %date :表示當然的時間
%level : 表示日志的級別
%logger, %c:表示日志產生的主題,通常是所在的類名,便於定位問題
%m, %message :表示日志的具體內容
%n, %newline: 換行
在AssemblyInfo.cs中添加如下代碼:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
在全局處理程序中添加如下代碼:
1 protected void Application_Start(object sender, EventArgs e) 2 { 3 log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo("log4net.config")); 4 }
測試
在頁面添加button和一個label,在button的單擊事件中添加如下代碼:
protected void btnShowTime_Click(object sender, EventArgs e) { log4net.ILog myLogger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); myLogger.Warn("這是一個警告日志"); myLogger.Info("單擊了按鈕"); myLogger.Debug("用Log4Net寫入數據庫日志"); myLogger.Error("這是一個錯誤日志"); myLogger.Fatal("這是一個致命的錯誤日志"); try { ILog logger = LogManager.GetLogger("LogRecord"); logger.Debug("用Log4Net寫入數據庫日志"); int x = 5; int y = 0; Response.Write(x / y); } catch (Exception ex) { myLogger.Error(ex); } finally { lblShow.Text = DateTime.Now.ToLongTimeString()+":操作日志已記錄完成"; } }
結果
案例二:日志記入數據庫
記入數據庫的方式和記入文件的方式大同小異,主要區別在配置文件,其他步驟相同,記入數據庫的配置文件log4net.config如下:
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> </configSections> <!--Log4net Begin--> <log4net> <appender name="ADONetAppender" type="log4net.Appender.ADONetAppender"> <bufferSize value="1" /> <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <connectionString value="SERVER=127.0.0.1;DATABASE=TestDataBase;UID=sa;PWD=123456;Connect Timeout=15;" /> <commandText value="INSERT INTO ErrorLog ([dtDate],[sThread],[sLevel],[sLogger],[sMessage],[sException]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" /> <parameter> <parameterName value="@log_date" /> <dbType value="DateTime" /> <layout type="log4net.Layout.RawTimeStampLayout" /> </parameter> <parameter> <parameterName value="@thread" /> <dbType value="String" /> <size value="100" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%t" /> </layout> </parameter> <parameter> <parameterName value="@log_level" /> <dbType value="String" /> <size value="200" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%p" /> </layout> </parameter> <parameter> <parameterName value="@logger" /> <dbType value="String" /> <size value="500" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%logger" /> </layout> </parameter> <parameter> <parameterName value="@message" /> <dbType value="String" /> <size value="3000" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%m" /> </layout> </parameter> <parameter> <parameterName value="@exception" /> <dbType value="String" /> <size value="4000" /> <layout type="log4net.Layout.ExceptionLayout" /> </parameter> </appender> <!-- setup the root category, add the appenders and set the default level --> <root> <level value="WARN"/> <level value="INFO"/> <level value="DEBUG"/> <level value="FINE"/> <appender-ref ref="ADONetAppender" /> </root> <!-- specify the level for some specific categories --> <logger name="iNotes"> <level value="WARN"/> <level value="INFO"/> <level value="DEBUG"/> <level value="FINE"/> <appender-ref ref="ADONetAppender"/> </logger> <logger name="StellaLogger"> <level value="ALL"/> <appender-ref ref="AdoNetAppender" /> </logger> </log4net> <!--Log4net End--> </configuration>
創建記錄日志的數據表:
CREATE TABLE [dbo].[ErrorLog]( [nId] [bigint] IDENTITY(1,1) NOT NULL, [dtDate] [datetime] NOT NULL, [sThread] [varchar](100) NOT NULL, [sLevel] [varchar](200) NOT NULL, [sLogger] [varchar](500) NOT NULL, [sMessage] [varchar](3000) NOT NULL, [sException] [varchar](4000) NULL)
測試
采用上面的測試方法。
結果
結語
項目中經常用到的兩種方式在這里做一下總結。其他方式,用到了再補上。