配置多个Log4net实例

应用场景:

控制软件工程拆分为多个子项目,在开发阶段希望每个子项目的日志是单独的。同时又希望日志统一集中定义在Tools(Tools为工具类项目,生成Tools.dll)下,而不是分散在各个子项目中。这就需要解决以下几个问题:

如何在DLL方案中配置Log4net;如何分类Logger;如何在外部使用Logger。

  1.在DLL中使用App.config配置Log4net

    • 使用NuGet添加log4net引用。
    • 为此项目添加应用程序配置文件 Tools.config。
    • 在Assembled中监视此配置文件。
    • 在Tools.config的文件属性中选择"如果较新则复制"。
2.在Log4net中配置多个名称的Logger对象
    • 在Tools.config中添加日志配置。其中 <root>定义了日志的记录级别,当前为全记录。<logger/>会继承<root/>的属性。
    • 配置不同的日志输出目标。在配置文件中表现为<appender/>的定义。
    • 关联<logger/>与<appender/>。同时指定<logger>的name属性,获取不同日志对象时使用。

 

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>       
    </configSections>
  <log4net name="DefaultLogger">
    <root>
      <level value="ALL"/>
    </root>

    <logger name="Doraemon.Hardware">
      <appender-ref ref="HardwareLogger"/>
    </logger>

    <logger name="Doraemon.UI">
      <appender-ref ref="UILogger"/>
    </logger>

    <!--硬件日志-->
    <appender name="HardwareLogger" type="log4net.Appender.RollingFileAppender">
      <file value="log/hardware.log"/>
      <appendToFile value="true"/>
      <rollingStyle value="Size"/>
      <maxSizeRollBackups value="20"/>
      <maximumFileSize value="256KB"/>
      <staticLogFileName value="true"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date #[%thread]#%-5level #%logger #[%property{NDC}] - #%message%newline"/>
      </layout>
    </appender>

    <!--UI & Workflow日志-->
    <appender name="UILogger" type="log4net.Appender.RollingFileAppender">
      <file value="log/ui.log"/>
      <appendToFile value="true"/>
      <rollingStyle value="Size"/>
      <maxSizeRollBackups value="20"/>
      <maximumFileSize value="256KB"/>
      <staticLogFileName value="true"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date #[%thread] #%-5level #%logger #[%property{NDC}] - #%message%newline"/>
      </layout>
    </appender>
  </log4net>
</configuration>
 
3.在其他项目中使用
 
public static class Logger

{

  public static ILog DefaultLogger { get; }

  public static ILog HardwareLogger { get; }

  static Logger()

  {

    DefaultLogger = LogManager.GetLogger(@"Doraemon.Default");

    HardwareLogger = LogManager.GetLogger("Doraemon.Hardware");

  }

}

4.单元测试

  

[TestMethod]

public void LoggerTest()

{

  var loggerCollect = new List<ILog>()

      {

          DefaultLogger,

          HardwareLogger,

      };

  var select = loggerCollect.FindAll((p) =>

                         p.IsDebugEnabled == p.IsErrorEnabled == p.IsFatalEnabled == p.IsInfoEnabled == p.IsWarnEnabled);

  Assert.AreEqual(loggerCollect.Count, select.Count, "日志对象初始化存在问题");

}
 
5.参考
ConfigManager.Net - App.config and Web.config helper utility, http://www.codeproject.com/Articles/26544/ConfigManager-Net-App-config-and-Web-config-helper
Log4net, http://logging.apache.org/log4net/download_log4net.cgi

2016-05-03 更新:

  如果不想将Log4net的配置文件集成在工程.config中,可以将它以XML格式存在在外部文件中。这样做的好处是随时可以自定义格式、自定义目标。配置到外部XML文件并没有什么不同,与配置在.config中及其相似,以下文件存储为log.config.xml.

<?xml version="1.0" encoding="utf-8" ?>
<log4net>    
    <logger name="Doraemon.Console">
      <appender-ref ref="Console"/>
    </logger>

    <logger name="Doraemon.UI">
      <appender-ref ref="RollingFile"/>
    </logger>
    
    <appender name="Console" type="log4net.Appender.ConsoleAppender">
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%5level [%thread] (%file:%line) - %message%newline" />
        </layout>
    </appender>
    
    <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
        <file value="example.log" />
        <appendToFile value="true" />
        <maximumFileSize value="100KB" />
        <maxSizeRollBackups value="2" />

        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%level %thread %logger - %message%newline" />
        </layout>
    </appender>
    
    <root>
        <level value="ALL" />
    </root>
</log4net>

在代码中访问也没有什么不同:)

    class Program
    {
        private static readonly ILog log = LogManager.GetLogger(@"Doraemon.Console");//@"Doraemon.UI"); begins by importing log4net related classes. 
      
        static void Main(string[] args)
        {
            // Set up a simple configuration that logs on the console.
            XmlConfigurator.Configure(new System.IO.FileInfo(@"log.config.xml"));  //使用正确的配置读取类别
            log.Info("Entering application.");
            var i = 0;
            while (i++ < 10)
                log.Info($"i = {i}");
            log.Debug("Exiting application.");

            Console.ReadLine();
        }
    }

2016-12-15 更新: 格式串

%m(message):输出的日志消息,如ILog.Debug(…)输出的一条消息

%n(new line):换行

%d(datetime):输出当前语句运行的时刻

%r(run time):输出程序从运行到执行到当前语句时消耗的毫秒数

%t(thread id):当前语句所在的线程ID

%p(priority): 日志的当前优先级别,即DEBUG、INFO、WARN…等

%c(class):当前日志对象的名称,例如:

%L:输出语句所在的行号

%F:输出语句所在的文件名

%-数字:表示该项的最小长度,如果不够,则用空格填充
原文地址:https://www.cnblogs.com/jjseen/p/5086427.html