Log4net終結版

目錄(?)[+]

        繼上一篇Log4net的整理已經多時,最近閒時把log4net封裝了下,針對一些可能的需求進行了調查,例如多級別日誌和多文件日誌。

1.單文件日誌

        對於單文件的日誌,封裝代碼如下:

[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public enum LogMessageType  
  2. {  
  3.     Debug,  
  4.     Info,  
  5.     Warn,  
  6.     Error,  
  7.     Fatal  
  8. }  
  9. public sealed class LogProvider  
  10. {  
  11.     private static readonly ILog provider = GetLogger();  
  12.     static LogProvider() { }  
  13.     private LogProvider() { }  
  14.   
  15.     public static void Write(string msg, LogMessageType msgType, Exception ex = null)  
  16.     {  
  17.         WriteLog(msg, msgType, ex);  
  18.     }  
  19.     public static void InitConfig()  
  20.     {  
  21.         XmlConfigurator.Configure();  
  22.     }  
  23.     public static void ShutDown()  
  24.     {  
  25.         LogManager.Shutdown();  
  26.     }  
  27.   
  28.     private static ILog GetLogger()  
  29.     {  
  30.         InitConfig();  
  31.         return LogManager.GetLogger("DefaultLogger");  
  32.     }  
  33.     private static void WriteLog(string msg, LogMessageType msgType, Exception ex)  
  34.     {  
  35.         if (provider != null)  
  36.         {  
  37.             switch (msgType)  
  38.             {  
  39.                 case LogMessageType.Debug:  
  40.                     provider.Debug(msg, ex);  
  41.                     break;  
  42.                 case LogMessageType.Info:  
  43.                     provider.Info(msg, ex);  
  44.                     break;  
  45.                 case LogMessageType.Warn:  
  46.                     provider.Warn(msg, ex);  
  47.                     break;  
  48.                 case LogMessageType.Error:  
  49.                     provider.Error(msg, ex);  
  50.                     break;  
  51.                 case LogMessageType.Fatal:  
  52.                     provider.Fatal(msg, ex);  
  53.                     break;  
  54.             }  
  55.         }  
  56.     }  
  57. }  
        這樣所有要記日誌的地方只需要LogProvider.Write("this is Log", LogMessageType.Error);一行代碼即可,Log4net初始化工作封裝在初始化器中,在第一次調用Log4net時進行自動初始化。LogProvider類開放出三個靜態方法:Write、InitConfig、ShutDown,後兩者用於在程序中手動控制Log4net的開啓和關閉;Write方法採用默認參數,達到重載的效果。配置文件如下:

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0"?>  
  2. <configuration>  
  3.   <configSections>  
  4.     <section name="log4net"   
  5.              type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>  
  6.   </configSections>  
  7.   <log4net>  
  8.     <logger name="DefaultLogger">  
  9.       <level value="ALL"/>  
  10.       <appender-ref ref="txtLogger" />  
  11.     </logger>  
  12.     <appender name="txtLogger"   
  13.               type="log4net.Appender.RollingFileAppender,log4net" >  
  14.       <File value="Log\Log.txt" />  
  15.       <datePattern value="(yyyyMMdd)"/>  
  16.       <appendToFile value="true"/>  
  17.       <RollingStyle value="Composite"/>  
  18.       <MaxSizeRollBackups value="10"/>  
  19.       <maximumFileSize value="1MB"/>  
  20.       <layout type="log4net.Layout.PatternLayout">  
  21.         <conversionPattern value="%date [%t]%-5p %c - %m%n"/>  
  22.       </layout>  
  23.     </appender>  
  24.   </log4net>  
  25.   <startup/>  
  26. </configuration>  
        唯一要注意的就是<logger name="DefaultLogger">這個用來關聯,幫助類中要和配置文件中一致,其他的參數說明參照這以前寫的log4net的配置詳解

2.分級別記錄日誌

        重構代碼時我想起我們原來的日誌框架有個功能是把不同級別的日誌分開記錄的,例如把奔潰和錯誤記在一起一個文件中,警告和信息記在一個文件中,查問題時就可以先看重大錯誤。針對這個需求調查了下,也可以在配置文件中配置的,配置文件如下:

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0"?>  
  2. <configuration>  
  3.   <configSections>  
  4.     <section name="log4net"   
  5.              type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>  
  6.   </configSections>  
  7.   <log4net>  
  8.     <logger name="DefaultLogger">  
  9.       <level value="ALL"/>  
  10.       <appender-ref ref="InfoLoging" />  
  11.       <appender-ref ref="ErrorLoging" />  
  12.     </logger>  
  13.     <!--DefaultLogger Info Log-->  
  14.     <appender name="InfoLoging"   
  15.               type="log4net.Appender.RollingFileAppender,log4net" >  
  16.       <File value="Log\LogTipMsg.txt" />  
  17.       <datePattern value="(yyyyMMdd)"/>  
  18.       <appendToFile value="true"/>  
  19.       <RollingStyle value="Composite"/>  
  20.       <MaxSizeRollBackups value="10"/>  
  21.       <maximumFileSize value="1MB"/>  
  22.       <layout type="log4net.Layout.PatternLayout">  
  23.         <conversionPattern value="%date [%t]%-5p %c - %m%n"/>  
  24.       </layout>  
  25.       <filter type="log4net.Filter.LevelRangeFilter">  
  26.         <LevelMin value="DEBUG"/>  
  27.         <LevelMax value="Warn"/>  
  28.       </filter>  
  29.     </appender>  
  30.     <!--DefaultLogger Error Log-->  
  31.     <appender name="ErrorLoging"   
  32.               type="log4net.Appender.RollingFileAppender,log4net" >  
  33.       <File value="Log\LogErrorMsg.txt" />  
  34.       <datePattern value="(yyyyMMdd)"/>  
  35.       <appendToFile value="true"/>  
  36.       <RollingStyle value="Composite"/>  
  37.       <MaxSizeRollBackups value="10"/>  
  38.       <maximumFileSize value="1MB"/>  
  39.       <layout type="log4net.Layout.PatternLayout">  
  40.         <conversionPattern value="%date [%t]%-5p %c - %m%n"/>  
  41.       </layout>  
  42.       <filter type="log4net.Filter.LevelRangeFilter">  
  43.         <LevelMin value="ERROR" />  
  44.       </filter>  
  45.     </appender>  
  46.   </log4net>  
  47.   <startup/>  
  48. </configuration>  

3.按業務邏輯記錄日誌

        另一個情況就是按業務模塊記錄到不同的文件中,此時同樣可以通過配置來獲得,配置文件如下:

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0"?>  
  2. <configuration>  
  3.   <configSections>  
  4.     <section name="log4net"  
  5.              type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>  
  6.   </configSections>  
  7.   <log4net>  
  8.     <logger name="DefaultLogger">  
  9.       <level value="ALL"/>  
  10.       <appender-ref ref="InfoLoging" />  
  11.       <appender-ref ref="ErrorLoging" />  
  12.     </logger>  
  13.     <logger name="OtherCustomerLogger">  
  14.       <level value="Info"/>  
  15.       <appender-ref ref="OtherInfoLoging" />  
  16.     </logger>  
  17.     <!--DefaultLogger Info Log-->  
  18.     <appender name="InfoLoging"   
  19.               type="log4net.Appender.RollingFileAppender,log4net" >  
  20.       <File value="Log\LogTipMsg.txt" />  
  21.       <datePattern value="(yyyyMMdd)"/>  
  22.       <appendToFile value="true"/>  
  23.       <RollingStyle value="Composite"/>  
  24.       <MaxSizeRollBackups value="10"/>  
  25.       <maximumFileSize value="1MB"/>  
  26.       <layout type="log4net.Layout.PatternLayout">  
  27.         <conversionPattern value="%date [%t]%-5p %c - %m%n"/>  
  28.       </layout>  
  29.       <filter type="log4net.Filter.LevelRangeFilter">  
  30.         <LevelMin value="DEBUG"/>  
  31.         <LevelMax value="Warn"/>  
  32.       </filter>  
  33.     </appender>  
  34.     <!--DefaultLogger Error Log-->  
  35.     <appender name="ErrorLoging"   
  36.               type="log4net.Appender.RollingFileAppender,log4net" >  
  37.       <File value="Log\LogErrorMsg.txt" />  
  38.       <datePattern value="(yyyyMMdd)"/>  
  39.       <appendToFile value="true"/>  
  40.       <RollingStyle value="Composite"/>  
  41.       <MaxSizeRollBackups value="10"/>  
  42.       <maximumFileSize value="1MB"/>  
  43.       <layout type="log4net.Layout.PatternLayout">  
  44.         <conversionPattern value="%date [%t]%-5p %c - %m%n"/>  
  45.       </layout>  
  46.       <filter type="log4net.Filter.LevelRangeFilter">  
  47.         <LevelMin value="ERROR" />  
  48.       </filter>  
  49.     </appender>  
  50.     <!--OtherCustomerLogger OtherInfo Log-->  
  51.     <appender name="OtherInfoLoging"   
  52.               type="log4net.Appender.RollingFileAppender,log4net" >  
  53.       <File value="Log\LogOtherInfoLoging.txt" />  
  54.       <datePattern value="(yyyyMMdd)"/>  
  55.       <appendToFile value="true"/>  
  56.       <RollingStyle value="Composite"/>  
  57.       <MaxSizeRollBackups value="10"/>  
  58.       <maximumFileSize value="1MB"/>  
  59.       <layout type="log4net.Layout.PatternLayout">  
  60.         <conversionPattern value="%date [%t]%-5p %c - %m%n"/>  
  61.       </layout>  
  62.     </appender>  
  63.   </log4net>  
  64.   <startup/>  
  65. </configuration>  
        此時幫助類就要適當的調整了,代碼如下:

[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public enum LogicType  
  2. {  
  3.     DefaultLogger,  
  4.     OtherCustomerLogger  
  5. }  
  6. public enum LogMessageType  
  7. {  
  8.     Debug,  
  9.     Info,  
  10.     Warn,  
  11.     Error,  
  12.     Fatal  
  13. }  
  14. public sealed class LogProvider  
  15. {  
  16.     static LogProvider() { }  
  17.     private LogProvider() { }  
  18.   
  19.     private static readonly Dictionary<string, ILog> dicLoggers = GetLoggers();  
  20.   
  21.     public static void Write(string msg, LogMessageType msgType, Exception ex = null)  
  22.     {  
  23.         WriteLog(msg, msgType, ex);  
  24.     }  
  25.     public static void Write(string msg,   
  26.         LogMessageType msgType, LogicType logicType, Exception ex = null)  
  27.     {  
  28.         WriteLog(msg, msgType, ex, logicType.ToString());  
  29.     }  
  30.     public static void InitConfig()  
  31.     {  
  32.         XmlConfigurator.Configure();  
  33.     }  
  34.     public static void ShutDown()  
  35.     {  
  36.         LogManager.Shutdown();  
  37.     }  
  38.   
  39.     static Dictionary<string, ILog> GetLoggers()  
  40.     {  
  41.         InitConfig();  
  42.         ILog[] allLoggers = LogManager.GetCurrentLoggers();  
  43.         Dictionary<string, ILog> dicLoggers = new Dictionary<string, ILog>();  
  44.         foreach (var logger in allLoggers)  
  45.         {  
  46.             dicLoggers.Add(logger.Logger.Name, logger);  
  47.         }  
  48.         return dicLoggers;  
  49.     }  
  50.     static void WriteLog(string msg,   
  51.         LogMessageType msgType, Exception ex, string logicType = "DefaultLogger")  
  52.     {  
  53.         if (dicLoggers != null && dicLoggers[logicType] != null)  
  54.         {  
  55.             switch (msgType)  
  56.             {  
  57.                 case LogMessageType.Debug:  
  58.                     dicLoggers[logicType].Debug(msg, ex);  
  59.                     break;  
  60.                 case LogMessageType.Info:  
  61.                     dicLoggers[logicType].Info(msg, ex);  
  62.                     break;  
  63.                 case LogMessageType.Warn:  
  64.                     dicLoggers[logicType].Warn(msg, ex);  
  65.                     break;  
  66.                 case LogMessageType.Error:  
  67.                     dicLoggers[logicType].Error(msg, ex);  
  68.                     break;  
  69.                 case LogMessageType.Fatal:  
  70.                     dicLoggers[logicType].Fatal(msg, ex);  
  71.                     break;  
  72.             }  
  73.         }  
  74.     }  
  75. }  
        增加了LogicType這個枚舉,記錄特定業務邏輯日誌時LogProvider.Write("this is Other Info", LogMessageType.Info, LogicType.OtherCustomerLogger)。實際操作時就是根據業務邏輯擴充這個枚舉。
        至此,這個版本已經能夠直接拿到項目中用了,只需配置即可,不需要額外改動代碼。

        後記:在封裝過程中也遇到了一些問題,例如readonly和靜態構造函數的問題,當時對其理解不夠徹底,疑惑了一陣,以後有空一併總結出來。雖然是終結版,能夠作爲項目的穩定版本,但也還有一些不足,例如只想滾動保存6個月的日誌,現在就不知道log4net能不能實現(或者說怎麼實現,如果讓我實現我就只能另外寫個線程每天遍歷一次,如果有6個月前的日誌就將其刪掉)。希望能對讀者有些幫助,如果有什麼錯誤或想法,還望不吝指教,轉載請保留原文鏈接

        源代碼下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章