Im using slf4j for tracing the information. My code is
private static final Logger log = LoggerFactory.getLogger(ObjectTest.class);
log.trace("Time taken to store " + count
+ " objects of size " + size + " is " + (time) + " msecs");
log.trace("Time taken to store {} objects of size {} is {} msecs",
new Object[] { count, size, time });
log.trace("Time taken to store {} objects of size {} is {} msecs",
count, size, time);
Which would be the preferred mechanism to log traces.
Conclusion. So essentially, SLF4J does not replace Log4j, Both work together. SLF4j removes the tight coupling between the application and logging frameworks. It makes it easy to replace with any other logging framework in the future with a more capable library.
SLF4J standardized the logging levels, which are different for the particular implementations. It drops the FATAL logging level (introduced in Log4j) based on the premise that in a logging framework we should not decide when to terminate an application. The logging levels used are ERROR, WARN, INFO, DEBUG and TRACE.
In fact, it is not possible to guarantee that a Logger will always be thread-safe. Someone could implement their own slf4j compatible logging classes. Such an implementation could be non-thread-safe, by accident or by design. If it was, then the Logger exposed via the slf4j facade would also be non-thread-safe.
Markers are named objects used to enrich log statements. Conforming logging system Implementations of SLF4J determine how information conveyed by markers are used, if at all. In particular, many conforming logging systems ignore marker data.
3 is the best.
3 and 2 generate the same (or nearly the same) bytecode, but 3 is easier to type and is shorter, so 3 is better than 2.
If trace is not enabled, 1 must perform string concatenation ("Time taken to store " + count + ....) which is somewhat expensive, while 2 does the string concatenation only if trace is enabled, which is why 3 is better than 1.
3 is best except that it is not supported in SLF4J 1.6.x. For three or more arguments you need the second form. The third form only works with one or two arguments (but not three or more).
As of SLF4J 1.7, the third form is now supported for 3 or more arguments as well. The java compiler silently transforms invocations with 3 or more arguments to the second form, passing an Object[] to the printing method. This is an implementation detail of varargs in Java and allows SLF4J 1.7 to be 100% compatible with SLF4J 1.6.
The 3rd variant is the best one.
In fact 1st case is a string concatenation via StringBuilder.
The 2nd and 3rd cases are the same. They need to box integer values to Integer (or other Object) and then to create an array to pack them.
The simple test on my machine say that the 3rd variant is better in about 8 times in case if no logging executed (56ns vs 459ns).
public class LogTest {
private static final Logger logger = LoggerFactory.getLogger(LogTest.class);
public static void main(String[] args) {
int size = 100_000_000;
long start = System.nanoTime();
for (int i = 0; i < size; i++) {
logger.trace("1 {} 2 {} 3 {}", i, i, i);
}
System.out.println((System.nanoTime() - start) / size);
start = System.nanoTime();
for (int i = 0; i < size; i++) {
logger.trace("1 " + i + " 2 " + i + " 3 " + i);
}
System.out.println((System.nanoTime() - start) / size);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With