Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a log4j console appender use different colors for different threads

I am tracking down some concurrency issues and it would be very helpful to have the output lines from each thread in a different color when logging to a console. I am on OS X. Could this be done using a conversion pattern to output some control codes or would it need a custom appender? Anyone know how?

2011-10-21 12:14:42,859 ["http-bio-8080"-exec-9] DEBUG ... 2011-10-21 12:14:43,198 ["http-bio-8080"-exec-10] DEBUG ... 

The lines for exec-9 and exec-10 should be in different colors.

like image 794
David Tinker Avatar asked Oct 21 '11 10:10

David Tinker


People also ask

What is log4j Appender console target?

The default target is System. err . Console appender uses the log message pattern specified by the user in configuration using PatternLayout property.

How does log4j Appender work?

In the log4j2 architecture, an appender is basically responsible for sending log messages to a certain output destination. Here are some of the most useful types of appenders that the library provides: ConsoleAppender – logs messages to the System console. FileAppender – writes log messages to a file.


2 Answers

You can use MulticolorLayout from jcabi-log. Add this dependency to the project:

<dependency>   <groupId>com.jcabi</groupId>   <artifactId>jcabi-log</artifactId>   <version>0.17.1</version> </dependency> 

And then configure it in log4j.properties:

log4j.rootLogger=INFO, CONSOLE log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.layout=com.jcabi.log.MulticolorLayout log4j.appender.CONSOLE.layout.ConversionPattern=[%color{%p}] %c: %m%n 

Same in log4j.xml:

<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">     <param name="Target" value="System.out" />     <layout class="com.jcabi.log.MulticolorLayout">         <param name="ConversionPattern" value="[%color{%p}] %m%n" />     </layout> </appender> 

In this example, %p will be replaced by DEBUG, INFO, ERROR, etc. and then painted into the color that is relevant to the logging level. Besides that you are able to use your own colors or predefined colors, for example:

log4j.appender.CONSOLE.layout.ConversionPattern=[%p] $color-cyan{%c}: %color-red{%m}%n log4j.appender.CONSOLE.layout.ConversionPattern=[%p] $color-0;0;31{%c}: %m%n 

More documentation about ANSI colors.

like image 82
yegor256 Avatar answered Oct 12 '22 12:10

yegor256


You can extend PatternLayout and override format(ILoggingEvent). There you could look at LoggingEvent.getThreadName() to get some color based on the thread name (odd/even, maybe?).

In order to output color to the console, you'll need to use an ANSI Escape Sequence.

For instance, to output a red text:

  "\u001b["  // Prefix - see [1] + "0"        // Brightness + ";"        // Separator + "31"       // Red foreground + "m"        // Suffix + text       // the text to output + "\u001b[m " // Prefix + Suffix to reset color 

Here some examples:

  • ColoredPatternLayout implementation by Ingo Thon.
  • Colour-coded Console Logging with Log4J blog post.

Just to add, maybe you could also achieve this by setting in the MDC a variable "randColor" with a random ANSI color code, for instance, in a Filter, and using it in the conversionPattern of a standard org.apache.log4j.PatternLayout in your log4j's console appender configuration:

<appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">     <layout class="org.apache.log4j.PatternLayout">         <param name="ConversionPattern"                value="\u001b[0;%X{randColor}m ....... \u001b[m" />     </layout> </appender> 

[1] What does "\u001B[J" represent?

like image 37
Xavi López Avatar answered Oct 12 '22 11:10

Xavi López