Log4net - Multiple colors on one line

I would like to record some information using log4net on the console and use several colors on each line. This is my current simplified configuration:

... <appender name="ConsoleDebug" type="log4net.Appender.ColoredConsoleAppender"> <filter type="log4net.Filter.LevelRangeFilter"> <levelMin value="INFO" /> </filter> <mapping> <level value="INFO" /> <foreColor value="Green, HighIntensity" /> </mapping> ... <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%logger{1} %message%newline" /> </layout> </appender> ... 

This displays all my registration messages as green text. Is it possible to output %logger in white text and %message as green?

+6
source share
1 answer

I thought that ANSI ESC codes might work, but apparently this is not possible on the latest operating systems. Any other solution that I see could do some non-trivial work for you.

To handle the switching colors in the layout of your message, you can do the following:

  • write your own PatternLayoutConverter template that allows you to specify which color you want. Change the colors using the Console.ForegroundColor and Console.BackgroundColor properties.
  • write your own PatternLayout template that will add the layout converter above to your converter list.
  • write a custom Appender that does not process the layout of the template before writing it. Rather, write the layout in pieces, process each piece, and then write it to the output. This saves you the ability to switch the colors of your layout converter.

This is a lot of writing code to get custom colors "done right" (i.e. your layout does not depend on the application it works with).


There is a way to cheat a little if you think that only the console appender uses your layout:

  • Create a custom appender that inherits from the Console application and override the Append method.
  • In the Append method, divided along the markers that tell you which color you want, and process them with a piece to get the desired color swaps.

It may be a quick and dirty solution, but the layout will only be used with this application. If you need to switch the application, you will have to redefine it again. Here is an example of such an application:

 public class ConsoleAppenderWithColorSwitching : ConsoleAppender { // forfeits the auto switch from Console.Error to Console.Out // of the original appender :/ protected override void Append(LoggingEvent loggingEvent) { var regex = new Regex(@"(\|\w+\|)"); var renderedLayout = base.RenderLoggingEvent(loggingEvent); var chunks = regex.Split(renderedLayout); foreach (var chunk in chunks) { if (chunk.StartsWith("|") && chunk.EndsWith("|")) { var consoleColor = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), chunk.Substring(1, chunk.Length - 2)); Console.ForegroundColor = consoleColor; } else { Console.Write(chunk); } } } } 

This allows you to change the foreground color in the layout using the following syntax: |Green| %logger{1} |Red|%message%newline |Green| %logger{1} |Red|%message%newline . This is really a proof of concept, but you can experiment with it ...


In general, I would not recommend you to take this path. It is definitely possible, but it may be more work than you are comfortable investing in dynamic color switchers.

+3
source

Source: https://habr.com/ru/post/974082/


All Articles