Convert BlockingQueueFactory into a plugin element Related to LOG4J2-1430.
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/65ec9bce Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/65ec9bce Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/65ec9bce Branch: refs/heads/master Commit: 65ec9bcef74dc30ecab9c2091c6e0638d53490d8 Parents: 0848d7a Author: Matt Sicker <boa...@gmail.com> Authored: Fri Jun 17 18:51:08 2016 -0500 Committer: Matt Sicker <boa...@gmail.com> Committed: Fri Jun 17 18:51:08 2016 -0500 ---------------------------------------------------------------------- .../log4j/core/appender/AsyncAppender.java | 24 +++++++++--- .../core/async/ArrayBlockingQueueFactory.java | 10 +++++ .../log4j/core/async/BlockingQueueFactory.java | 13 ++++++- .../async/DisruptorBlockingQueueFactory.java | 11 +++++- .../core/async/LinkedTransferQueueFactory.java | 10 +++++ .../log4j/core/appender/AsyncAppenderTest.java | 16 ++++---- .../BlockingQueueFactory-ArrayBlockingQueue.xml | 40 ++++++++++++++++++++ ...ckingQueueFactory-DisruptorBlockingQueue.xml | 40 ++++++++++++++++++++ ...BlockingQueueFactory-LinkedTransferQueue.xml | 40 ++++++++++++++++++++ 9 files changed, 189 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/65ec9bce/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AsyncAppender.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AsyncAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AsyncAppender.java index 3c9c37c..dee5e50 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AsyncAppender.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AsyncAppender.java @@ -26,8 +26,11 @@ import org.apache.logging.log4j.core.AbstractLogEvent; import org.apache.logging.log4j.core.Appender; import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.async.ArrayBlockingQueueFactory; import org.apache.logging.log4j.core.async.AsyncQueueFullPolicy; import org.apache.logging.log4j.core.async.AsyncQueueFullPolicyFactory; +import org.apache.logging.log4j.core.async.BlockingQueueFactory; +import org.apache.logging.log4j.core.async.BlockingQueueFactoryUtil; import org.apache.logging.log4j.core.async.DiscardingAsyncQueueFullPolicy; import org.apache.logging.log4j.core.async.EventRoute; import org.apache.logging.log4j.core.config.AppenderControl; @@ -42,7 +45,6 @@ import org.apache.logging.log4j.core.config.plugins.PluginConfiguration; import org.apache.logging.log4j.core.config.plugins.PluginElement; import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required; import org.apache.logging.log4j.core.impl.Log4jLogEvent; -import org.apache.logging.log4j.core.async.BlockingQueueFactoryUtil; import org.apache.logging.log4j.core.util.Constants; /** @@ -73,8 +75,8 @@ public final class AsyncAppender extends AbstractAppender { private AsyncAppender(final String name, final Filter filter, final AppenderRef[] appenderRefs, final String errorRef, final int queueSize, final boolean blocking, - final boolean ignoreExceptions, - final long shutdownTimeout, final Configuration config, final boolean includeLocation) { + final boolean ignoreExceptions, final long shutdownTimeout, final Configuration config, + final boolean includeLocation, final BlockingQueueFactory<LogEvent> blockingQueueFactory) { super(name, filter, null, ignoreExceptions); this.queue = BlockingQueueFactoryUtil.<LogEvent>getBlockingQueueFactory().create(queueSize); this.queueSize = queueSize; @@ -217,7 +219,9 @@ public final class AsyncAppender extends AbstractAppender { } /** - * Create an AsyncAppender. + * Create an AsyncAppender. This method is retained for backwards compatibility. New code should use the + * {@link Builder} instead. This factory will use {@link ArrayBlockingQueueFactory} by default as was the behavior + * pre-2.7. * * @param appenderRefs The Appenders to reference. * @param errorRef An optional Appender to write to if the queue is full or other errors occur. @@ -247,7 +251,7 @@ public final class AsyncAppender extends AbstractAppender { } return new AsyncAppender(name, filter, appenderRefs, errorRef, size, blocking, ignoreExceptions, - shutdownTimeout, config, includeLocation); + shutdownTimeout, config, includeLocation, new ArrayBlockingQueueFactory<LogEvent>()); } @PluginBuilderFactory @@ -290,6 +294,9 @@ public final class AsyncAppender extends AbstractAppender { @PluginBuilderAttribute private boolean ignoreExceptions = true; + @PluginElement(BlockingQueueFactory.ELEMENT_TYPE) + private BlockingQueueFactory<LogEvent> blockingQueueFactory = new ArrayBlockingQueueFactory<>(); + public Builder setAppenderRefs(AppenderRef[] appenderRefs) { this.appenderRefs = appenderRefs; return this; @@ -340,10 +347,15 @@ public final class AsyncAppender extends AbstractAppender { return this; } + public Builder setBlockingQueueFactory(final BlockingQueueFactory<LogEvent> blockingQueueFactory) { + this.blockingQueueFactory = blockingQueueFactory; + return this; + } + @Override public AsyncAppender build() { return new AsyncAppender(name, filter, appenderRefs, errorRef, bufferSize, blocking, ignoreExceptions, - shutdownTimeout, configuration, includeLocation); + shutdownTimeout, configuration, includeLocation, blockingQueueFactory); } } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/65ec9bce/log4j-core/src/main/java/org/apache/logging/log4j/core/async/ArrayBlockingQueueFactory.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/ArrayBlockingQueueFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/ArrayBlockingQueueFactory.java index e9c99b8..dcad78a 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/ArrayBlockingQueueFactory.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/ArrayBlockingQueueFactory.java @@ -3,14 +3,24 @@ package org.apache.logging.log4j.core.async; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; +import org.apache.logging.log4j.core.config.Node; +import org.apache.logging.log4j.core.config.plugins.Plugin; +import org.apache.logging.log4j.core.config.plugins.PluginFactory; + /** * Factory for creating instances of {@link ArrayBlockingQueue}. * * @since 2.7 */ +@Plugin(name = "ArrayBlockingQueue", category = Node.CATEGORY, elementType = BlockingQueueFactory.ELEMENT_TYPE) public class ArrayBlockingQueueFactory<E> implements BlockingQueueFactory<E> { @Override public BlockingQueue<E> create(int capacity) { return new ArrayBlockingQueue<>(capacity); } + + @PluginFactory + public static <E> ArrayBlockingQueueFactory<E> createFactory() { + return new ArrayBlockingQueueFactory<>(); + } } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/65ec9bce/log4j-core/src/main/java/org/apache/logging/log4j/core/async/BlockingQueueFactory.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/BlockingQueueFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/BlockingQueueFactory.java index ccd1625..5763d1e 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/BlockingQueueFactory.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/BlockingQueueFactory.java @@ -9,7 +9,18 @@ import java.util.concurrent.BlockingQueue; */ public interface BlockingQueueFactory<E> { - String PROPERTY = "log4j.BlockingQueueFactory"; + /** + * The {@link org.apache.logging.log4j.core.config.plugins.Plugin#elementType() element type} to use for plugins + * implementing this interface. + */ + String ELEMENT_TYPE = "BlockingQueueFactory"; + /** + * Creates a new BlockingQueue with the specified maximum capacity. Note that not all implementations of + * BlockingQueue support a bounded capacity in which case the value is ignored. + * + * @param capacity maximum size of the queue if supported + * @return a new BlockingQueue + */ BlockingQueue<E> create(int capacity); } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/65ec9bce/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorBlockingQueueFactory.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorBlockingQueueFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorBlockingQueueFactory.java index 8fb3707..add375d 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorBlockingQueueFactory.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorBlockingQueueFactory.java @@ -3,15 +3,24 @@ package org.apache.logging.log4j.core.async; import java.util.concurrent.BlockingQueue; import com.conversantmedia.util.concurrent.DisruptorBlockingQueue; +import org.apache.logging.log4j.core.config.Node; +import org.apache.logging.log4j.core.config.plugins.Plugin; +import org.apache.logging.log4j.core.config.plugins.PluginFactory; /** * Factory for creating instances of {@link DisruptorBlockingQueue}. * * @since 2.7 */ +@Plugin(name = "DisruptorBlockingQueue", category = Node.CATEGORY, elementType = BlockingQueueFactory.ELEMENT_TYPE) public class DisruptorBlockingQueueFactory<E> implements BlockingQueueFactory<E> { @Override public BlockingQueue<E> create(int capacity) { - return new DisruptorBlockingQueue<E>(capacity); + return new DisruptorBlockingQueue<>(capacity); + } + + @PluginFactory + public static <E> DisruptorBlockingQueueFactory<E> createFactory() { + return new DisruptorBlockingQueueFactory<>(); } } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/65ec9bce/log4j-core/src/main/java/org/apache/logging/log4j/core/async/LinkedTransferQueueFactory.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/LinkedTransferQueueFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/LinkedTransferQueueFactory.java index 862fab3..6ab24e7 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/LinkedTransferQueueFactory.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/LinkedTransferQueueFactory.java @@ -20,14 +20,24 @@ package org.apache.logging.log4j.core.async; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedTransferQueue; +import org.apache.logging.log4j.core.config.Node; +import org.apache.logging.log4j.core.config.plugins.Plugin; +import org.apache.logging.log4j.core.config.plugins.PluginFactory; + /** * Factory for creating instances of {@link LinkedTransferQueue}. * * @since 2.7 */ +@Plugin(name = "LinkedTransferQueue", category = Node.CATEGORY, elementType = BlockingQueueFactory.ELEMENT_TYPE) public class LinkedTransferQueueFactory<E> implements BlockingQueueFactory<E> { @Override public BlockingQueue<E> create(int capacity) { return new LinkedTransferQueue<>(); } + + @PluginFactory + public static <E> LinkedTransferQueueFactory<E> createFactory() { + return new LinkedTransferQueueFactory<>(); + } } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/65ec9bce/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java index 3066f38..076fdd0 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java @@ -41,19 +41,21 @@ import static org.junit.Assert.*; */ @RunWith(Parameterized.class) public class AsyncAppenderTest { - private static final String CONFIG = "log4j-asynch.xml"; @Parameterized.Parameters public static Object[] data() { - return new Class<?>[]{ - ArrayBlockingQueueFactory.class, - DisruptorBlockingQueueFactory.class, - LinkedTransferQueueFactory.class + return new String[]{ + // default async config uses array blocking queue + "log4j-asynch.xml", + // override default blocking queue implementations + "BlockingQueueFactory-ArrayBlockingQueue.xml", + "BlockingQueueFactory-DisruptorBlockingQueue.xml", + "BlockingQueueFactory-LinkedTransferQueue.xml" }; } - public AsyncAppenderTest(final Class<? extends BlockingQueueFactory> factory) { - context = new LoggerContextRule(CONFIG).withSystemProperty(BlockingQueueFactory.PROPERTY, factory.getName()); + public AsyncAppenderTest(final String configFileName) { + context = new LoggerContextRule(configFileName); } @Rule http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/65ec9bce/log4j-core/src/test/resources/BlockingQueueFactory-ArrayBlockingQueue.xml ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/resources/BlockingQueueFactory-ArrayBlockingQueue.xml b/log4j-core/src/test/resources/BlockingQueueFactory-ArrayBlockingQueue.xml new file mode 100644 index 0000000..e8bbfa6 --- /dev/null +++ b/log4j-core/src/test/resources/BlockingQueueFactory-ArrayBlockingQueue.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. + +--> +<Configuration status="OFF" name="ArrayBlockingQueueFactory"> + + <Appenders> + <Console name="STDOUT"> + <PatternLayout pattern="%m%n"/> + </Console> + <List name="List"> + <PatternLayout pattern="%C %M %m"/> + </List> + <Async name="Async" includeLocation="true" error-ref="STDOUT"> + <AppenderRef ref="List"/> + <ArrayBlockingQueue/> + </Async> + </Appenders> + + <Loggers> + <Root level="debug"> + <AppenderRef ref="Async"/> + </Root> + </Loggers> + +</Configuration> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/65ec9bce/log4j-core/src/test/resources/BlockingQueueFactory-DisruptorBlockingQueue.xml ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/resources/BlockingQueueFactory-DisruptorBlockingQueue.xml b/log4j-core/src/test/resources/BlockingQueueFactory-DisruptorBlockingQueue.xml new file mode 100644 index 0000000..268cca7 --- /dev/null +++ b/log4j-core/src/test/resources/BlockingQueueFactory-DisruptorBlockingQueue.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. + +--> +<Configuration status="OFF" name="DisruptorBlockingQueueFactory"> + + <Appenders> + <Console name="STDOUT"> + <PatternLayout pattern="%m%n"/> + </Console> + <List name="List"> + <PatternLayout pattern="%C %M %m"/> + </List> + <Async name="Async" includeLocation="true" error-ref="STDOUT"> + <AppenderRef ref="List"/> + <DisruptorBlockingQueue/> + </Async> + </Appenders> + + <Loggers> + <Root level="debug"> + <AppenderRef ref="Async"/> + </Root> + </Loggers> + +</Configuration> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/65ec9bce/log4j-core/src/test/resources/BlockingQueueFactory-LinkedTransferQueue.xml ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/resources/BlockingQueueFactory-LinkedTransferQueue.xml b/log4j-core/src/test/resources/BlockingQueueFactory-LinkedTransferQueue.xml new file mode 100644 index 0000000..13063d3 --- /dev/null +++ b/log4j-core/src/test/resources/BlockingQueueFactory-LinkedTransferQueue.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. + +--> +<Configuration status="OFF" name="LinkedTransferQueueFactory"> + + <Appenders> + <Console name="STDOUT"> + <PatternLayout pattern="%m%n"/> + </Console> + <List name="List"> + <PatternLayout pattern="%C %M %m"/> + </List> + <Async name="Async" includeLocation="true" error-ref="STDOUT"> + <AppenderRef ref="List"/> + <LinkedTransferQueue/> + </Async> + </Appenders> + + <Loggers> + <Root level="debug"> + <AppenderRef ref="Async"/> + </Root> + </Loggers> + +</Configuration> \ No newline at end of file