Log4J2 | Create custom log levels and how to use them

Manserpatrice
CodeX
Published in
4 min readApr 30, 2021
Photo by Mildly Useful on Unsplash

Yesterday I had the problem, that I needed to log some events of my application in different log styles (different color, other order of information). I still wanted to use the same logger and didn’t wanna create a new one for each style. How to do that? With custom log levels.

What are log levels?

Log levels are used to differentiate different logs based on their importance. There are already some pretty useful log levels predefined by log4J.

As you see, the higher the number, the more information gets logged. If it is null, nothing will be logged, no matter what log level is used to log. The importance of these log is also based on the intLevel. The higher the more important a log level is. Fatal for example is extremely important and gets logged very rarely.

Create custom log level

First of all, we need to have Log4J2 added as a dependency in the build.gradle file.

We need to have the core and the api of log4J, that we can start with configuring the log4j2.xml file.

Log4J will look for different files in your project. There are different types of files which we could configure, but in our case we will stick with the log4j2.xml file. It is used to configure the loggers and log levels.

Right at the top of the file we create a new Custom Level called SUCCESS with an intLevel of 350. If you compare this intLevel to the table from above, you can see that this log level gets logged every time when at least the info level is active.

The second part is the definition of our appender. In this case we just use the normal SYSTEM_OUT as Console. The pattern layout is also pretty important and easy to use. In this configuration only the message gets printed out with a highlighting colour. These colours are defined for each log level. Errors for example are printed out red.

The last part is to configure the loggers themselves. The logger will have the name of the class it is instantiated in. You can set the default log level and the additivity. Mostly this is set to false because if it is set on true, you will receive every log event two times from the root logger and your defined one. The Appender Ref defines where the logs should get put to. In our case just the command line.

Use the log levels

To use the custom log levels we defined above, we have to create an extension function for the logger. This is how it could look like for the success level:

Create an instance of the logger

The easiest way to use the logger is to just create a new logger with the LogManager and call the log levels from there.

This way is often used since it is really easy to use and understandable on the first blink of an eye. There is another way that I will show you now.

Use Kotlin Delegate

Since we are working with Kotlin, we have the opportunity to use Kotlin Delegate, which is pretty useful in this case. If you don’t know what Kolin Delegate is or what it does, please read this article about it. It helped me understand it pretty good.

Pay attention to the part with

Logger by LogManager.getLogger()

This delegates LogManager.getLogger() to my own class and enables it to use the info or success logging right away without actually having to create an object. Delegates are also not dependent to the base class.

The output of these logs could look like this. This is dependent on the configuration in the log4j2.xml file.

Reflection

What went good

The usage of the log4j2 itself was pretty easy and fast. Also the configuration possibilities were nearly endless. There are also many possibilities to configure the output of these logs, but i chose the log4j2.xml file because it was the easiest to understand for me.

What needs improvement

In the beginning I had some trouble with the correct log levels to log out my custom log levels. Another problem I had, was using Kotlin Delegate. In the end, it wasn’t that complicated, I just forgot about one little detail in the implementation and because of that, it failed all the time.

I hope this article was useful for you 😃

--

--