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 2015/12/23 14:38:41 UTC
[02/11] logging-log4j2 git commit: LOG4J2-1080 factory that creates
AsyncEventLogger implementations based on system properties
LOG4J2-1080 factory that creates AsyncEventLogger implementations based on system properties
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/f04e0cf1
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/f04e0cf1
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/f04e0cf1
Branch: refs/heads/master
Commit: f04e0cf172cf2bbe833fef177b8e6111219ea29a
Parents: a55fe82
Author: rpopma <rp...@apache.org>
Authored: Wed Dec 23 22:05:42 2015 +0900
Committer: rpopma <rp...@apache.org>
Committed: Wed Dec 23 22:05:42 2015 +0900
----------------------------------------------------------------------
.../core/async/AsyncEventRouterFactory.java | 117 +++++++++++++++++++
1 file changed, 117 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/f04e0cf1/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncEventRouterFactory.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncEventRouterFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncEventRouterFactory.java
new file mode 100644
index 0000000..f2ef388
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncEventRouterFactory.java
@@ -0,0 +1,117 @@
+/*
+ * 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.Level;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.PropertiesUtil;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * Creates {@link AsyncEventRouter} instances based on user-specified system properties. The {@code AsyncEventRouter}
+ * created by this factory is used in AsyncLogger, AsyncLoggerConfig and AsyncAppender
+ * to control if events are logged in the current thread, the background thread, or discarded.
+ * <p>
+ * Property {@code "log4j2.AsyncEventRouter"} controls the routing behaviour. If this property is not specified or has
+ * value {@code "Default"}, this factory creates {@link DefaultAsyncEventRouter} objects.
+ * </p> <p>
+ * If this property has value {@code "Discard"}, this factory creates {@link DiscardingAsyncEventRouter} objects.
+ * By default, this router discards events of level {@code INFO}, {@code DEBUG} and {@code TRACE} if the queue is at
+ * 80% capacity or more. This can be adjusted with properties {@code "log4j2.DiscardQueueRatio"} (must be a float
+ * between 0.0 and 1.0) and {@code "log4j2.DiscardThreshold"} (name of the level at which to start discarding).
+ * </p> <p>
+ * For any other value, this
+ * factory interprets the value as the fully qualified name of a class implementing the {@link AsyncEventRouter}
+ * interface. If a constructor with a single {@code int} argument exists, this constructor is invoked with the queue
+ * size, otherwise the default constructor is called.
+ * </p>
+ *
+ * @since 2.5.1
+ */
+public class AsyncEventRouterFactory {
+ static final String PROPERTY_NAME_ASYNC_EVENT_ROUTER = "log4j2.AsyncEventRouter";
+ static final String PROPERTY_VALUE_DEFAULT_ASYNC_EVENT_ROUTER = "Default";
+ static final String PROPERTY_VALUE_DISCARDING_ASYNC_EVENT_ROUTER = "Discard";
+ static final String PROPERTY_NAME_DISCARDING_QUEUE_RATIO = "log4j2.DiscardQueueRatio";
+ static final String PROPERTY_NAME_DISCARDING_THRESHOLD_LEVEL = "log4j2.DiscardThreshold";
+
+ private static final Logger LOGGER = StatusLogger.getLogger();
+
+ /**
+ * Creates and returns {@link AsyncEventRouter} instances based on user-specified system properties.
+ * <p>
+ * Property {@code "log4j2.AsyncEventRouter"} controls the routing behaviour. If this property is not specified or
+ * has value {@code "Default"}, this method returns {@link DefaultAsyncEventRouter} objects.
+ * </p> <p>
+ * If this property has value {@code "Discard"}, this method returns {@link DiscardingAsyncEventRouter} objects.
+ * </p> <p>
+ * For any other value, this method interprets the value as the fully qualified name of a class implementing the
+ * {@link AsyncEventRouter} interface. If a constructor with a single {@code int} argument exists, this constructor
+ * is invoked with the queue size, otherwise the default constructor is called.
+ * </p>
+ *
+ * @param queueSize the queue size
+ * @return a new AsyncEventRouter
+ */
+ public static AsyncEventRouter create(final int queueSize) {
+ final String router = PropertiesUtil.getProperties().getStringProperty(PROPERTY_NAME_ASYNC_EVENT_ROUTER);
+ if (router == null || PROPERTY_VALUE_DEFAULT_ASYNC_EVENT_ROUTER.equals(router)
+ || DefaultAsyncEventRouter.class.getSimpleName().equals(router)
+ || DefaultAsyncEventRouter.class.getName().equals(router)) {
+ return new DefaultAsyncEventRouter();
+ }
+ if (PROPERTY_VALUE_DISCARDING_ASYNC_EVENT_ROUTER.equals(router)
+ || DiscardingAsyncEventRouter.class.getSimpleName().equals(router)
+ || DiscardingAsyncEventRouter.class.getName().equals(router)) {
+ return createDiscardingAsyncEventRouter(queueSize);
+ }
+ return createCustomRouter(router, queueSize);
+ }
+
+ private static AsyncEventRouter createCustomRouter(final String router, final int queueSize) {
+ try {
+ @SuppressWarnings("unchecked")
+ final Class<AsyncEventRouter> cls = (Class<AsyncEventRouter>) Class.forName(router);
+ try {
+ // if the custom router has a constructor taking an int, pass it the queue size
+ Constructor<AsyncEventRouter> constructor = cls.getDeclaredConstructor(new Class[]{int.class});
+ LOGGER.debug("Creating custom AsyncEventRouter '{}({})'", router, queueSize);
+ return constructor.newInstance(new Object[]{queueSize});
+ } catch (final Exception e) {
+ // otherwise we try the default constructor
+ LOGGER.debug("Creating custom AsyncEventRouter '{}'", router);
+ return cls.newInstance();
+ }
+ } catch (final Exception ex) {
+ LOGGER.debug("Using DefaultAsyncEventRouter. Could not create custom AsyncEventRouter '{}': {}", router,
+ ex.toString());
+ return new DefaultAsyncEventRouter();
+ }
+ }
+
+ private static AsyncEventRouter createDiscardingAsyncEventRouter(final int queueSize) {
+ final PropertiesUtil util = PropertiesUtil.getProperties();
+ final float ratio = (float) util.getDoubleProperty(PROPERTY_NAME_DISCARDING_QUEUE_RATIO, 0.8);
+ final String level = util.getStringProperty(PROPERTY_NAME_DISCARDING_THRESHOLD_LEVEL, Level.INFO.name());
+ final Level thresholdLevel = Level.toLevel(level, Level.INFO);
+ LOGGER.debug("Creating custom DiscardingAsyncEventRouter(discardThreshold:{}, discardRatio:{})", thresholdLevel,
+ ratio);
+ return new DiscardingAsyncEventRouter(queueSize, ratio, thresholdLevel);
+ }
+}