【问题标题】:Log4Net: Programmatically specify multiple loggers (with multiple file appenders)Log4Net:以编程方式指定多个记录器(带有多个文件附加器)
【发布时间】:2008-11-21 11:06:11
【问题描述】:

如何(以编程方式,无需 xml 配置)使用 Log4Net 配置多个记录器? 我需要它们写入不同的文件。

【问题讨论】:

    标签: c# log4net


    【解决方案1】:

    This thread at the log4net Dashboard details an approach.

    总结一下,希望不要抄袭太多代码:

    using log4net;
    using log4net.Appender;
    using log4net.Layout;
    using log4net.Repository.Hierarchy;
    
    // Set the level for a named logger
    public static void SetLevel(string loggerName, string levelName)
    {
        ILog log = LogManager.GetLogger(loggerName);
        Logger l = (Logger)log.Logger;
    
        l.Level = l.Hierarchy.LevelMap[levelName];
        }
    
    // Add an appender to a logger
    public static void AddAppender(string loggerName, IAppender appender)
    {
        ILog log = LogManager.GetLogger(loggerName);
        Logger l = (Logger)log.Logger;
    
        l.AddAppender(appender);
    }
    
    // Create a new file appender
    public static IAppender CreateFileAppender(string name, string fileName)
    {
        FileAppender appender = new
            FileAppender();
        appender.Name = name;
        appender.File = fileName;
        appender.AppendToFile = true;
    
        PatternLayout layout = new PatternLayout();
        layout.ConversionPattern = "%d [%t] %-5p %c [%x] - %m%n";
        layout.ActivateOptions();
    
        appender.Layout = layout;
        appender.ActivateOptions();
    
        return appender;
    }
    
    // In order to set the level for a logger and add an appender reference you
    // can then use the following calls:
    SetLevel("Log4net.MainForm", "ALL");
    AddAppender("Log4net.MainForm", CreateFileAppender("appenderName", "fileName.log"));
    
    // repeat as desired
    

    【讨论】:

    • 我对我的一个程序集采用了这种方法,而不是使用 XML 配置方法。虽然确实生成了文件,但由于某种原因,与 ILog 日志记录相关的方法不会将任何内容写入文件。是否有方法可以调用以使新的 appender 生效?我还没有找到类似的东西……
    • @Dave:我遇到了同样的问题,并通过将l.Repository.Configured = true; 附加到AddAppender 来解决它。
    • @Stephan 谢谢,我相信这正是我必须做的才能让它工作。 :)
    • 链接似乎已失效。讨论是否有可能存储在其他地方?
    • @MonkeyWrench:我找到了here
    【解决方案2】:
    using System;
    using Com.Foo;
    using System.Collections.Generic;
    using System.Text;
    using log4net.Config;
    using log4net;
    using log4net.Appender;
    using log4net.Layout;
    using log4net.Repository.Hierarchy;
    
    
    public class MyApp
    {
    
    
        public static void SetLevel(string loggerName, string levelName)
        {
            ILog log = LogManager.GetLogger(loggerName);
            Logger l = (Logger)log.Logger;
    
            l.Level = l.Hierarchy.LevelMap[levelName];
        }
    
        // Add an appender to a logger
        public static void AddAppender(string loggerName, IAppender appender)
        {
            ILog log = LogManager.GetLogger(loggerName);
            Logger l = (Logger)log.Logger;
    
            l.AddAppender(appender);
        }
        // Add an appender to a logger
        public static void AddAppender2(ILog log, IAppender appender)
        {
           // ILog log = LogManager.GetLogger(loggerName);
            Logger l = (Logger)log.Logger;
    
            l.AddAppender(appender);
        }
    
        // Create a new file appender
        public static IAppender CreateFileAppender(string name, string fileName)
        {
            FileAppender appender = new
                FileAppender();
            appender.Name = name;
            appender.File = fileName;
            appender.AppendToFile = true;
    
            PatternLayout layout = new PatternLayout();
            layout.ConversionPattern = "%d [%t] %-5p %c [%logger] - %m%n";
            layout.ActivateOptions();
    
            appender.Layout = layout;
            appender.ActivateOptions();
    
            return appender;
        }
    
        private static readonly ILog log = LogManager.GetLogger(typeof(MyApp));
        static void Main(string[] args)
        {
            BasicConfigurator.Configure();
            SetLevel("Log4net.MainForm", "ALL");
            AddAppender2(log, CreateFileAppender("appenderName", "fileName.log"));
            log.Info("Entering application.");
            Console.WriteLine("starting.........");
            log.Info("Entering application.");
            Bar bar = new Bar();
            bar.DoIt();
            Console.WriteLine("starting.........");
            log.Error("Exiting application.");
            Console.WriteLine("starting.........");
        }
    }
    
    
    namespace Com.Foo
    {
        public class Bar
        {
            private static readonly ILog log = LogManager.GetLogger(typeof(Bar));
    
            public void DoIt()
            {
                log.Debug("Did it again!");
            }
        }
    }
    

    【讨论】:

    • 这个工作正常,至少需要 log4jNet dll version2.0。
    【解决方案3】:

    我希望这会有所帮助,它配置了一个简单的控制台记录器。

    static void Main(string[] args)
    {
        const string logLayoutPattern =
            "[%date %timestamp][%level] %message %newline" +
            "Domain: %appdomain, User: %username %identity %newline" +
            "%stacktracedetail{10} %newline" +
            "%exception %newline";
    
        var wrapperLogger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        var logger = (Logger) wrapperLogger.Logger;
        logger.Hierarchy.Root.Level = Level.All;
    
        var consoleAppender = new ConsoleAppender
        {
            Name = "ConsoleAppender",
            Layout = new PatternLayout(logLayoutPattern)
        };
    
        logger.Hierarchy.Root.AddAppender(consoleAppender);
        logger.Hierarchy.Configured = true;
    
        wrapperLogger.Debug("Hello");
        Console.ReadKey();
    }
    

    【讨论】:

      【解决方案4】:

      我将 Blair Conrad 的答案中的代码和 Philipp M 在这篇文章中的代码混合在一起:

      stackoverflow.com/questions/16336917/can-you-configure-log4net-in-code-instead-of-using-a-config-file

      我将结果编译成我在项目中引用的 dll 并像这样调用,通常在主程序的第一行:

      public static Log = new Log4NetWrapper.LogWrapper().Setup(@"c:\myLog.log", "TestLog");
      

      这是 DLL 中的代码:

      public class LogWrapper
          {
              public ILog Setup(string logFilePath, string logName, string maxFileSize = "10MB")
              {
                  var patternLayout = new PatternLayout();
                  patternLayout.ConversionPattern = "%date [%thread] %-5level %logger - %message%newline";
                  patternLayout.ActivateOptions();
      
                  var roller = new RollingFileAppender();
                  roller.AppendToFile = true;
                  roller.File = logFilePath;
                  roller.Layout = patternLayout;
                  roller.MaxSizeRollBackups = 5;
                  roller.MaximumFileSize = maxFileSize;
                  roller.RollingStyle = RollingFileAppender.RollingMode.Size;
                  roller.StaticLogFileName = true;
                  roller.ActivateOptions();
                  //hierarchy.Root.AddAppender(roller);
      
                  var memory = new MemoryAppender();
                  memory.ActivateOptions();
      
                  ILog log = LogManager.GetLogger(logName);
                  var l = (Logger)log.Logger;
                  l.AddAppender(roller);
                  l.AddAppender(memory);
      
                  l.Level = l.Hierarchy.LevelMap["Debug"];
                  l.Repository.Configured = true;
                  return log;
              }
          }
      

      当然可以根据需要向构造函数添加参数或创建覆盖。

      【讨论】:

      • 遗憾的是,我发现虽然这在我的一个项目中运行良好,但在另一个项目中,除非代码在 Visual Studio 托管进程中运行,否则日志记录突然停止工作。我花了很多时间在上面,但我不知道为什么。所以我必须同意另一篇文章中关于 log4net 的评论。 Log4Net 很难使用而且根本不可靠):
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-13
      • 1970-01-01
      相关资源
      最近更新 更多