If you are a java coder, logging is indispensable part of your life. Often in your life you may have been in a situation, where you need a special purpose logging.
For example performance logging. If you have performance bottleneck in your application and if you suspect a few classes to be the culprit (or methods for that matter), then you may need a separate logger, that will log the performance of those classes. It will be in addition to the existing logging you have in your application.
Performance logging is just an example, but in these special situations, you feel the need of a custom logger.
Writing a custom logger is very simple, yet very helpful.
I a hereby giving the example of a performance logger. It will note the START time, END time and the time difference in the form of a CSV. As you dont want this to mess with your main application logs, you will need a separate log appender for this(TimingStats in this example).
Though it talks about performance logging, this code snippet can be modified to implement any kind of custom logger.
PerformanceLogger.java
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
public class PerformanceLogger {
private static Logger logger = Logger.getLogger(PerformanceLogger.class);
String methodName;
long startTime;
long endTime;
public PerformanceLogger() {
super();
logger.setLevel(Level.ERROR);
}
public PerformanceLogger(Level level) {
super();
logger.setLevel(level);
}
public static boolean debug(){
return logger.getLevel()==Level.DEBUG?true:false;
}
public void writeTime(String operation){
logger.debug(operation);
}
public void startMethod(String methodName){
this.methodName = methodName;
startTime = System.currentTimeMillis();
writeTime(methodName+":START: ,"+startTime+", milliseconds");
}
public void endMethod(String methodName) {
this.methodName = methodName;
endTime = System.currentTimeMillis();
writeTime(methodName+":END: ,"+endTime+", milliseconds");
writeTime(methodName+":TIME TAKEN: ,"+((endTime-startTime)/1000)+", seconds");
}
}
log4j.xml
<appender name="Your_Default_appender" />
<!-- this appender will be used by performance logger class -->
<appender name="TimingStats" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="./logs/TimingStats.csv"/>
<param name="Append" value="false" />
<param name="MaxFileSize" value="10MB"/>
<param name="MaxBackupIndex" value="1"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d , [%t] , %x , %-5p , (%F) , %m%n"/>
</layout>
</appender>
<!-- All your loggin levels for classes would be here. -->
<logger name="some class" additivity="false">
<level value="DEBUG" />
<appender-ref ref="Your_Default_appender" />
</logger>
<!-- There will be a special declaration of the PerformanceLogger class. Note that it is not using the default appender. -->
<logger name="PerformanceLogger" additivity="false">
<level value="DEBUG" />
<appender-ref ref="TimingStats" />
</logger>
Put the following lines in the class you want to log the performance.
private static PerformanceLogger log = new PerformanceLogger(Level.DEBUG);
You can use a singleton pattern if you want. But that is another topic.
At the start of any methos put
log.startMethod(methodName);
At the end of any method put
log.endMethod(methodName)
That should serve your purpose. If you see any issue with my code, please comment and help me improve