Over the last little while I have been trying to improve the performance of our java web app running on Tomcat. Over the past 2 days, I decided to test our current logging framework against a few other competitors. There are many blog posts about which is the fastest but nothing beats your own testing!
We current use SLF4J which is great because it makes exercises like this one much easier. It basically allows you to plug and play many java logging libraries without changing any code (you just need to add certain JARs to the classpath). Our current implementation uses java.util.logging (JUL) a.k.a JDK14 logging.
Our goal: Find the fastest java logging framework that can be switched to in < 2 days of effort. We operate in a very low latency environment where speed is everything.
Contenders: JUL, Logback, Bllitz4j (not log4j b/c of reasons below)
If you poke around “common knowledge” on the internet is:
– Most people use log4j
– Logback is 10x faster than log4j
– Blitz4j (Netflix’s improvement to log4j) is 3x faster than log4j
So going into the experiments I was expecting to see Logback or Blitz4j to come out on top.
The real problem was that I couldn’t find any articles that compared (and the reason why I wanted to post this article) JUL logger to other frameworks.
So I setup a dummy endpoint that would flex all the logger muscles, nothing too complicated as below. (the idea is the same, some syntax for the loggers had to be changed a bit)
logger.debug("Debug Message");logger.info("Info Message");logger.warn("Warn Message");logger.error("Error Message");logger.trace("Trace message");logger.error(aShortString);if (logger.isDebugEnabled()) logger.debug("Debug Message With Check");if (logger.isInfoEnabled()) logger.info("Info Message With Check");if (logger.isWarnEnabled()) logger.warn("Warn Message With Check");if (logger.isErrorEnabled()) logger.error("Error Message With Check");if (logger.isTraceEnabled()) logger.trace("Trace message With Check");logger.error(aLongLongString);
I deployed my app to an EC2 host (m1.large) running on Apache Tomcat 7. Versions were:
– JUL 1.4, LogBack 1.0.9, Blitz4J 1.18, SLF4J 1.7.2
For our performance testing we use JMeter. I used both JMeter and Cloudwatch to gather the timing metrics. I used 4 JMeter hosts which each had 3 threads making requests, so I could make sure that the logging framework could handle concurrent requests well.
Below are the results and as you can see, JUL took the cake! I definitely didn’t expect that to happen and it was by a large margint the victor! Since I didn’t test just plain old Log4J, I didn’t test the claims by Logback or Blitz4j.
A. Average request time (single iteration per request)
- JUL 1.4 – 5 ms
- Logback 1.0.9 – 15 ms
- Blitz4j 1.18 – 18 ms
B. Average request time (100 iterations per request)
- JUL 1.4 – 761 ms
- Logback 1.0.9 – 1412 ms
- Blitz4j 1.18 – 1267 ms
Anyways, thats all. It was just a small test but I was very surprised to say the least. I know Netflix’s library can probably take a lot more load than this, and might not have been a fair comparison. Looks like we will be sticking with JUL for the short-term unless something comes up that warrants a switch.