Avatar billede Droa Seniormester
30. december 2014 - 09:51 Der er 5 kommentarer og
1 løsning

log4net ColoredConsoleAppender individuelt farveskema pr logger

Hej Eksperter.

Jeg prøver at farvekode min ColoredConsoleAppender igennem app.config.

jeg kan se at mapping kun kan farve efter level, og ikke efter logger navn.


betyder det at hvis man vil have et specielt farveskema for en speciel logger, at maner nød til at lave en ny appender, eller kan man gøre det igennem den samme?
Avatar billede arne_v Ekspert
31. december 2014 - 01:44 #1
Der maa vaere flere maader at goere det paa.

Men er at instantiere flere ColoredConsoleAppender'ere.

Foelgende virker.


using System;

using log4net;
using log4net.Config;

namespace Blue.One
{
    public class CB1
    {
        private ILog log = LogManager.GetLogger(typeof(CB1).FullName);
        public void Test()
        {
            log.Fatal("Just testing");
            log.Error("Just testing");
            log.Warn("Just testing");
            log.Info("Just testing");
            log.Debug("Just testing");
        }
    }
}

namespace Blue.Two
{
    public class CB2
    {
        private ILog log = LogManager.GetLogger(typeof(CB2).FullName);
        public void Test()
        {
            log.Fatal("Just testing");
            log.Error("Just testing");
            log.Warn("Just testing");
            log.Info("Just testing");
            log.Debug("Just testing");
        }
    }
}

namespace Red.One
{
    public class CR1
    {
        private ILog log = LogManager.GetLogger(typeof(CR1).FullName);
        public void Test()
        {
            log.Fatal("Just testing");
            log.Error("Just testing");
            log.Warn("Just testing");
            log.Info("Just testing");
            log.Debug("Just testing");
        }
    }
}

namespace Red.Two
{
    public class CR2
    {
        private ILog log = LogManager.GetLogger(typeof(CR2).FullName);
        public void Test()
        {
            log.Fatal("Just testing");
            log.Error("Just testing");
            log.Warn("Just testing");
            log.Info("Just testing");
            log.Debug("Just testing");
        }
    }
}

namespace E
{
    public class Program
    {
        public static void Main(string[] args)
        {
            XmlConfigurator.Configure();
            (new Blue.One.CB1()).Test();
            (new Blue.Two.CB2()).Test();
            (new Red.One.CR1()).Test();
            (new Red.Two.CR2()).Test();
            Console.ReadKey();
        }
    }
}



<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
    </configSections>
    <log4net>
        <appender name="blueconsole" type="log4net.Appender.ColoredConsoleAppender,log4net">
            <layout type="log4net.Layout.PatternLayout,log4net">
                <conversionPattern value="%d [%t] %-5p - %m%n"/>
            </layout>
            <mapping>
                <level value="ERROR" />
                <foreColor value="Blue, HighIntensity" />
                <backColor value="White" />
            </mapping>
            <mapping>
                <level value="INFO" />
                <foreColor value="Blue" />
                <backColor value="White" />
            </mapping>
        </appender>
        <appender name="redconsole" type="log4net.Appender.ColoredConsoleAppender,log4net">
            <layout type="log4net.Layout.PatternLayout,log4net">
                <conversionPattern value="%d [%t] %-5p - %m%n"/>
            </layout>
            <mapping>
                <level value="ERROR" />
                <foreColor value="Red, HighIntensity" />
                <backColor value="White" />
            </mapping>
            <mapping>
                <level value="INFO" />
                <foreColor value="Red" />
                <backColor value="White" />
            </mapping>
        </appender>
        <root>
            <level value="ALL"/>
        </root>
        <logger name="Blue">
            <level value="ALL"/>
            <appender-ref ref="blueconsole"/>
        </logger>
        <logger name="Red">
            <level value="ALL"/>
            <appender-ref ref="redconsole"/>
        </logger>
    </log4net>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
    </startup>
</configuration>
Avatar billede arne_v Ekspert
31. december 2014 - 03:59 #2
Alternativt kan man lave sin egen AdvancedColoredConsoleAppender som tillader mere avanceret konfiguration.
Avatar billede Droa Seniormester
31. december 2014 - 06:11 #3
tror os det var den løsning jeg tænkte på, hvor du laver forskellige appenders, efter farve tema.

det med at lave min egen appender, kunne jo os være en mulighed, men holder mig nok til dit eksempel, da det virker til og være lettest at konfigurere senere.

kommer der et svar? :)
Avatar billede arne_v Ekspert
01. januar 2015 - 05:02 #4
Sa svaert et det heller ikke.


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;

using log4net;
using log4net.Config;
using log4net.Appender;
using log4net.Core;

namespace Blue.One
{
    public class CB1
    {
        private ILog log = LogManager.GetLogger(typeof(CB1).FullName);
        public void Test()
        {
            log.Fatal("Just testing");
            log.Error("Just testing");
            log.Warn("Just testing");
            log.Info("Just testing");
            log.Debug("Just testing");
        }
    }
}

