One important thing that needs to be setup early in every development process is logging. If you are using log4j , you have to set up properties file(s) and define Loggers, Appenders and Layouts. According to documentations “These three types of components work together to enable developers to log messages according to message type and level, and to control at runtime how these messages are formatted and where they are reported”.
One important property of every log4j configuration file is layout parameter ConversionPattern, which defines data (and data format) of log lines. Usually, your ConversionPattern will consist of information such as Log message, Timestamp, Thread, Class or Location of log line. You have to be aware that some of these properties consume more resources than others.
But what if you want to add custom parameter to your log lines? For example things like username, ip address, user agent or some kind of relevant data that is meaningful when you (or someone else) reads log files and tries to understand what happened.
This can be easily achieved with log4j Mapped Diagnostic Context or MDC. According to documentation “MDC in short, is an instrument for distinguishing interleaved log output from different sources” and is “managed on a per thread basis”. MDC is essentially a Map in which you can store/read/remove values and use them later in PatternLayout property to write them in log lines.
Say for example you want to put User-Agent header in all your log lines.
You want to fill your MDC before you wrote any log line. Good place for this is perhaps Filter, which you can setup to be executed before other code. In filter you just need to read request header, and put it in log4j MDC, before any other logging is executed.


String userAgent = request.getHeader(“User-Agent”);
MDC.put(“user-agent”, userAgent );



Now there is only one more thing left to do – add ConversionPattern property “%X{user-agent}” in your log4j configuration file, like in an example below:


<appender name="console" class="org.apache.log4j.ConsoleAppender">
	<param name="Target" value="System.out" />
	<layout class="org.apache.log4j.PatternLayout">
		<param name="ConversionPattern" value="[%X{user-agent}] %d %-5p %l - %m%n" />
	</layout>
</appender>



Similar to Log4j MDC, there is also a NDC (Nested Diagonostic Context), which is basically stack implementations onto which context information can be pushed and popped.

0 comments