log4net managedcoloredconsole 不适用于动态创建

Posted

技术标签:

【中文标题】log4net managedcoloredconsole 不适用于动态创建【英文标题】:log4net managedcoloredconsole not working with dynamic creation 【发布时间】:2022-01-20 16:14:39 【问题描述】:

我有一个程序,它有一组基于输入参数调用的不同模块。订单、发货、定价等模块。我编写了一个以 log4net 为基础的日志记录类,尽管也需要一些自定义日志记录。我想要的是让每个模块都有自己的日志文件,并且到那时,我能够让 log4net 为每个文件动态创建附加程序。

我还能够在手动运行时获得控制台显示,但我丢失了(并且无法弄清楚如何让它工作是彩色控制台附加程序。我找到了基本解决方案here用于创建附加程序,然后我使用this link 来弄清楚如何创建控制台和 ManagedColoredConsole 附加程序,但是虽然它仍然写入控制台,但我没有得到颜色。

有些东西不见了,但我不知道是什么。我编写了一个小测试程序来尝试解决这个问题,这就是日志记录类:

using log4net;
using log4net.Appender;
using log4net.Layout;
using log4net.Repository.Hierarchy;
using System;
using System.Linq;

namespace TestLogging

    public class Logging
    

        // Since the current version of logging will require more custom fields passed into the logging table
        // I'm going to set up a wrapper around the log for net processing. This should simplify the way we call it in 
        // the main program sections so we don't have to keep adding constants like pid and we can deal with variables 
        // like item, order number, shipping numbers

        public static ILog log = null;

        public string transType = "";
        public string pid = "0";
        private string logModule = "main";
        private string path = "";

        public Logging(string LogModule)
        
            logModule = LogModule;    // set up to default to main then pass in the specific log file name for log4net

            SetLevel("Log4net.MainForm", "ALL");
            path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
            string execPath = AppDomain.CurrentDomain.BaseDirectory;

            if (log.Logger.Repository.GetAppenders().Count() == 0)
            
                //CreateConsoleAppender();
                CreateManagedColorConsoleAppender();
            

            AddAppender(LogModule, CreateFileAppender(logModule, execPath + "\\logs\\" + logModule + ".log"));

        
        public void Info(string message, string sohnum = null, string itmref = null, string sdhnum = null, double processtime = 0.0)
        
            setCustom(sohnum, itmref, sdhnum, processtime);
            log.Info(message);
        
        private void setCustom(string sohnum = null, string itmref = null, string sdhnum = null, double processtime = 0.0)
        
            log4net.ThreadContext.Properties["TransType"] = transType;

            log4net.ThreadContext.Properties["sohnum_0"] = sohnum;
            log4net.ThreadContext.Properties["itmref_0"] = itmref;
            log4net.ThreadContext.Properties["sdhnum_0"] = sdhnum;
            log4net.ThreadContext.Properties["processtime"] = processtime.ToString();
            log4net.ThreadContext.Properties["pid"] = pid;

        
        // Set the level for a named logger
        public static void SetLevel(string loggerName, string levelName)
        
            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)
        
            log = LogManager.GetLogger(loggerName);
            Logger l = (Logger)log.Logger;

            l.Repository.Configured = true;
            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;
        
        public static IAppender CreateConsoleAppender()
        
            ConsoleAppender appender = new ConsoleAppender();
            appender.Name = "console";

            PatternLayout layout = new PatternLayout();
            layout.ConversionPattern = "%d [%t] %-5p %c [%x] - %m%n";
            layout.ActivateOptions();

            appender.Layout = layout;
            appender.ActivateOptions();

            var hierarchy = (Hierarchy)LogManager.GetRepository();

            hierarchy.Configured = true;

            hierarchy.Root.AddAppender(appender);


            return appender;
        
        public static IAppender CreateManagedColorConsoleAppender()
        

            ManagedColoredConsoleAppender appender = new ManagedColoredConsoleAppender();
            ManagedColoredConsoleAppender.LevelColors mapping = new ManagedColoredConsoleAppender.LevelColors();

            appender.Name = "ManagedColoredConsoleAppender";
            mapping.Level = log4net.Core.Level.Debug;
            mapping.ForeColor = ConsoleColor.Blue;
            appender.AddMapping(mapping);
            mapping.Level = log4net.Core.Level.Info;
            mapping.ForeColor = ConsoleColor.Green;
            appender.AddMapping(mapping);
            mapping.Level = log4net.Core.Level.Error;
            mapping.ForeColor = ConsoleColor.Yellow;
            appender.AddMapping(mapping);
            mapping.Level = log4net.Core.Level.Fatal;
            mapping.ForeColor = ConsoleColor.Red;
            appender.AddMapping(mapping);

            PatternLayout layout = new PatternLayout();
            layout.ConversionPattern = "%d [%t] %-5p %c [%x] - %m%n";
            layout.ActivateOptions();

            appender.Layout = layout;
            appender.ActivateOptions();


            var hierarchy = (Hierarchy)LogManager.GetRepository();

            hierarchy.Root.AddAppender(appender);
            hierarchy.Configured = true;
            hierarchy.Root.Level = log4net.Core.Level.Info;
            
            return appender;

        
    