namespace Blue.Two
{
    public class CB2
    {
        private ILog log = LogManager.GetLogger(typeof(CB2).FullName);
        public void Test()
        {
            log.Fatal("Just testing");
            log.Error("Just testing");
            log.Warn("Just testing");
            log.Info("Just testing");
            log.Debug("Just testing");
        }
    }
}

namespace Red.One
{
    public class CR1
    {
        private ILog log = LogManager.GetLogger(typeof(CR1).FullName);
        public void Test()
        {
            log.Fatal("Just testing");
            log.Error("Just testing");
            log.Warn("Just testing");
            log.Info("Just testing");
            log.Debug("Just testing");
        }
    }
}

namespace Red.Two
{
    public class CR2
    {
        private ILog log = LogManager.GetLogger(typeof(CR2).FullName);
        public void Test()
        {
            log.Fatal("Just testing");
            log.Error("Just testing");
            log.Warn("Just testing");
            log.Info("Just testing");
            log.Debug("Just testing");
        }
    }
}

namespace E
{
    public class AdvancedColoredConsoleAppender : AppenderSkeleton
    {
        public string Map { get; set; }
        private Dictionary<Tuple<string, Level>, ConsoleColor[]> colmap = new Dictionary<Tuple<string, Level>, ConsoleColor[]>();
        private static Level ParseLevel(string s)
        {
            switch(s)
            {
                case "Fatal": return Level.Fatal;
                case "Error": return Level.Error;
                case "Warn": return Level.Warn;
                case "Info": return Level.Info;
                case "Debug": return Level.Debug;
                default: throw new Exception("Unknown level: " + s);
            }
        }
        public override void ActivateOptions()
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(Map);
            foreach(XmlElement logger in doc.SelectNodes("/map/logger"))
            {
                string pref = logger.GetAttribute("prefix");
                foreach(XmlElement color in logger.SelectNodes("color"))
                {
                    Level lvl = ParseLevel(color.GetAttribute("level"));
                    ConsoleColor[] cols = color.FirstChild.Value.Split('/').Select(s => (ConsoleColor)Enum.Parse(typeof(ConsoleColor), s)).ToArray();
                    colmap.Add(Tuple.Create(pref, lvl), cols);
                }
            }
        }
        private Level[] alllevels = { Level.Fatal, Level.Error, Level.Warn, Level.Info, Level.Debug };
        protected override void Append(LoggingEvent evt)
        {
            using(StringWriter sw = new StringWriter())
            {
                Layout.Format(sw, evt);
                lock(this)
                {
                    ConsoleColor savfore = Console.ForegroundColor;
                    ConsoleColor savback = Console.BackgroundColor;
                    for(int i = 1; i < evt.LoggerName.Length; i++)
                    {
                        string pref = evt.LoggerName.Substring(0, i);
                        foreach(Level lvl in alllevels)
                        {
                            if(evt.Level >= lvl && colmap.ContainsKey(Tuple.Create(pref, lvl)))
                            {
                                ConsoleColor[] cols = colmap[Tuple.Create(pref, lvl)];
                                Console.ForegroundColor = cols[0];
                                Console.BackgroundColor = cols[1];
                                break;
                            }
                        }
                    }
                    Console.Write(sw.ToString());
                    Console.ForegroundColor = savfore;
                    Console.BackgroundColor = savback;
                }
            }
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            XmlConfigurator.Configure();
            (new Blue.One.CB1()).Test();
            (new Blue.Two.CB2()).Test();
            (new Red.One.CR1()).Test();
            (new Red.Two.CR2()).Test();
            Console.ReadKey();
        }
    }
}



<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
    </configSections>
    <log4net>
        <appender name="console" type="E.AdvancedColoredConsoleAppender,Dec3">
            <layout type="log4net.Layout.PatternLayout,log4net">
                <conversionPattern value="%d [%t] %-5p - %m%n"/>
            </layout>
            <map><![CDATA[<map>
                              <logger prefix="Blue">
                                  <color level="Error">Blue/White</color>
                                  <color level="Info">DarkBlue/White</color>
                              </logger>
                              <logger prefix="Red">
                                  <color level="Error">Red/White</color>
                                  <color level="Info">DarkRed/White</color>
                              </logger>
                          </map>]]></map>
        </appender>
        <root>
            <level value="ALL"/>
            <appender-ref ref="console"/>
        </root>
    </log4net>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
    </startup>
</configuration>
Avatar billede arne_v Ekspert
01. januar 2015 - 05:04 #5
Jeg har snydt lidt og embedded XMl som data femfor at boevle med en custom configuration section.

Men det er ligesom ikke hovedproblemet.
Avatar billede arne_v Ekspert
01. januar 2015 - 05:04 #6
Og et svar.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester