Posted on

Writing custom appender log4j

My View and Experience

log4j is a powerful and very versatile tool. here is a code snippet to write a custom file Appender.

The way i desire, First we need to write a java class for making a custom appender.Let’s call it “CustomFileAppender.java”

code will be as follows

public class CustomFileAppender extends FileAppender

@Override
public void setFile(String fileName) if (fileName.indexOf(“%timestamp”) >= 0) Date d = new Date();
SimpleDateFormat format = new SimpleDateFormat(“yyyyMMddHHmmssSS”);
fileName = fileName.replaceAll(“%timestamp”, format.format(d));
>
super.setFile(fileName);
>
>

her we add the date and time in format “yyyyMMddHHmmssSS” after the end of file name. In otherwords as a suffix.

eg: then your log file name would be like “log-2016063014401283”

I believe that everybody understand the numbers

for ease of everybody, i will explain that part also

the format we use “yyyyMMddHHmmssSS” and example is “2016063014401283”.
let’s take part by part from left to right.

How to Write a Custom Appender in Log4j2

Ever wanted to test whether a log statement is triggered? Or whether the format is the way you want? In this post, we’re going to create a custom log appender so we can be sure logging is behaving the way we expect.

Our CustomListAppender extends AbstractAppender , because that implements a lot of the methods from the Appender interface for us that we would otherwise have to implement ourselves.

The @Plugin annotation identifies this class a plugin that should be picked up by the PluginManager :

  • The name attribute defines the name of the appender that can be used in the configuration.
  • The category attribute should be “Core” , because “Core plugins are those that are directly represented by an element in a configuration file, such as an Appender, Layout, Logger or Filter” (source). And we are creating an appender.
  • The elementType attribute defines which type of element in the Core category this plugin should be. In our case, “appender” .
  • The printObject attribute defines whether our custom plugin class defines a useful toString() method. We do, because the AbstractAppender class we’re extending is taking care of that for us.

We implement the Appender#append(LogEvent) method to add each event to our events list. If the LogEvent happens to be mutable, we must take care to create an immutable copy of the event, otherwise subsequent log events will overwrite it (we will get a list of, say, three log events that are all referencing the same object). We also add a simple getter method to retrieve all log events.

For the PluginManager to create our custom plugin, it needs a way to instantiate it. log4j2 uses a factory method for that, indicated by the annotation @PluginFactory . An appender contains attributes, such as a name, and other elements, such as layouts and filters. To allow for these, we use the corresponding annotations @PluginAttribute to indicate that a parameter represents an attribute, and @PluginElement to indicate that a parameter represents an element.

To log errors that might occur during this setup, we can make use of the StatusLogger . This logger is available as LOGGER , and is defined in one of the parents of our custom plugin, AbstractLifeCycle . (The level of log messages that should be visible can be adjusted in the element.)

Configuration

The packages attribute on the Configuration element indicates the package that should be scanned by the PluginManager for custom plugins during initialization.

How to use our custom list appender?

When we run tests now, we are able to see all logged events by calling appender.getEvents() . Before each test, we take care to clear the list of the previous log statements.