We use log4j 1.2.x for logging in our product and are looking to migrate to log4j 2.x in near future. One of the functionality we have implemented is to log the system information and other important parameters on every new roll-over logfile that gets generated. The way we implemented in log4j 1.2.x is that we have extended RollingFileAppender
class of log4j and have overridden the rollOver()
method, below is the part snippet of the implementation
@Override
public void rollOver() {
super.rollOver(); //We are not modifying it's default functionality but as soon as rollOver happens we apply our logic
//
// Logic to log required system properties and important parameters.
//
}
Now as we want to migrate to log4j2 we are looking at a new solution to achieve same functionality. But as I see the source code for log4j2 it is very different from older source code. The RollingFileAppender
class does not contain rollover()
method as it has been moved to RollingManagerhelper
and it has been set to private
as-well.
Developing a complete new package and extending/implementing some abstract/helper classes from log4j2 is one of the possible solution for us but that would require a lot of coding/copying as we do not modify what RollingFileAppender
does rather we only need small extension to it. Is there a simple solution to it?
UPDATE
I created a custom lookup according to the suggestion in answers and below is how I created it;
@Plugin(name = "property", category = StrLookup.CATEGORY)
public class CustomLookup extends AbstractLookup {
private static AtomicLong aLong = new AtomicLong(0);
@Override
public String lookup(LogEvent event, String key) {
if (aLong.getAndIncrement() == 0) {
return "this was first call";
}
if (key.equalsIgnoreCase("customKey")) {
return getCustomHeader();
} else {
return "non existing key";
}
}
private static String getCustomHeader() {
// Implementation of custom header
return "custom header string";
}}
But this did not work as mentioned; this always prints this was first call
in the header. I also tried putting breakoint on the first if
condition and what I noticed was that it only gets called once. So what I fear is that the customLookup class only gets initialized on the startup when log4j2 is initialising its properties from xml config. I don't know how else I could implemented this custom lookup class.
UPDATE 2
After the above implementation I tried it in bit different way which is as below;
private static AtomicLong aLong = new AtomicLong(0);
@Override
public String lookup(LogEvent event, String key) {
return getCustomHeader(key);
}
private static String getCustomHeader(final String key) {
if (aLong.getAndIncrement() == 0) {
return "this was first call";
}
if (key.equalsIgnoreCase("customKey")) {
// Implementation for customKey
return "This is custom header";
} else {
return "non existing key";
}
}
But this does the same thing as-well. log4j2 creates the headers at while initialising from its xml config file and then uses the headers from memory. The return
value of overridden lookup()
method can not be changed dynamically as it only gets called during initialisation. Any more help would be highly appreciated.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…