Log4net终结版

        继 上一篇Log4net的整理已经多时,最近闲时把log4net封装了下,针对一些可能的需求进行了调查,例如多级别日志和多文件日志。

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个月前的日志就将其删掉)。希望能对读者有些帮助,如果有什么错误或想法,还望不吝指教,转载请保留原文链接

        源代码下载

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值