Expression and registration of Java Lambda

I read the new Log4j2 functions and there was a function that allows

"Java 8 lambda support for lazy logging"

And he gives two examples

The first one is bad practice.

// pre-Java 8 style optimization: explicitly check the log level // to make sure the expensiveOperation() method is only called if necessary if (logger.isTraceEnabled()) { logger.trace("Some long-running operation returned {}", expensiveOperation()); } 

And the second is good practice.

 // Java-8 style optimization: no need to explicitly check the log level: // the lambda expression is not evaluated if the TRACE level is not enabled logger.trace("Some long-running operation returned {}", () -> expensiveOperation()); 

Where is checking to see if the requested log level is enabled? "logger.isTraceEnabled()" ?

+6
source share
2 answers

Where is checking to see if the requested log level is enabled?

Inside the logger.trace() method.

The trick here, however, is how you pass the argument. The pre-java8 style computed value during a call to logger.trace .

 logger.trace(..., expensiveOperation()); 

Java 8 style uses Supplier

 logger.trace( ..., () -> expensiveOperation()); 

Thus, expensiveOperation() is called only on request - inside the trace method.

Take a look at the java.util.logging.Logger.log() implementation:

 public void log(Level level, Supplier<String> msgSupplier) { if (!isLoggable(level)) { return; } LogRecord lr = new LogRecord(level, msgSupplier.get()); // <-- here is the expensive computation doLog(lr); } 
+7
source

The trace method (or any other logging method for this) already checks the level of logging inside. Checking it at the caller is also an optimization to avoid calculating expensiveOperation() . With Java 8 syntax, we do not pass the computed value of expensiveOperation() , but lambda, which only calls it when necessary.

Note that although log4j did not implement it, theoretically you could have the same behavior without the strong syntax of Java 8, defining the interface for the value provider and the logging method that calls it:

 // Interface definition public interface ValueProvider { String getValue(); } // Calling it from the main code with an anonymous implementation: logger.trace("Some long-running operation returned {}", new ValueProvider() { public String getValue() { return expensiveOperation(); } }); 
+2
source

Source: https://habr.com/ru/post/1013746/


All Articles