You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rg...@apache.org on 2020/06/29 00:40:32 UTC
[logging-log4j2] 02/03: LOG4J2-2867 - Obtain ContextDataProviders
asynchronously
This is an automated email from the ASF dual-hosted git repository.
rgoers pushed a commit to branch release-2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit f5392e6b87ea4829894eb0744bf1293cbc43fd99
Author: Ralph Goers <rg...@apache.org>
AuthorDate: Sun Jun 28 15:41:27 2020 -0700
LOG4J2-2867 - Obtain ContextDataProviders asynchronously
---
.../apache/logging/log4j/core/LoggerContext.java | 4 ++
.../log4j/core/impl/ThreadContextDataInjector.java | 49 +++++++++++++++++-----
.../org/apache/logging/log4j/core/LoggingTest.java | 4 +-
3 files changed, 44 insertions(+), 13 deletions(-)
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
index fe1ec01..a7e5b60 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
@@ -27,6 +27,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -43,6 +44,7 @@ import org.apache.logging.log4j.core.config.DefaultConfiguration;
import org.apache.logging.log4j.core.config.NullConfiguration;
import org.apache.logging.log4j.core.config.Reconfigurable;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
+import org.apache.logging.log4j.core.impl.ThreadContextDataInjector;
import org.apache.logging.log4j.core.jmx.Server;
import org.apache.logging.log4j.core.util.Cancellable;
import org.apache.logging.log4j.core.util.ExecutorServices;
@@ -136,6 +138,7 @@ public class LoggerContext extends AbstractLifeCycle
externalMap.put(EXTERNAL_CONTEXT_KEY, externalContext);
}
this.configLocation = configLocn;
+ CompletableFuture.runAsync(ThreadContextDataInjector::initServiceProviders);
}
/**
@@ -164,6 +167,7 @@ public class LoggerContext extends AbstractLifeCycle
} else {
configLocation = null;
}
+ CompletableFuture.runAsync(ThreadContextDataInjector::initServiceProviders);
}
public void addShutdownListener(LoggerContextShutdownAware listener) {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java
index 5ce7819..89623cd 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java
@@ -23,6 +23,8 @@ import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
@@ -52,7 +54,7 @@ import org.apache.logging.log4j.util.StringMap;
*/
public class ThreadContextDataInjector {
- private static Logger LOGGER = StatusLogger.getLogger();
+ private static final Logger LOGGER = StatusLogger.getLogger();
/**
* ContextDataProviders loaded via OSGi.
@@ -60,6 +62,38 @@ public class ThreadContextDataInjector {
public static Collection<ContextDataProvider> contextDataProviders =
new ConcurrentLinkedDeque<>();
+ private static volatile List<ContextDataProvider> serviceProviders = null;
+ private static final Lock providerLock = new ReentrantLock();
+
+ public static void initServiceProviders() {
+ if (serviceProviders == null) {
+ providerLock.lock();
+ try {
+ if (serviceProviders == null) {
+ serviceProviders = getServiceProviders();
+ }
+ } finally {
+ providerLock.unlock();
+ }
+ }
+ }
+
+ private static List<ContextDataProvider> getServiceProviders() {
+ List<ContextDataProvider> providers = new ArrayList<>();
+ for (final ClassLoader classLoader : LoaderUtil.getClassLoaders()) {
+ try {
+ for (final ContextDataProvider provider : ServiceLoader.load(ContextDataProvider.class, classLoader)) {
+ if (providers.stream().noneMatch((p) -> p.getClass().isAssignableFrom(provider.getClass()))) {
+ providers.add(provider);
+ }
+ }
+ } catch (final Throwable ex) {
+ LOGGER.debug("Unable to access Context Data Providers {}", ex.getMessage());
+ }
+ }
+ return providers;
+ }
+
/**
* Default {@code ContextDataInjector} for the legacy {@code Map<String, String>}-based ThreadContext (which is
* also the ThreadContext implementation used for web applications).
@@ -248,17 +282,10 @@ public class ThreadContextDataInjector {
}
private static List<ContextDataProvider> getProviders() {
+ initServiceProviders();
final List<ContextDataProvider> providers = new ArrayList<>(contextDataProviders);
- for (final ClassLoader classLoader : LoaderUtil.getClassLoaders()) {
- try {
- for (final ContextDataProvider provider : ServiceLoader.load(ContextDataProvider.class, classLoader)) {
- if (providers.stream().noneMatch((p) -> p.getClass().isAssignableFrom(provider.getClass()))) {
- providers.add(provider);
- }
- }
- } catch (final Throwable ex) {
- LOGGER.debug("Unable to access Context Data Providers {}", ex.getMessage());
- }
+ if (serviceProviders != null) {
+ providers.addAll(serviceProviders);
}
return providers;
}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggingTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggingTest.java
index 4491627..6664ddf 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggingTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggingTest.java
@@ -86,11 +86,11 @@ public class LoggingTest {
logger.info("This is a test");
System.out.println(timer.stop());
timer = new Timer("more", 100);
- timer.start();
+/* timer.start();
for (int i=0; i < 100; ++i) {
logger.info("This is another test");
}
- System.out.println(timer.stop());
+ System.out.println(timer.stop());*/
}
}