You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ck...@apache.org on 2021/03/24 19:22:43 UTC

[logging-log4j2] branch release-2.x updated (cefa593 -> 5b34274)

This is an automated email from the ASF dual-hosted git repository.

ckozak pushed a change to branch release-2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git.


    from cefa593  LOG4J2-2940: Reduce StackWalker interactions accessing an slf4j logger instance
     new 12bd5bf  LOG4J2-2940: Implement BasicAsyncLoggerContextSelector
     new 5b34274  BasicAsyncLoggerContextSelector documentation

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../BasicAsyncLoggerContextSelector.java}          |  33 +++----
 .../log4j/core/selector/CoreContextSelectors.java  |   8 +-
 .../async/BasicAsyncLoggerContextSelectorTest.java | 107 +++++++++++++++++++++
 src/changes/changes.xml                            |   5 +
 src/site/xdoc/manual/async.xml                     |  10 +-
 src/site/xdoc/manual/configuration.xml.vm          |   1 +
 6 files changed, 143 insertions(+), 21 deletions(-)
 copy log4j-core/src/main/java/org/apache/logging/log4j/core/{selector/BasicContextSelector.java => async/BasicAsyncLoggerContextSelector.java} (72%)
 create mode 100644 log4j-core/src/test/java/org/apache/logging/log4j/core/async/BasicAsyncLoggerContextSelectorTest.java

[logging-log4j2] 02/02: BasicAsyncLoggerContextSelector documentation

Posted by ck...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ckozak pushed a commit to branch release-2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit 5b34274e5555e9a76ff06b3ff0881df48189cc41
Author: Carter Kozak <ck...@apache.org>
AuthorDate: Tue Mar 23 21:33:15 2021 -0400

    BasicAsyncLoggerContextSelector documentation
---
 src/site/xdoc/manual/async.xml            | 10 +++++++---
 src/site/xdoc/manual/configuration.xml.vm |  1 +
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/site/xdoc/manual/async.xml b/src/site/xdoc/manual/async.xml
index 699ec97..e704f78 100644
--- a/src/site/xdoc/manual/async.xml
+++ b/src/site/xdoc/manual/async.xml
@@ -133,7 +133,8 @@
         <p>
           This is simplest to configure and gives the best performance. To make all loggers asynchronous,
           add the disruptor jar to the classpath and set the system property <tt>log4j2.contextSelector</tt>
-          to <tt>org.apache.logging.log4j.core.async.AsyncLoggerContextSelector</tt>.
+          to <tt>org.apache.logging.log4j.core.async.AsyncLoggerContextSelector</tt> or
+          <tt>org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector</tt>.
         </p>
         <p>
           By default, <a href="#Location">location</a> is not passed to the I/O thread by
@@ -147,6 +148,8 @@
 
 <!-- Don't forget to set system property
 -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
+or
+-Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector
      to make all loggers asynchronous. -->
 
 <Configuration status="WARN">
@@ -165,9 +168,10 @@
   </Loggers>
 </Configuration>]]></pre>
         <p>
-          When <tt>AsyncLoggerContextSelector</tt> is used to make all loggers asynchronous, make sure to use normal
+          When <tt>AsyncLoggerContextSelector</tt> or <tt>BasicAsyncLoggerContextSelector</tt> is used to make all
+          loggers asynchronous, make sure to use normal
           <tt>&lt;root&gt;</tt> and <tt>&lt;logger&gt;</tt> elements in the configuration. The
-          AsyncLoggerContextSelector will ensure that all loggers are asynchronous, using a mechanism
+          context selector will ensure that all loggers are asynchronous, using a mechanism
           that is different from what happens when you configure <tt>&lt;asyncRoot&gt;</tt>
           or <tt>&lt;asyncLogger&gt;</tt>.
           The latter elements are intended for mixing async with sync loggers. If you use both mechanisms
