【log4net】- 日誌使用教程
阿新 • • 發佈:2020-10-13
一、log4net簡介:
1. Log4net的優點:
幾乎所有的大型應用都會有自己的用於跟蹤除錯的API。因為一旦程式被部署以後,就不太可能再利用專門的除錯工具了。然而一個管理員可能需要有一套強大的日誌系統來診斷和修復配置上的問題。
經驗表明,日誌記錄往往是軟體開發週期中的重要組成部分。它具有以下幾個優點:它可以提供應用程式執行時的精確環境,可供開發人員儘快找到應用程式中的Bug;一旦在程式中加入了Log 輸出程式碼,程式執行過程中就能生成並輸出日誌資訊而無需人工干預。另外,日誌資訊可以輸出到不同的地方(控制檯,檔案等)以備以後研究之用。
Log4net就是為這樣一個目的設計的,用於.NET開發環境的日誌記錄包。
2. Log4net的安裝:
使用者可以從http://logging.apache.org/log4net/下載log4net的原始碼。解壓軟體包後,在解壓的src目錄下將log4net.sln載入Visual Studio .NET,編譯後可以得到log4net.dll。使用者要在自己的程式里加入日誌功能,只需將log4net.dll引入工程即可。
3. Log4net的結構
log4net 有四種主要的元件,分別是Logger(記錄器), Repository(庫), Appender(附著器)以及 Layout(佈局).
二、log4net使用:
1.建立專案 -> 引入log4net.dll -> 新增資料夾命名為Config -> 新增配置檔案命名為log4net.config
2.編輯log4net.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <!--註冊log4net(目前註釋掉也可以正常使用)--> <!--<configSections> <section name="log4net" type="log4net.Config.IgnoreSectionHandler"/> </configSections>--> <log4net> <!-- 日誌預設值節點 --> <root> <!-- 預設日誌物件級別 --> <!--(高) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (低) --> <level value="all" /> <!-- 預設日誌記錄方式 ref為<appender>節點的name屬性--> <appender-ref ref="MyColoredConsoleAppender"/> <!--<appender-ref ref="MyRollingFileAppender"/>--> </root>
<!-- 注意!!! <root>節點和<logger>節點,如果同時出現,會先執行root的內容,再執行logger的內容,有可能會出現重複插入記錄的情況,解決方案:預設節點不設定預設記錄方式 --> <!-- 指定類別日誌設定節點 name為LogManager.GetLogger("logger.db.debug")中的name引數 --> <logger name="logger.db.debug"> <!-- 該日誌物件的級別(可多個級別設定在一起,公用同一個記錄方式)--> <level value="DEBUG"/> <!-- 該日誌物件的記錄方式(可多個記錄方式設定在一起,同時記錄到多種媒介上) --> <appender-ref ref="AdoNetAppender_Debug"/> </logger> <logger name="logger.db.info"> <level value="INFO"/> <appender-ref ref="AdoNetAppender_Info"/> </logger>
<!-- 文字日誌 --> <logger name="logger.file.debug"> <level value="DEBUG"/> <appender-ref ref="RollingFileAppender_Debug"/> </logger> <logger name="logger.file.other"> <level value="INFO"/> <level value="WARN"/> <appender-ref ref="RollingFileAppender_Other"/> </logger> <!-- AdoNetAppender:利用ADO.NET記錄到資料庫的日誌。ConsoleAppender:將日誌輸出到控制檯。RollingFileAppender:將日誌以回滾檔案(重複操作原始檔案)的形式寫到檔案中。--> <!-- 控制檯顯示日誌 --> <appender name="MyColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender"> <!-- 設定不同級別控制檯顯示的不同顏色 --> <mapping> <level value="INFO" /> <foreColor value="Green" /> </mapping> <mapping> <level value="ERROR" /> <foreColor value="Red, HighIntensity" /> </mapping> <!-- 記錄的格式。 --> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date{HH:mm:ss,fff} [%-5level] %m %n" /> </layout> <!-- 過濾器type有如下幾種型別 log4net.Filter.DenyAllFilter 丟棄所有日誌事件。 log4net.Filter.LevelMatchFilter 準確匹配事件等級。 log4net.Filter.LevelRangeFilter 匹配一個範圍的等級。 log4net.Filter.LoggerMatchFilter 匹配一個日誌器名字的開始。 log4net.Filter.PropertyFilter 匹配指定屬性名稱的子字串。 log4net.Filter.StringMatchFilter 匹配事件訊息的子字串。 --> <filter type="log4net.Filter.LevelRangeFilter"> <!-- 控制輸出日誌的級別範圍 --> <param name="LevelMin" value="Info" /> <param name="LevelMax" value="Error" /> </filter> </appender> <!-- 檔案形式記錄日誌-Debug --> <appender name="RollingFileAppender_Debug" type="log4net.Appender.RollingFileAppender"> <!--日誌檔案路徑,按檔案大小方式輸出時在這裡指定檔名,並且前面的日誌按天在檔名後自動添加當天日期形成檔案--> <param name= "File" value= "D:\App_Log\Debug\"/>
<!--是否是向檔案中追加日誌--> <param name= "AppendToFile" value= "true"/>
<!--記錄日誌寫入檔案時,不鎖定文字檔案--> <!--<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />--> <!--Unicode編碼--> <!--<Encoding value="UTF-8" />--> <!--最多產生的日誌檔案數,value="-1"為不限檔案數--> <!--<param name="MaxSizeRollBackups" value="10" />--> <!--log保留天數--> <param name= "MaxSizeRollBackups" value= "10"/>
<!--日誌檔名是否是固定不變的(是否只寫到一個檔案中)--> <param name= "StaticLogFileName" value= "false"/>
<!--按日期產生資料夾,檔名[在日期方式與混合方式下使用]日誌檔名格式為:2008-08-31.log --> <param name= "DatePattern" value= "yyyy-MM-dd".log""/> <!--<param name="DatePattern" value="yyyy-MM-dd/"-ReflectionLayout.log="""" /> <param name="DatePattern" value="yyyyMMdd/yyyyMMdd"-TimerServer.log"" /> <param name="DatePattern" value="yyyyMMdd/"TimerServer/TimerServer.log"" />-->
<!--按照何種方式產生多個日誌檔案(日期[Date],檔案大小[Size],混合[Composite])--> <param name="RollingStyle" value="Date" />
<!--每個檔案的大小。只在混合方式與檔案大小方式下使用,超出大小的在檔名後自動增加1重新命名--> <param name="maximumFileSize" value="500KB" />
<!--記錄的格式。--> <layout type="log4net.Layout.PatternLayout"> <!-- %d, %date :表示當然的時間 %p, %level :表示日誌的級別 %c, %logger :表示日誌產生的主題或名稱,通常是所在的類名,便於定位問題 %m, %message :表示日誌的具體內容 %n, %newline :換行 %exception :表示異常資訊 --> <param name="ConversionPattern" value="%d [%t] %-5p %c - %m %logger %n" /> </layout> </appender> <!-- 檔案形式記錄日誌-Other --> <appender name="RollingFileAppender_Other" type="log4net.Appender.RollingFileAppender"> <param name= "File" value= "D:\App_Log\Other\"/> <param name= "AppendToFile" value= "true"/> <param name= "MaxSizeRollBackups" value= "10"/> <param name= "StaticLogFileName" value= "false"/> <param name= "DatePattern" value= "yyyy-MM-dd".log""/> <param name="RollingStyle" value="Date" /> <param name="maximumFileSize" value="500KB" /> <layout type="log4net.Layout.PatternLayout"> <param name="ConversionPattern" value="%d [%t] %-5p %c - %m %logger %n" /> </layout> <filter type="log4net.Filter.LevelRangeFilter"> <!-- 控制輸出日誌的級別範圍 --> <param name="LevelMin" value="Info" /> <param name="LevelMax" value="Warn" /> </filter> </appender> <!-- name屬性指定其名稱,type則是log4net.Appender名稱空間的一個類的名稱,意思是,指定使用哪種介質 --> <!-- 資料庫日誌-Debug(每一個appender節點,代表一個記錄日誌的方式) --> <appender name="AdoNetAppender_Debug" type="log4net.Appender.AdoNetAppender"> <!--日誌快取寫入條數 設定為0時只要有一條就立刻寫到資料庫 生產環境可改為10-100寫入一次--> <bufferSize value="0" />
<!-- 日誌資料庫連線型別(此處寫錯會導致無法寫入資料庫) --> <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=Test;User ID=sa;Password=sa"/>
<!-- 日誌資料庫執行SQL語句 --> <commandText value="INSERT INTO ApplicationLog_Debug(LogDate, Level, Logger, Message, Exception)VALUES(@logdate, @loglevel, @logger, @message, @exception)"/>
<!-- 引數-日誌時間 --> <parameter> <parameterName value="@logdate" /> <dbType value="DateTime" /> <layout type="log4net.Layout.RawTimeStampLayout"/> </parameter> <!-- 引數-日誌級別 --> <parameter> <parameterName value="@loglevel" /> <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="%c" /> </layout> </parameter> <!-- 引數-日誌內容(size是最大長度,超出則直接去到該長度的內容) --> <parameter> <parameterName value="@message" /> <dbType value="String" /> <size value="4000" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%m" /> </layout> </parameter> <!-- 引數-異常內容(Exception會記錄異常的所有資訊,如:System.NullReferenceException: 未將物件引用設定到物件的例項。在 TestLog4Net.Program.Main(String[] args) 位置 d:\TestDemo_Tyh\TestLog4Net\TestLog4Net\Program.cs:行號 41) --> <parameter> <parameterName value="@exception"/> <dbType value="String"/> <size value="4000"/> <layout type="log4net.Layout.ExceptionLayout"/> </parameter> </appender> <!-- 資料庫日誌-Info --> <appender name="AdoNetAppender_Info" type="log4net.Appender.AdoNetAppender"> <!-- 表示是記錄10條到緩衝區,滿10條後再寫入SQL server 除錯時可以改為1,實際應用建議為100 --> <bufferSize value="0" /> <!-- 資料庫連線型別 --> <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=Test;User ID=sa;Password=sa"/> <!-- 執行SQL語句 --> <commandText value="INSERT INTO ApplicationLog_Info(LogDate, Level, Logger, Message, Exception)VALUES(@logdate, @loglevel, @logger, @message, @exception)"/> <!-- 引數賦值 --> <parameter> <parameterName value="@logdate" /> <dbType value="DateTime" /> <layout type="log4net.Layout.RawTimeStampLayout"/> </parameter> <parameter> <parameterName value="@loglevel" /> <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="4000" /> <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> </log4net> </configuration>
3.編寫C#程式碼
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using log4net; using log4net.Config; namespace TestLog4Net { public class Program { public static void Main(string[] args) { //初始化log4net物件 InitLog4Net(); //建立預設型別的日誌物件(傳遞物件型別typeof(Program)可以自動記錄類名稱) var logger = LogManager.GetLogger(typeof(Program)); //建立指定型別的日誌物件 var loggerDbDebug = LogManager.GetLogger("logger.db.debug"); var loggerDbInfo = LogManager.GetLogger("logger.db.info");//建立指定型別的文字日誌物件 var loggerFileDebug = LogManager.GetLogger("logger.file.debug"); var loggerFileOther = LogManager.GetLogger("logger.file.other"); //寫入預設型別日誌 logger.Debug("測試日誌");//配置了過濾器不記錄此條資訊 logger.Info("測試日誌"); logger.Error("測試日誌"); //寫入指定型別日誌(可以先驗證是否為當前日誌級別) if (loggerDbDebug.IsDebugEnabled) loggerDbDebug.Debug("db.debug", new Exception("db.debug.Exception")); if (loggerDbInfo.IsInfoEnabled) loggerDbInfo.Info("db.info", new Exception("db.info.Exception")); //寫入指定型別的文字日誌 loggerFileDebug.Debug("file.debug", new Exception("file.debug.Exception")); loggerFileOther.Info("file.info", new Exception("file.info.Exception")); loggerFileOther.Warn("file.warn", new Exception("file.warn.Exception")); loggerFileOther.Error("file.error", new Exception("file.error.Exception"));//配置了過濾器不記錄此條資訊 loggerFileOther.Fatal("file.fatal", new Exception("file.fatal.Exception"));//配置了過濾器不記錄此條資訊 Console.WriteLine("complete"); Console.ReadKey(); } public static void InitLog4Net() { //配置檔案 var logCfg = new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "/Config/log4net.config"); //載入配置 XmlConfigurator.ConfigureAndWatch(logCfg); } } }
4.資料庫表建立(直接用PowerDesigner生成)
if exists (select 1 from sysindexes where id = object_id('ApplicationLog_Debug') and name = 'Index_ApplicationLog_Debug_LogDate' and indid > 0 and indid < 255) drop index ApplicationLog_Debug.Index_ApplicationLog_Debug_LogDate go if exists (select 1 from sysobjects where id = object_id('ApplicationLog_Debug') and type = 'U') drop table ApplicationLog_Debug go /*==============================================================*/ /* Table: ApplicationLog_Debug */ /*==============================================================*/ create table ApplicationLog_Debug ( Id bigint identity, LogDate datetime not null, Level varchar(50) not null, Logger varchar(50) null, Message ntext null, Exception text null, constraint PK_APPLICATIONLOG_DEBUG primary key nonclustered (Id) ) go /*==============================================================*/ /* Index: Index_ApplicationLog_Debug_LogDate */ /*==============================================================*/ create clustered index Index_ApplicationLog_Debug_LogDate on ApplicationLog_Debug ( LogDate DESC ) go
5.執行檢視日誌記錄