如何使用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);
}
}
网友评论