diff --git a/src/site/xdoc/manual/configuration.xml.vm b/src/site/xdoc/manual/configuration.xml.vm
index 72272c4..dbcae15 100644
--- a/src/site/xdoc/manual/configuration.xml.vm
+++ b/src/site/xdoc/manual/configuration.xml.vm
@@ -1740,6 +1740,7 @@ public class AwesomeTest {
       Available context selector implementation classes:<br />
     <!-- deliberately inserted spaces to allow line break -->
       <tt>org.apache.logging.log4j.core.async .AsyncLoggerContextSelector</tt> - makes <a href="async.html">all loggers asynchronous</a>.<br />
+      <tt>org.apache.logging.log4j.core.async .BasicAsyncLoggerContextSelector</tt> - makes <a href="async.html"> all loggers asynchronous using a single shared AsyncLoggerContext.<br />
       <tt>org.apache.logging.log4j.core.selector .BasicContextSelector</tt> - creates a single shared LoggerContext.<br />
       <tt>org.apache.logging.log4j.core.selector .ClassLoaderContextSelector</tt> - separate LoggerContexts for each web application.<br />
       <tt>org.apache.logging.log4j.core.selector .JndiContextSelector</tt> - use JNDI to locate each web application's LoggerContext.<br/>

[logging-log4j2] 01/02: LOG4J2-2940: Implement BasicAsyncLoggerContextSelector

Posted by ck...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ckozak pushed a commit to branch release-2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit 12bd5bf77939f276cf4bfbcb867085bf0dfdd568
Author: Carter Kozak <ck...@apache.org>
AuthorDate: Mon Mar 22 14:52:11 2021 -0400

    LOG4J2-2940: Implement BasicAsyncLoggerContextSelector
    
    The BasicAsyncLoggerContextSelector is equivalent to the
    AsyncLoggerContextSelector without ClassLoader introspection
    and associated overhead.
---
 .../async/BasicAsyncLoggerContextSelector.java     |  84 ++++++++++++++++
 .../log4j/core/selector/CoreContextSelectors.java  |   8 +-
 .../async/BasicAsyncLoggerContextSelectorTest.java | 107 +++++++++++++++++++++
 src/changes/changes.xml                            |   5 +
 4 files changed, 203 insertions(+), 1 deletion(-)

diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/BasicAsyncLoggerContextSelector.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/BasicAsyncLoggerContextSelector.java
new file mode 100644
index 0000000..90ce160
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/BasicAsyncLoggerContextSelector.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.async;
+
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.impl.ContextAnchor;
+import org.apache.logging.log4j.core.selector.ContextSelector;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Returns either this Thread's context or the default {@link AsyncLoggerContext}.
+ * Single-application instances should prefer this implementation over the {@link AsyncLoggerContextSelector}
+ * due the the reduced overhead avoiding classloader lookups.
+ */
+public class BasicAsyncLoggerContextSelector implements ContextSelector {
+
+    private static final AsyncLoggerContext CONTEXT = new AsyncLoggerContext("AsyncDefault");
+
+    @Override
+    public void shutdown(String fqcn, ClassLoader loader, boolean currentContext, boolean allContexts) {
+        LoggerContext ctx = getContext(fqcn, loader, currentContext);
+        if (ctx != null && ctx.isStarted()) {
+            ctx.stop(DEFAULT_STOP_TIMEOUT, TimeUnit.MILLISECONDS);
+        }
+    }
+
+    @Override
+    public boolean hasContext(String fqcn, ClassLoader loader, boolean currentContext) {
+        LoggerContext ctx = getContext(fqcn, loader, currentContext);
+        return ctx != null && ctx.isStarted();
+    }
+
+    @Override
+    public LoggerContext getContext(final String fqcn, final ClassLoader loader, final boolean currentContext) {
+        final LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();
+        return ctx != null ? ctx : CONTEXT;
+    }
+
+
+    @Override
+    public LoggerContext getContext(
+            final String fqcn,
+            final ClassLoader loader,
+            final boolean currentContext,
+            final URI configLocation) {
+        final LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();
+        return ctx != null ? ctx : CONTEXT;
+    }
+
+    @Override
+    public void removeContext(final LoggerContext context) {
+        // does not remove anything
+    }
+
+    @Override
+    public boolean isClassLoaderDependent() {
+        return false;
+    }
+
+    @Override
+    public List<LoggerContext> getLoggerContexts() {
+        return Collections.singletonList(CONTEXT);
+    }
+
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/CoreContextSelectors.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/CoreContextSelectors.java
index 1077e5a..2ee6b0d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/CoreContextSelectors.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/CoreContextSelectors.java
@@ -17,9 +17,15 @@
 package org.apache.logging.log4j.core.selector;
 
 import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
+import org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector;
 
 public class CoreContextSelectors {
 
-    public static final Class<?>[] CLASSES = new Class<?>[] { ClassLoaderContextSelector.class, BasicContextSelector.class, AsyncLoggerContextSelector.class };
+    public static final Class<?>[] CLASSES = new Class<?>[] {
+            ClassLoaderContextSelector.class,
+            BasicContextSelector.class,
+            AsyncLoggerContextSelector.class,
+            BasicAsyncLoggerContextSelector.class
+    };
 
 }
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/BasicAsyncLoggerContextSelectorTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/BasicAsyncLoggerContextSelectorTest.java
new file mode 100644
index 0000000..823cc3f
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/BasicAsyncLoggerContextSelectorTest.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.async;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.LifeCycle;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.util.Constants;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+@Category(AsyncLoggers.class)
+public class BasicAsyncLoggerContextSelectorTest {
+
+    private static final String FQCN = BasicAsyncLoggerContextSelectorTest.class.getName();
+
+    @BeforeClass
+    public static void beforeClass() {
+        System.setProperty(Constants.LOG4J_CONTEXT_SELECTOR,
+                BasicAsyncLoggerContextSelector.class.getName());
+    }
+
+    @AfterClass
+    public static void afterClass() {
+        System.clearProperty(Constants.LOG4J_CONTEXT_SELECTOR);
+    }
+
+    @Test
+    public void testContextReturnsAsyncLoggerContext() {
+        final BasicAsyncLoggerContextSelector selector = new BasicAsyncLoggerContextSelector();
+        final LoggerContext context = selector.getContext(FQCN, null, false);
+
+        assertTrue(context instanceof AsyncLoggerContext);
+    }
+
+    @Test
+    public void testContext2ReturnsAsyncLoggerContext() {
+        final BasicAsyncLoggerContextSelector selector = new BasicAsyncLoggerContextSelector();
+        final LoggerContext context = selector.getContext(FQCN, null, false, null);
+
+        assertTrue(context instanceof AsyncLoggerContext);
+    }
+
+    @Test
+    public void testLoggerContextsReturnsAsyncLoggerContext() {
+        final BasicAsyncLoggerContextSelector selector = new BasicAsyncLoggerContextSelector();
+
+        List<LoggerContext> list = selector.getLoggerContexts();
+        assertEquals(1, list.size());
+        assertTrue(list.get(0) instanceof AsyncLoggerContext);
+
+        selector.getContext(FQCN, null, false);
+
+        list = selector.getLoggerContexts();
+        assertEquals(1, list.size());
+        assertTrue(list.get(0) instanceof AsyncLoggerContext);
+    }
+
+    @Test
+    public void testContextNameIsAsyncDefault() {
+        final BasicAsyncLoggerContextSelector selector = new BasicAsyncLoggerContextSelector();
+        final LoggerContext context = selector.getContext(FQCN, null, false);
+        assertEquals("AsyncDefault" , context.getName());
+    }
+
+    @Test
+    public void testDependentOnClassLoader() {
+        final BasicAsyncLoggerContextSelector selector = new BasicAsyncLoggerContextSelector();
+        assertFalse(selector.isClassLoaderDependent());
+    }
+
+    @Test
+    public void testFactoryIsNotDependentOnClassLoader() {
+        assertFalse(LogManager.getFactory().isClassLoaderDependent());
+    }
+
+    @Test
+    public void testLogManagerShutdown() {
+        LoggerContext context = (LoggerContext) LogManager.getContext();
+        assertEquals(LifeCycle.State.STARTED, context.getState());
+        LogManager.shutdown();
+        assertEquals(LifeCycle.State.STOPPED, context.getState());
+    }
+}
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 13f9d7a..825222f 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -47,6 +47,11 @@
         basic context selectors to avoid the unnecessary overhead of walking the stack to
         determine the caller's ClassLoader.
       </action>
+      <action issue="LOG4J2-2940" dev="ckozak" type="add">
+        Add BasicAsyncLoggerContextSelector equivalent to AsyncLoggerContextSelector for
+        applications with a single LoggerContext. This selector avoids classloader lookup
+        overhead incurred by the existing AsyncLoggerContextSelector.
+      </action>
       <action issue="LOG4J2-3041" dev="rgoers" type="update">
         Allow a PatternSelector to be specified on GelfLayout.
       </action>