原文地址:http://blog.csdn.net/pfe_nova/article/details/20072137
1.单文件日志
对于单文件的日志,封装代码如下:
public enum LogMessageType { Debug, Info, Warn, Error, Fatal } public sealed class LogProvider { private static readonly ILog provider = GetLogger(); static LogProvider() { } private LogProvider() { } public static void Write(string msg, LogMessageType msgType, Exception ex = null) { WriteLog(msg, msgType, ex); } public static void InitConfig() { XmlConfigurator.Configure(); } public static void ShutDown() { LogManager.Shutdown(); } private static ILog GetLogger() { InitConfig(); return LogManager.GetLogger("DefaultLogger"); } private static void WriteLog(string msg, LogMessageType msgType, Exception ex) { if (provider != null) { switch (msgType) { case LogMessageType.Debug: provider.Debug(msg, ex); break; case LogMessageType.Info: provider.Info(msg, ex); break; case LogMessageType.Warn: provider.Warn(msg, ex); break; case LogMessageType.Error: provider.Error(msg, ex); break; case LogMessageType.Fatal: provider.Fatal(msg, ex); break; } } } }
这样所有要记日志的地方只需要LogProvider.Write("this is Log", LogMessageType.Error);一行代码即可,Log4net初始化工作封装在初始化器中,在第一次调用Log4net时进行自动初始化。LogProvider类开放出三个静态方法:Write、InitConfig、ShutDown,后两者用于在程序中手动控制Log4net的开启和关闭;Write方法采用默认参数,达到重载的效果。配置文件如下:
<?xml version="1.0"?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/> </configSections> <log4net> <logger name="DefaultLogger"> <level value="ALL"/> <appender-ref ref="txtLogger" /> </logger> <appender name="txtLogger" type="log4net.Appender.RollingFileAppender,log4net" > <File value="Log\Log.txt" /> <datePattern value="(yyyyMMdd)"/> <appendToFile value="true"/> <RollingStyle value="Composite"/> <MaxSizeRollBackups value="10"/> <maximumFileSize value="1MB"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%t]%-5p %c - %m%n"/> </layout> </appender> </log4net> <startup/> </configuration>
唯一要注意的就是<logger name="DefaultLogger">这个用来关联,帮助类中要和配置文件中一致,其他的参数说明参照这以前写的log4net的配置详解。
2.分级别记录日志
重构代码时我想起我们原来的日志框架有个功能是把不同级别的日志分开记录的,例如把奔溃和错误记在一起一个文件中,警告和信息记在一个文件中,查问题时就可以先看重大错误。针对这个需求调查了下,也可以在配置文件中配置的,配置文件如下:
<?xml version="1.0"?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/> </configSections> <log4net> <logger name="DefaultLogger"> <level value="ALL"/> <appender-ref ref="InfoLoging" /> <appender-ref ref="ErrorLoging" /> </logger> <!--DefaultLogger Info Log--> <appender name="InfoLoging" type="log4net.Appender.RollingFileAppender,log4net" > <File value="Log\LogTipMsg.txt" /> <datePattern value="(yyyyMMdd)"/> <appendToFile value="true"/> <RollingStyle value="Composite"/> <MaxSizeRollBackups value="10"/> <maximumFileSize value="1MB"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%t]%-5p %c - %m%n"/> </layout> <filter type="log4net.Filter.LevelRangeFilter"> <LevelMin value="DEBUG"/> <LevelMax value="Warn"/> </filter> </appender> <!--DefaultLogger Error Log--> <appender name="ErrorLoging" type="log4net.Appender.RollingFileAppender,log4net" > <File value="Log\LogErrorMsg.txt" /> <datePattern value="(yyyyMMdd)"/> <appendToFile value="true"/> <RollingStyle value="Composite"/> <MaxSizeRollBackups value="10"/> <maximumFileSize value="1MB"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%t]%-5p %c - %m%n"/> </layout> <filter type="log4net.Filter.LevelRangeFilter"> <LevelMin value="ERROR" /> </filter> </appender> </log4net> <startup/> </configuration>
3.按业务逻辑记录日志
另一个情况就是按业务模块记录到不同的文件中,此时同样可以通过配置来获得,配置文件如下:
<?xml version="1.0"?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/> </configSections> <log4net> <logger name="DefaultLogger"> <level value="ALL"/> <appender-ref ref="InfoLoging" /> <appender-ref ref="ErrorLoging" /> </logger> <logger name="OtherCustomerLogger"> <level value="Info"/> <appender-ref ref="OtherInfoLoging" /> </logger> <!--DefaultLogger Info Log--> <appender name="InfoLoging" type="log4net.Appender.RollingFileAppender,log4net" > <File value="Log\LogTipMsg.txt" /> <datePattern value="(yyyyMMdd)"/> <appendToFile value="true"/> <RollingStyle value="Composite"/> <MaxSizeRollBackups value="10"/> <maximumFileSize value="1MB"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%t]%-5p %c - %m%n"/> </layout> <filter type="log4net.Filter.LevelRangeFilter"> <LevelMin value="DEBUG"/> <LevelMax value="Warn"/> </filter> </appender> <!--DefaultLogger Error Log--> <appender name="ErrorLoging" type="log4net.Appender.RollingFileAppender,log4net" > <File value="Log\LogErrorMsg.txt" /> <datePattern value="(yyyyMMdd)"/> <appendToFile value="true"/> <RollingStyle value="Composite"/> <MaxSizeRollBackups value="10"/> <maximumFileSize value="1MB"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%t]%-5p %c - %m%n"/> </layout> <filter type="log4net.Filter.LevelRangeFilter"> <LevelMin value="ERROR" /> </filter> </appender> <!--OtherCustomerLogger OtherInfo Log--> <appender name="OtherInfoLoging" type="log4net.Appender.RollingFileAppender,log4net" > <File value="Log\LogOtherInfoLoging.txt" /> <datePattern value="(yyyyMMdd)"/> <appendToFile value="true"/> <RollingStyle value="Composite"/> <MaxSizeRollBackups value="10"/> <maximumFileSize value="1MB"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%t]%-5p %c - %m%n"/> </layout> </appender> </log4net> <startup/> </configuration>
帮助类调整如下:
public enum LogicType { DefaultLogger, OtherCustomerLogger } public enum LogMessageType { Debug, Info, Warn, Error, Fatal } public sealed class LogProvider { static LogProvider() { } private LogProvider() { } private static readonly Dictionary<string, ILog> dicLoggers = GetLoggers(); public static void Write(string msg, LogMessageType msgType, Exception ex = null) { WriteLog(msg, msgType, ex); } public static void Write(string msg, LogMessageType msgType, LogicType logicType, Exception ex = null) { WriteLog(msg, msgType, ex, logicType.ToString()); } public static void InitConfig() { XmlConfigurator.Configure(); } public static void ShutDown() { LogManager.Shutdown(); } static Dictionary<string, ILog> GetLoggers() { InitConfig(); ILog[] allLoggers = LogManager.GetCurrentLoggers(); Dictionary<string, ILog> dicLoggers = new Dictionary<string, ILog>(); foreach (var logger in allLoggers) { dicLoggers.Add(logger.Logger.Name, logger); } return dicLoggers; } static void WriteLog(string msg, LogMessageType msgType, Exception ex, string logicType = "DefaultLogger") { if (dicLoggers != null && dicLoggers[logicType] != null) { switch (msgType) { case LogMessageType.Debug: dicLoggers[logicType].Debug(msg, ex); break; case LogMessageType.Info: dicLoggers[logicType].Info(msg, ex); break; case LogMessageType.Warn: dicLoggers[logicType].Warn(msg, ex); break; case LogMessageType.Error: dicLoggers[logicType].Error(msg, ex); break; case LogMessageType.Fatal: dicLoggers[logicType].Fatal(msg, ex); break; } } } }
增加了LogicType这个枚举,记录特定业务逻辑日志时LogProvider.Write("this is Other Info", LogMessageType.Info, LogicType.OtherCustomerLogger)。实际操作时就是根据业务逻辑扩充这个枚举。
至此,这个版本已经能够直接拿到项目中用了,只需配置即可,不需要额外改动代码。
后记:在封装过程中也遇到了一些问题,例如readonly和静态构造函数的问题,当时对其理解不够彻底,疑惑了一阵,以后有空一并总结出来。虽然是终结版,能够作为项目的稳定版本,但也还有一些不足,例如只想滚动保存6个月的日志,现在就不知道log4net能不能实现(或者说怎么实现,如果让我实现我就只能另外写个线程每天遍历一次,如果有6个月前的日志就将其删掉)。希望能对读者有些帮助,如果有什么错误或想法,还望不吝指教,转载请保留原文链接。