You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@logging.apache.org by "onlineeeeee (via GitHub)" <gi...@apache.org> on 2023/12/21 07:43:44 UTC

[I] LoggerContext.selector sometimes not working (logging-log4j2)

onlineeeeee opened a new issue, #2116:
URL: https://github.com/apache/logging-log4j2/issues/2116

   I have set System.setProperty(Log4jPropertyKey.CONTEXT_SELECTOR_CLASS_NAME.getSystemKey(), AsyncLoggerContextSelector.class.getCanonicalName()); before LogManager.getLogger. 
   sometimes it work as AsyncLoggerContext, sometimes get LoggerContext.
   
   I found out that this is due to the fact that the methods returned by the JVM's getMethods do not guarantee order
   in the code org.apache.logging.log4j.plugins.di.DefaultInjector method registerBundleInstance
   c.getDeclaredMethods() is disordered, in method createMethodBindings, it getMethodName from scopes, if method defaultContextSelector before systemPropertyContextSelector init into scopes, then LogManager.getLogger while return LoggerContext, but it must be AsyncLoggerContext.
   `
   // registerBundleInstance method 
   Stream.<Class<?>>iterate(moduleClass, c -> c != Object.class, Class::getSuperclass)
                   .flatMap(c -> Stream.of(c.getDeclaredMethods()))
                   .filter(method -> AnnotationUtil.isMetaAnnotationPresent(method, FactoryType.class))
                   .forEachOrdered(method -> {
                       if (method.getDeclaringClass().equals(moduleClass) || providerMethods.stream().noneMatch(m ->
                               m.getName().equals(method.getName()) &&
                                       Arrays.equals(m.getParameterTypes(), method.getParameterTypes()))) {
                           final var bindings = createMethodBindings(bundle, method);
                           if (!bindings.isEmpty()) {
                               providerMethods.add(method);
                               bindings.forEach(binding -> merge(binding.getKey(), binding));
                           }
                       }
                   });
   
   // createMethodBindings method
   ...
   final Supplier<T> factory = getScopeForMethod(method).get(primaryKey, unscoped);
   ...
   
   // getScopeForMethod method
   final Annotation methodScope = AnnotationUtil.getMetaAnnotation(method, ScopeType.class);
   return methodScope != null ? getScope(methodScope.annotationType()) : getScopeForType(method.getReturnType());
   
   // getScope method
   public Scope getScope(final Class<? extends Annotation> scopeType) {
       return scopes.get(scopeType);
   }
   `
   
   ## Configuration
   
   **Version:** 3.0.0-alpha1
   
   **Operating system:** windows 11 22h2
   
   **JDK:** 21.0.1
   
   ## Logs
   
   ```
   [Stacktraces, errors, etc. relevant applications logs.]
   ```
   
   ## Reproduction
   
   `
   package online.charmander.log4j;
   
   import org.apache.logging.log4j.LogManager;
   import org.apache.logging.log4j.Logger;
   import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
   import org.apache.logging.log4j.core.impl.Log4jPropertyKey;
   
   public class LogAsynchronous {
   
       public static void main(String[] args) throws Exception {
           String classpath = ClassLoader.getSystemClassLoader().getResource("").getPath();
           System.setProperty(Log4jPropertyKey.CONFIG_LOCATION.getKey(), classpath + "/asynchronous/log4j2.xml");
   
           System.setProperty(Log4jPropertyKey.CONTEXT_SELECTOR_CLASS_NAME.getSystemKey(), AsyncLoggerContextSelector.class.getCanonicalName());
   
           Logger LOGGER = LogManager.getLogger(LogAsynchronous.class.getName());
   
           LOGGER.info('log');
       }
   }
   `
   `
   <?xml version="1.0" encoding="UTF-8"?>
   <Configuration name="Configuring Log4j using XML" status="debug" strict="true" monitorInterval="300">
       <Properties>
           <Property name="CHARSET">UTF-8</Property>
           <Property name="LOG_LEVEL">all</Property>
           <Property name="MAX_ROLLING_FILE_COUNT">5</Property>
           <Property name="PER_FILE_MAXIMUM_SIZE">250 M</Property>
           <Property name="PATTERN">%style{%processId %date{yyyy-MM-dd HH:mm:ss}}{magenta} %style{[%threadName(%threadId)]}{bright_blue} %highlight{[%-5level] %location %message%n}</Property>
           <Property name="FILE_PATTERN">%processId %date{yyyy-MM-dd HH:mm:ss} [%threadName(%threadId)] [%-5level] %location %message%n</Property>
           <Property name="LOG_DIRECTORY">logs/$${ctx:PROJECT_NAME:-charmander}</Property>
       </Properties>
   
       <Appenders>
           <Console name="Console" target="SYSTEM_OUT">
               <ThresholdFilter level="${LOG_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
               <PatternLayout charset="${CHARSET}" pattern="${PATTERN}"/>
           </Console>
           <RandomAccessFile name="Asynchronous" fileName="${LOG_DIRECTORY}/asynchronous.log" immediateFlush="false" append="false">
               <PatternLayout charset="${CHARSET}" pattern="${FILE_PATTERN}"/>
           </RandomAccessFile>
       </Appenders>
   
       <Loggers>
           <Root level="${LOG_LEVEL}" includeLocation="true">
               <AppenderRef ref="Console"/>
               <AppenderRef ref="Asynchronous"/>
           </Root>
       </Loggers>
   </Configuration>
   `
   


