ppkarwasz commented on issue #2720:
URL: 
https://github.com/apache/logging-log4j2/issues/2720#issuecomment-2217954069

   @blaghed,
   
   > After receiving your feedback and going again through the mentioned code, 
I can't really find a nice way to "cache" the `LoggerContext` in order to 
prevent the expensive `StackWalker` to always be called, at least not without 
some hacky approach. Indeed, logback doesn't have this issue, so I should 
simply use that one instead.
   
   As @vy explained, the expensive `StackWalker` call is necessary to return a 
different `Logger` instance depending on the caller of 
`LoggerFactory#getLogger()`. If you eliminate the call (e.g. by switching to 
Logback) you lose **all advantages** that instance loggers have over static 
loggers.
   
   The trick of using instance loggers is to manage the cost of `Logger` 
creation by assigning the logger to a field:
   
   ```java
   public class MyService {
     private final org.slf4j.Logger log = 
org.slf4j.LoggerFactory.getLogger(MyApp.class);
     public void doSomething() {
       log.info("Hello World!");
     }
   }
   ```
   
   This way if both application `A` and application `B` instantiate 
`MyService`, they could get different `Logger` instances, configured to log to 
different appenders.
   
   The choice of using instance loggers implies however other limitations to 
your library. You can not use logging in classical "utility" classes:
   
   ```java
   public final class MyUtil {
       private static final Logger log = LoggerFactory.getLogger(MyUtil.class);
   
       public static String transform(String value) {
           log.debug("Transforming {}.", value);
       }
   ```
   
   You need to either to pass `Logger` as parameter to the utility class:
   
   ```java
   public final class MyUtil {
       public static String transform(String value, Logger log) {
           log.debug("Transforming {}.", value);
       }
   ```
   
   or replace static methods with instance methods:
   
   ```java
   public final class MyUtil {
       private final Logger log = LoggerFactory.getLogger(MyUtil.class);
   
       public String transform(String value) {
           log.debug("Transforming {}.", value);
       }
   ```
   
   
   **Remark**: If you want to emulate Logback's behavior, you can also set the 
[`log4j2.contextSelector` configuration 
property](https://logging.staged.apache.org/log4j/2.x/manual/systemproperties.html#log4j2.contextSelector)
 to `org.apache.logging.log4j.core.selector.BasicContextSelector`. There will 
be a single logger context for the entire application, so the caller lookup 
will not be necessary.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to