很粗糙,但这只是为了测试和学习。

这是主程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestLogging

    public class Program
    
        //private Logging logging = new Logging("file");
        private static Logging logit = new Logging("main");

        static void Main(string[] args)
        

            logit.Info("This is the main program");

            ordersClass orders = new ordersClass();
            orders.callMe();
            shipments shipit = new shipments();
            shipit.shipMe();

        
    

以及写入不同日志文件的类之一:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestLogging

    public class ordersClass
    
        private Logging logit = new Logging("orders");
        public void callMe()
        
            logit.Info("Just placed an order");
        
    

当我设置断点来查看日志对象时,我可以看到托管颜色作为根附加程序存在,而其他颜色则在首次创建时添加。没有太多关于以编程方式使用 log4net 的信息,但我希望有人能做到这一点。

【问题讨论】:

【参考方案1】:

当我阅读更多内容时,我发现了如何为 log4net 打开内部日志记录。将它放在 app.config 文件中,是的,它向我展示了如何解决我的问题,尽管它为什么不能动态工作仍然暗示我。

<appSettings>
    <add key="log4net.Internal.Debug" value="true"/>
</appSettings>

我发现了一些东西:

如果您以编程方式进行设置,Log4net 不需要配置文件即可工作。发现是因为我没有将“复制到输出目录”设置为“不复制”,所以没有将配置文件放在 exe 文件夹中。这向我表明您不需要配置文件来进行日志记录,但它仍然没有回答为什么没有颜色。

如果您决定使用配置文件,但没有放入根目录中引用的附加程序,log4net 会记录错误,但会继续工作。我有这个

<appender-ref ref="ManagedColoredConsoleAppender" />

但文件中没有附加程序。我添加了 ManagedColorConsole Appender,现在我得到了彩色控制台消息并登录到多个文件。这是一个解决方案,但没有解释为什么我可以动态添加颜色附加器,但不能让它工作。如果有答案请发帖。同时,这是一个已解决的问题。

<log4net>
  <root>
    <level value="ALL" />
    <appender-ref ref="ManagedColoredConsoleAppender" />
  </root>
  <appender name="ManagedColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
    <mapping>
      <level value="INFO" />
      <foreColor value="Green, HighIntensity" />
    </mapping>
    <mapping>
      <level value="DEBUG" />
      <foreColor value="Green" />
    </mapping>
    <mapping>
      <level value="ERROR" />
      <foreColor value="Yellow, HighIntensity" />
    </mapping>
    <mapping>
      <level value="FATAL" />
      <foreColor value="Red, HighIntensity" />
    </mapping>
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
  </appender>
</log4net>

【讨论】:

以上是关于log4net managedcoloredconsole 不适用于动态创建的主要内容,如果未能解决你的问题,请参考以下文章

c#中使用log4net工具记录日志

log4net 存储到oracle 调试 Could not load type [log4net.Appender.OracleAppender]

如何配置log4net以便log.IsDebugEnabled为true

log4net使用

log4net 配置

Log4Net之记录日志到数据库