Celeral / log4j2-android

Use log4j2 logger with Android projects
Apache License 2.0
7 stars 1 forks source link

Implement a Log4j API `Provider` #2

Open ppkarwasz opened 1 week ago

ppkarwasz commented 1 week ago

Currently log4j2-android uses the log4j2.loggerContextFactory to register itself with the Log4j API. The usage of this property is deprecated since version 2.24.0 and will be removed in the future.

Please implement a Provider class and register it with ServiceLoader in a META-INF/services/org.apache.logging.log4j.spi.Provider class.

The Provider service determines both the LoggerContextFactory to use with the LogManager class and the ThreadContextMap to use with the ThreadContext class. Since the Android Log API does not handle context data, I would suggest to set the latter to NoOpThreadContextMap:


public class AndroidProvider extends Provider {
    private static final LoggerContextFactory CONTEXT_FACTORY = new AndroidLoggerContextFactory();

    public AndroidProvider() {
        // Since this provider is targeted at Android,
        // use a priority higher than those of the Log4j API implementations targeted at the JRE.
        super(25, CURRENT_VERSION);
    }

    @Override
    public LoggerContextFactory getLoggerContextFactory() {
        return CONTEXT_FACTORY;
    }

    @Override
    public ThreadContextMap getThreadContextMapInstance() {
        // Android does not provide an MDC implementation
        return NoOpThreadContextMap.INSTANCE;
    }
}
ppkarwasz commented 1 week ago

You might be probably interested in the discussion on apache/logging-log4j2#3038 and related PRs. The log4j-slf4j-impl artifact has a useless runtime log4j-core dependency. The "advantage" of this solution is that users don't need to explicitly add log4j-core to their dependencies, but this breaks the usage of other Log4j API implementations like log4j2-android.