{C#} Log4net Repository

如何使用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);
     }
配置文件:

  
    
    
    
  

  
    
  

  
    
  

  
    
    

    
      
      
      
    
    
      
      
    
  

  
    
      
    
  

然后

    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)