美文网首页
{C#} Log4net Repository

{C#} Log4net Repository

作者: windflow | 来源:发表于2016-11-16 18:07 被阅读0次

    如何使用log4net不用多说,这里说一下Repository的用法。log4net Repository代表了仓库的含义,可以生产多个具名log对象。这些对象可分别写入日志。

    创建Repository的方法
    LogManager.CreateRepository(domain);
    
    Repository的配置

    有两种方法,一种是配置文件,一种是手动写代码配置。

    手动代码:
        public void InitLog4netConfig3()
        {
            var infoFilter = new LevelRangeFilter();
    
            infoFilter.LevelMax = log4net.Core.Level.Info;
            infoFilter.LevelMin = log4net.Core.Level.Info;
            infoFilter.ActivateOptions();
    
            string layoutFormat = "@Log Begin%newlineThread ID:[%thread]%newline%message%newlineLog End@%newline";
    
            var basepath = AppDomain.CurrentDomain.BaseDirectory;
            var LogDir = Path.Combine(basepath, "log");
    
            PatternLayout layout = new PatternLayout(layoutFormat);
    
            var domain = "base";
            var repository = log4net.LogManager.CreateRepository(domain);
            repository.Threshold = Level.Info;
    
            var fileAppender = new RollingFileAppender();
            fileAppender.Name = domain + "_" + "Info" + "_FileAppender";
            fileAppender.File = System.IO.Path.Combine(LogDir, "Log_" + domain + "\\" + "Info" + "\\");
            fileAppender.AppendToFile = true;
            fileAppender.RollingStyle = RollingFileAppender.RollingMode.Date;
            fileAppender.DatePattern = "yyyy-MM-dd'.log'";
            fileAppender.StaticLogFileName = false;
            fileAppender.Layout = layout;
            fileAppender.AddFilter(infoFilter);
            fileAppender.ActivateOptions();
    
            BasicConfigurator.Configure(repository, fileAppender);
         }
    
    配置文件:
    <log4net>
      <root>
        <level value="WARN" />
        <appender-ref ref="LogFileAppender" />
        <appender-ref ref="ConsoleAppender" />
      </root>
    
      <logger name="log1">
        <level value="DEBUG"/>
      </logger>
    
      <logger name="log2">
        <level value="DEBUG"/>
      </logger>
    
      <appender name="LogFileAppender" type="log4net.Appender.FileAppender" >
        <param name="File" value="your-log-file.txt" />
        <param name="AppendToFile" value="true" />
    
        <layout type="log4net.Layout.PatternLayout">
          <param name="Header" value="[Header] "/>
          <param name="Footer" value="[Footer] "/>
          <param name="ConversionPattern" value="%d [%t] %-5p %c [%x]  - %m%n" />
        </layout>
        <filter type="log4net.Filter.LevelRangeFilter">
          <param name="LevelMin" value="DEBUG" />
          <param name="LevelMax" value="WARN" />
        </filter>
      </appender>
    
      <appender name="ConsoleAppender"  type="log4net.Appender.ConsoleAppender" >
        <layout type="log4net.Layout.PatternLayout">
          <param name="ConversionPattern"  value="%d [%t] %-5p %c [%x] - %m%n" />
        </layout>
      </appender>
    </log4net>
    

    然后

        public void InitLog4netConfig()
        {
            var domain = "base";
            var repository = log4net.LogManager.CreateRepository(domain);
            var basepath = AppDomain.CurrentDomain.BaseDirectory;
            var filepath = System.IO.Path.Combine(basepath, "log4net.xml");
            var fileInfo = new FileInfo(filepath);
    
            XmlConfigurator.Configure(repository, fileInfo);
        }
    

    root是所有log的基本配置,其他的log都继承自root。level定义了可访问的最低级别。

    问题是log4net只提供了Info(),Warn(),Error()三个接口来写入日志。如果我们要单独写入其他级别的日志,比如NOTICE,该如何实现呢?

    其他级别日志

    首先,appender设置成不同的输出目录,Filter采用LevelRangeFilter并限定好,确保该级别日志会被输出。
    其次,调整好Repository.Threshold,不要被阻挡在外。
    然后,这么做:

            log4net.ILog log = log4net.LogManager.GetLogger("base", "abc");
    
            var loggingEventData = new LoggingEventData()
            {
                Level = Level.Notice,
                Message = "put notice message"
            };
    
            log.Logger.Log(new LoggingEvent(loggingEventData));
    
            log.Logger.Log(typeof(LogImpl), Level.Notice, "put notice message 2", null);
    
    • Filter
      关于Filter,LevelMatchFilter并不像其字面含义,在匹配时才输出日志。其真正作用,是在level匹配时,配合AcceptOnMatch=false阻止后续Filter的执行。
      从反编译的源代码可以看出这一点:
    // AppenderSkeleton.cs
    protected virtual bool FilterEvent(LoggingEvent loggingEvent)
    {
      if (!this.IsAsSevereAsThreshold(loggingEvent.Level))
        return false;
      IFilter filter = this.FilterHead;
      while (filter != null)
      {
        switch (filter.Decide(loggingEvent))
        {
          case FilterDecision.Deny:
            return false;
          case FilterDecision.Neutral:
            filter = filter.Next;
            break;
          case FilterDecision.Accept:
            filter = (IFilter) null;
            break;
        }
      }
      return true;
    }
    
    // LevelMatchFilter.cs
    public override FilterDecision Decide(LoggingEvent loggingEvent)
    {
      if (loggingEvent == null)
        throw new ArgumentNullException("loggingEvent");
      if (this.m_levelToMatch != (Level) null && this.m_levelToMatch == loggingEvent.Level)
        return this.m_acceptOnMatch ? FilterDecision.Accept : FilterDecision.Deny;
      else
        return FilterDecision.Neutral;
    }
    
    • level
      如何定义自己的Level呢? 比如说慢日志,也很简单。
    class SlowLogExample
    {
        private Level SLOW = new Level(Level.Info.Value + 1, "SLOW");
    
        public void InitLogConfig()
        {
            var InfoFilter = new LevelRangeFilter();
    
            InfoFilter.LevelMax = SLOW;
            InfoFilter.LevelMin = SLOW;
            InfoFilter.ActivateOptions();
    
            string layoutFormat = "@Log Begin%newlineThread ID:[%thread]%newline%message%newlineLog End@%newline";
    
            var basepath = AppDomain.CurrentDomain.BaseDirectory;
            var LogDir = Path.Combine(basepath, "log");
    
            PatternLayout layout = new PatternLayout(layoutFormat);
    
            var domain = "base";
            var repository = log4net.LogManager.CreateRepository(domain);
    
            //repository.Threshold = Level.Info;
            repository.LevelMap.Add(SLOW);
    
            var fileAppender1 = new RollingFileAppender();
            fileAppender1.Name = domain + "_" + "Info" + "_FileAppender";
            fileAppender1.File = System.IO.Path.Combine(LogDir, "Log_" + domain + "\\" + "Slow" + "\\");
            fileAppender1.AppendToFile = true;
            fileAppender1.RollingStyle = RollingFileAppender.RollingMode.Date;
            fileAppender1.DatePattern = "yyyy-MM-dd'.log'";
            fileAppender1.StaticLogFileName = false;
            fileAppender1.Layout = layout;
            fileAppender1.AddFilter(InfoFilter);
            fileAppender1.ActivateOptions();
    
            BasicConfigurator.Configure(repository, fileAppender1);
        }
    
        public void LogSlow(string message)
        {
            var log = log4net.LogManager.GetLogger("base", "");
    
            log.Logger.Log(typeof(LogImpl), SLOW, message, null);
        }
    }

    相关文章

      网友评论

          本文标题:{C#} Log4net Repository

          本文链接:https://www.haomeiwen.com/subject/cbprpttx.html