-- 
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: notifications-unsubscribe@logging.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] LoggerContext.selector sometimes not working (logging-log4j2)

Posted by "onlineeeeee (via GitHub)" <gi...@apache.org>.
onlineeeeee closed issue #2116: LoggerContext.selector sometimes not working
URL: https://github.com/apache/logging-log4j2/issues/2116


-- 
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: notifications-unsubscribe@logging.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] LoggerContext.selector sometimes not working (logging-log4j2)

Posted by "onlineeeeee (via GitHub)" <gi...@apache.org>.
onlineeeeee commented on issue #2116:
URL: https://github.com/apache/logging-log4j2/issues/2116#issuecomment-1871699253

   Thanks, i use 3.0.0-beta1 instead of, it work normal.


-- 
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: notifications-unsubscribe@logging.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] LoggerContext.selector sometimes not working (logging-log4j2)

Posted by "jvz (via GitHub)" <gi...@apache.org>.
jvz commented on issue #2116:
URL: https://github.com/apache/logging-log4j2/issues/2116#issuecomment-1869804088

   So I'm going to note that we're [removing the system properties for specifying classes](https://github.com/apache/logging-log4j2/issues/1977); you can currently register your own bundle class with a prioritized `ConfigurableInstanceFactoryPostProcessor` service class which can register the bindings ahead of time. In my `spi-cleanup` branch, I already separated the system properties bundle into its own bundle class that's registered before the default bundles class, though I'm working on removing the properties in general due to `ClassLoader` complexity. More documentation will be needed, but mimicking the existing code shouldn't be too tricky (just pick an integer less than `Integer.MAX_VALUE - 1000` such as, oh, `0`). Example of how to do this:
   
   ```java
   package com.example;
   
   import aQute.bnd.annotation.spi.ServiceProvider;
   import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
   import org.apache.logging.log4j.core.selector.ContextSelector;
   import org.apache.logging.log4j.plugins.Ordered;
   import org.apache.logging.log4j.plugins.SingletonFactory;
   import org.apache.logging.log4j.plugins.di.ConfigurableInstanceFactory;
   import org.apache.logging.log4j.plugins.di.spi.ConfigurableInstanceFactoryPostProcessor;
   
   @Ordered(0)
   @ServiceProvider(ConfigurableInstanceFactoryPostProcessor.class)
   public class AsyncLoggerContextPostProcessor implements ConfigurableInstanceFactoryPostProcessor {
       @Override
       public void postProcessFactory(final ConfigurableInstanceFactory factory) {
           factory.registerBundle(new Object() {
               @SingletonFactory
               ContextSelector asyncContextSelector() {
                   return factory.getInstance(AsyncLoggerContextSelector.class);
               }
           });
       }
   }
   ```
   
   If you're not using the same BND annotation processor thing, then instead of the `@ServiceProvider` annotation, you'll also need to add this class to either your `module-info.java` or to a `META-INF/services/org.apache.logging.log4j.plugins.di.spi.ConfigurableInstanceFactoryPostProcessor` file. The module info would be something like:
   
   ```
   provides org.apache.logging.log4j.plugins.di.spi.ConfigurableInstanceFactoryPostProcessor
       with com.example.AsyncLoggerContextPostProcessor
   ```
   
   In a future beta, I do have an easier way to register this, but it's not in beta1. However, this example will work without updates in future betas as the `Binding` class is going away in favor of a different DSL which supports scopes and dynamic bindings better.


-- 
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: notifications-unsubscribe@logging.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org