As I said earlier, main motivation of using SLF4J in your code to write log statements is, to make your program, independent of any particular logging library, which might require different configuration than you already have, and introduce more maintenance headache. But apart from that, there is one more feature of SLF4J API, which convinced me to use SL4J over my long time favorite Log4j, that is know as place holder and represented as {} in code. Placeholder is pretty much same as %s in format() method of String, because it get substituted by actual string supplied at runtime. This not only reduce lot of String concatenation in your code, but also cost of creating String object. This is true even if you might not need that, depending upon your log level in production environment e.g. String concatenation on DEBUG and INFO levels. Since Strings are immutable and they are created in String pool, they consume heap memory and most of the time they are not needed e.g. an String used in DEBUG statement is not needed, when your application is running on ERROR level in production. By using SLF4J, you can defer String creation at runtime, which means only required Strings will be created. If you have been using log4j then you already familiar with a workaround of putting debug statement inside if() condition, but SLF4J placeholders are much better than that.
This is how you would do in Log4j, but surely this is not fun and reduce readability of code by adding unnecessary boiler-plate code.
if (logger.isDebugEnabled()) {
logger.debug("Processing trade with id: " + id + " symbol: " + symbol);
}
On the other hand if you use SLF4J, you can get same result in much concise format as shown below :
logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol);
In SLF4J, we don't need String concatenation and don't incur cost of temporary not need String. Instead, we write log message in a template format with placeholder and supply actual value as parameters. You might be thinking about what if I have multiple parameters, well you can either use variable arguments version of log methods or pass them as Object array. This is really convenient and efficient way of logging. Remember, before generating final String for logging message, this method check if a particular log level is enabled or not, which not only reduce memory consumption but also CPU time involved for executing those String concatenation instruction in advance. Here is the code of SLF4J logger method from it's Log4j Adapter class Log4jLoggerAdapter from slf4j-log4j12-1.6.1.jar.
public void debug(String format, Object arg1, Object arg2) {
if (logger.isDebugEnabled()) {
FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable());
}
}
It's also worth knowing that logging has severe impact on performance of application, and it's always advised to only mandatory logging in production environment.
This is how you would do in Log4j, but surely this is not fun and reduce readability of code by adding unnecessary boiler-plate code.
if (logger.isDebugEnabled()) {
logger.debug("Processing trade with id: " + id + " symbol: " + symbol);
}
On the other hand if you use SLF4J, you can get same result in much concise format as shown below :
logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol);
In SLF4J, we don't need String concatenation and don't incur cost of temporary not need String. Instead, we write log message in a template format with placeholder and supply actual value as parameters. You might be thinking about what if I have multiple parameters, well you can either use variable arguments version of log methods or pass them as Object array. This is really convenient and efficient way of logging. Remember, before generating final String for logging message, this method check if a particular log level is enabled or not, which not only reduce memory consumption but also CPU time involved for executing those String concatenation instruction in advance. Here is the code of SLF4J logger method from it's Log4j Adapter class Log4jLoggerAdapter from slf4j-log4j12-1.6.1.jar.
public void debug(String format, Object arg1, Object arg2) {
if (logger.isDebugEnabled()) {
FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable());
}
}
It's also worth knowing that logging has severe impact on performance of application, and it's always advised to only mandatory logging in production environment.
Responses
0 Respones to "SLF4J over Log4J, logback and java.util.Logging"
Post a Comment