You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rp...@apache.org on 2022/04/26 09:31:17 UTC
[logging-log4j2] branch master updated (3d1592895a -> 37566b67f1)
This is an automated email from the ASF dual-hosted git repository.
rpopma pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
from 3d1592895a LOG4J2-3472 (master) make disruptor WaitStrategy configurable in Log4j configuration (#830)
new 543863b158 LOG4J2-3473 (master) make default WaitStrategy garbage-free
new c30f09318d LOG4J2-3472 (master) disable flaky test
new 37566b67f1 LOG4J2-3472 (master) re-enable flaky test
The 3 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:
NOTICE.txt | 3 +
.../async/AsyncWaitStrategyFactoryConfigTest.java | 1 -
...egyFactoryIncorrectConfigGlobalLoggersTest.java | 1 -
.../async/DefaultAsyncWaitStrategyFactory.java | 1 -
.../logging/log4j/core/async/DisruptorUtil.java | 5 -
.../core/async/TimeoutBlockingWaitStrategy.java | 135 +++++++++++++++++++++
src/site/asciidoc/manual/garbagefree.adoc | 5 +-
7 files changed, 142 insertions(+), 9 deletions(-)
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/async/TimeoutBlockingWaitStrategy.java
[logging-log4j2] 03/03: LOG4J2-3472 (master) re-enable flaky test
Posted by rp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rpopma pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 37566b67f1352b48f7953a2f20115c7981472919
Author: Remko Popma <re...@yahoo.com>
AuthorDate: Tue Apr 26 18:30:51 2022 +0900
LOG4J2-3472 (master) re-enable flaky test
---
.../java/org/apache/logging/log4j/core/config/xml/XmlSchemaTest.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/xml/XmlSchemaTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/xml/XmlSchemaTest.java
index 0020a10fbc..fa1ffd8433 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/xml/XmlSchemaTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/xml/XmlSchemaTest.java
@@ -39,7 +39,6 @@ import javax.xml.validation.Validator;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.mutable.MutableInt;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
@@ -90,7 +89,6 @@ public class XmlSchemaTest {
return xml;
}
- @Disabled
@Test
public void testXmlSchemaValidation() throws SAXException, IOException {
final SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
[logging-log4j2] 02/03: LOG4J2-3472 (master) disable flaky test
Posted by rp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rpopma pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit c30f09318deef97d97d4c9f0e9c82cf9a86546bd
Author: Remko Popma <re...@yahoo.com>
AuthorDate: Tue Apr 26 17:51:00 2022 +0900
LOG4J2-3472 (master) disable flaky test
---
.../java/org/apache/logging/log4j/core/config/xml/XmlSchemaTest.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/xml/XmlSchemaTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/xml/XmlSchemaTest.java
index fa1ffd8433..0020a10fbc 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/xml/XmlSchemaTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/xml/XmlSchemaTest.java
@@ -39,6 +39,7 @@ import javax.xml.validation.Validator;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.mutable.MutableInt;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
@@ -89,6 +90,7 @@ public class XmlSchemaTest {
return xml;
}
+ @Disabled
@Test
public void testXmlSchemaValidation() throws SAXException, IOException {
final SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
[logging-log4j2] 01/03: LOG4J2-3473 (master) make default WaitStrategy garbage-free
Posted by rp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rpopma pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 543863b158464fa7cedb8bb2e10334be6ae1e55d
Author: Remko Popma <re...@yahoo.com>
AuthorDate: Tue Apr 26 17:33:48 2022 +0900
LOG4J2-3473 (master) make default WaitStrategy garbage-free
add garbage-free version of TimeoutBlockingWaitStrategy and make this the default Async Loggers WaitStrategy
---
NOTICE.txt | 3 +
.../async/AsyncWaitStrategyFactoryConfigTest.java | 1 -
...egyFactoryIncorrectConfigGlobalLoggersTest.java | 1 -
.../async/DefaultAsyncWaitStrategyFactory.java | 1 -
.../logging/log4j/core/async/DisruptorUtil.java | 5 -
.../core/async/TimeoutBlockingWaitStrategy.java | 135 +++++++++++++++++++++
src/site/asciidoc/manual/garbagefree.adoc | 5 +-
7 files changed, 142 insertions(+), 9 deletions(-)
diff --git a/NOTICE.txt b/NOTICE.txt
index a241a12d0e..922a1c7046 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -15,3 +15,6 @@ Copyright 2002-2012 Ramnivas Laddad, Juergen Hoeller, Chris Beams
picocli (http://picocli.info)
Copyright 2017 Remko Popma
+
+TimeoutBlockingWaitStrategy.java and parts of Util.java
+Copyright 2011 LMAX Ltd.
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactoryConfigTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactoryConfigTest.java
index b27de0c15c..afe08bf49f 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactoryConfigTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactoryConfigTest.java
@@ -16,7 +16,6 @@
*/
package org.apache.logging.log4j.core.async;
-import com.lmax.disruptor.TimeoutBlockingWaitStrategy;
import com.lmax.disruptor.WaitStrategy;
import com.lmax.disruptor.YieldingWaitStrategy;
import org.apache.logging.log4j.core.LoggerContext;
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactoryIncorrectConfigGlobalLoggersTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactoryIncorrectConfigGlobalLoggersTest.java
index 7adc8b85d5..86b8913daa 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactoryIncorrectConfigGlobalLoggersTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactoryIncorrectConfigGlobalLoggersTest.java
@@ -16,7 +16,6 @@
*/
package org.apache.logging.log4j.core.async;
-import com.lmax.disruptor.TimeoutBlockingWaitStrategy;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.test.categories.AsyncLoggers;
import org.apache.logging.log4j.core.LoggerContext;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DefaultAsyncWaitStrategyFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DefaultAsyncWaitStrategyFactory.java
index bbe3af696a..a5c54ae4ed 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DefaultAsyncWaitStrategyFactory.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DefaultAsyncWaitStrategyFactory.java
@@ -19,7 +19,6 @@ package org.apache.logging.log4j.core.async;
import com.lmax.disruptor.BlockingWaitStrategy;
import com.lmax.disruptor.BusySpinWaitStrategy;
import com.lmax.disruptor.SleepingWaitStrategy;
-import com.lmax.disruptor.TimeoutBlockingWaitStrategy;
import com.lmax.disruptor.WaitStrategy;
import com.lmax.disruptor.YieldingWaitStrategy;
import org.apache.logging.log4j.Logger;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorUtil.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorUtil.java
index e37f45473a..200686c672 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorUtil.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorUtil.java
@@ -22,13 +22,8 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
-import com.lmax.disruptor.BlockingWaitStrategy;
-import com.lmax.disruptor.BusySpinWaitStrategy;
import com.lmax.disruptor.ExceptionHandler;
-import com.lmax.disruptor.SleepingWaitStrategy;
-import com.lmax.disruptor.TimeoutBlockingWaitStrategy;
import com.lmax.disruptor.WaitStrategy;
-import com.lmax.disruptor.YieldingWaitStrategy;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.util.Constants;
import org.apache.logging.log4j.core.util.Integers;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/TimeoutBlockingWaitStrategy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/TimeoutBlockingWaitStrategy.java
new file mode 100644
index 0000000000..804e9c901d
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/TimeoutBlockingWaitStrategy.java
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+
+// Where the above is the copyright notice of the derivate work,
+// below is the copyright notice of the original source of this work:
+/*
+ * Copyright 2011 LMAX Ltd.
+ *
+ * Licensed 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 com.lmax.disruptor.AlertException;
+import com.lmax.disruptor.Sequence;
+import com.lmax.disruptor.SequenceBarrier;
+import com.lmax.disruptor.TimeoutException;
+import com.lmax.disruptor.WaitStrategy;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Blocking strategy that uses a lock and condition variable for {@link EventProcessor}s waiting on a barrier.
+ * However, it will periodically wake up if it has been idle for specified period by throwing a
+ * {@link TimeoutException}. To make use of this, the event handler class should override
+ * {@link EventHandler#onTimeout(long)}, which the {@link BatchEventProcessor} will call if the timeout occurs.
+ *
+ * <p>This strategy can be used when throughput and low-latency are not as important as CPU resource.
+ */
+// IMPLEMENTATION NOTE:
+// This is a copy of the com.lmax.disruptor.TimeoutBlockingWaitStrategy class in disruptor-4.0.0-RC1.
+// The difference between this code and the implementation of this class in disruptor-3.4.4
+// is that this class is garbage-free, because it uses a synchronized block instead of a ReentrantLock.
+// This class is package-protected, so that it can be used internally as the default WaitStrategy
+// by Log4j Async Loggers, but can be removed in a future Log4j release without impacting binary compatibility.
+// (disruptor-4.0.0-RC1 requires Java 11 and has other incompatible changes so cannot be used in Log4j 2.x.)
+class TimeoutBlockingWaitStrategy implements WaitStrategy {
+ private final Object mutex = new Object();
+ private final long timeoutInNanos;
+
+ /**
+ * @param timeout how long to wait before waking up
+ * @param units the unit in which timeout is specified
+ */
+ public TimeoutBlockingWaitStrategy(final long timeout, final TimeUnit units) {
+ timeoutInNanos = units.toNanos(timeout);
+ }
+
+ @Override
+ public long waitFor(
+ final long sequence,
+ final Sequence cursorSequence,
+ final Sequence dependentSequence,
+ final SequenceBarrier barrier)
+ throws AlertException, InterruptedException, TimeoutException {
+ long timeoutNanos = timeoutInNanos;
+
+ long availableSequence;
+ if (cursorSequence.get() < sequence) {
+ synchronized (mutex) {
+ while (cursorSequence.get() < sequence) {
+ barrier.checkAlert();
+ timeoutNanos = awaitNanos(mutex, timeoutNanos);
+ if (timeoutNanos <= 0) {
+ throw TimeoutException.INSTANCE;
+ }
+ }
+ }
+ }
+
+ while ((availableSequence = dependentSequence.get()) < sequence) {
+ barrier.checkAlert();
+ }
+
+ return availableSequence;
+ }
+
+ @Override
+ public void signalAllWhenBlocking() {
+ synchronized (mutex) {
+ mutex.notifyAll();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "TimeoutBlockingWaitStrategy{" +
+ "mutex=" + mutex +
+ ", timeoutInNanos=" + timeoutInNanos +
+ '}';
+ }
+
+ // below code is from com.lmax.disruptor.util.Util class in disruptor 4.0.0-RC1
+ private static final int ONE_MILLISECOND_IN_NANOSECONDS = 1_000_000;
+
+ /**
+ * @param mutex The object to wait on
+ * @param timeoutNanos The number of nanoseconds to wait for
+ * @return the number of nanoseconds waited (approximately)
+ * @throws InterruptedException if the underlying call to wait is interrupted
+ */
+ private static long awaitNanos(final Object mutex, final long timeoutNanos) throws InterruptedException {
+ long millis = timeoutNanos / ONE_MILLISECOND_IN_NANOSECONDS;
+ long nanos = timeoutNanos % ONE_MILLISECOND_IN_NANOSECONDS;
+
+ long t0 = System.nanoTime();
+ mutex.wait(millis, (int) nanos);
+ long t1 = System.nanoTime();
+
+ return timeoutNanos - (t1 - t0);
+ }
+}
diff --git a/src/site/asciidoc/manual/garbagefree.adoc b/src/site/asciidoc/manual/garbagefree.adoc
index 2dc2b74d81..9ae92a189c 100644
--- a/src/site/asciidoc/manual/garbagefree.adoc
+++ b/src/site/asciidoc/manual/garbagefree.adoc
@@ -100,9 +100,12 @@ NOTE: As of version 2.6, a Log4j configuration containing a
`<Properties>` section will result in temporary objects being created
during steady-state logging.
-NOTE: The Async Logger Timeout wait strategy (the default) and the Block wait strategy
+NOTE: as of version 2.17.3, the default Async Logger wait strategy used by Log4j
+(Timeout) is garbage-free. Some of the wait strategies included in LMAX disruptor 3.4.4,
+especially `TimeoutBlockingWaitStrategy` and `BlockingWaitStrategy` (Block)
are not garbage-free since they
cause `java.util.concurrent.locks.AbstractQueuedSynchronizer$Node` objects to be created.
+The default wait strategy used by Log4j uses a synchronized block instead of a ReentrantLock to avoid this problem.
The Yield and Sleep wait strategies are garbage-free. (For configuring predefined wait strategies, see
link:async.html#SysPropsAllAsync[here] and
link:async.html#SysPropsMixedSync-Async[here],