Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a correct way to pass arguments in slf4j?

Tags:

java

slf4j

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.

like image 328
diya Avatar asked Aug 18 '11 04:08

diya


People also ask

Can SLF4J work without Log4j?

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.

How does SLF4J work?

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.

Is SLF4J logger thread safe?

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.

What is marker in SLF4J?

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 Answers

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.

like image 181
sbridges Avatar answered Sep 20 '22 06:09

sbridges


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.

like image 24
Ceki Avatar answered Sep 24 '22 06:09

Ceki


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);
    }
}
like image 44
Фима Гирин Avatar answered Sep 24 '22 06:09

Фима Гирин