Repository: logging-log4j2 Updated Branches: refs/heads/master e27c5b5ba -> d329cf38a
LOG4J2-938 To avoid memory leaks when web applications are restarted, JMX notifications are sent from the caller thread in web applications. For non-web applications notifications are sent from a background thread as before. Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/d329cf38 Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/d329cf38 Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/d329cf38 Branch: refs/heads/master Commit: d329cf38aa7ccffde137ed53443d909dd18efd49 Parents: e27c5b5 Author: rpopma <[email protected]> Authored: Sun Feb 22 23:02:59 2015 +0900 Committer: rpopma <[email protected]> Committed: Sun Feb 22 23:02:59 2015 +0900 ---------------------------------------------------------------------- .../apache/logging/log4j/core/jmx/Server.java | 27 +++++++++++++++++++- src/changes/changes.xml | 5 ++++ src/site/xdoc/manual/configuration.xml.vm | 10 ++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d329cf38/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java index 92a19a3..54eb214 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.management.InstanceAlreadyExistsException; @@ -40,6 +41,7 @@ import org.apache.logging.log4j.core.async.DaemonThreadFactory; import org.apache.logging.log4j.core.config.LoggerConfig; import org.apache.logging.log4j.core.impl.Log4jContextFactory; import org.apache.logging.log4j.core.selector.ContextSelector; +import org.apache.logging.log4j.core.util.Loader; import org.apache.logging.log4j.spi.LoggerContextFactory; import org.apache.logging.log4j.status.StatusLogger; import org.apache.logging.log4j.util.PropertiesUtil; @@ -57,13 +59,36 @@ public final class Server { */ public static final String DOMAIN = "org.apache.logging.log4j2"; private static final String PROPERTY_DISABLE_JMX = "log4j2.disable.jmx"; + private static final String PROPERTY_ASYNC_NOTIF = "log4j2.jmx.notify.async"; + private static final String THREAD_NAME_PREFIX = "log4j2.jmx.notif"; private static final StatusLogger LOGGER = StatusLogger.getLogger(); - static final Executor executor = Executors.newFixedThreadPool(1, new DaemonThreadFactory("log4j2.jmx.notif")); + static final Executor executor = createExecutor(); private Server() { } /** + * Returns either a {@code null} Executor (causing JMX notifications to be sent from the caller thread) or a daemon + * background thread Executor, depending on the value of system property "log4j2.jmx.notify.async". If this + * property is not set, use a {@code null} Executor for web apps to avoid memory leaks and other issues when the + * web app is restarted. + * @see LOG4J2-938 + */ + private static ExecutorService createExecutor() { + boolean defaultAsync = !isWebApp(); + boolean async = PropertiesUtil.getProperties().getBooleanProperty(PROPERTY_ASYNC_NOTIF, defaultAsync); + return async ? Executors.newFixedThreadPool(1, new DaemonThreadFactory(THREAD_NAME_PREFIX)) : null; + } + + /** + * Returns {@code true} if we think we are running in a web container, based on the presence of the + * {@code javax.servlet.Servlet} class in the classpath. + */ + private static boolean isWebApp() { + return Loader.isClassAvailable("javax.servlet.Servlet"); + } + + /** * Either returns the specified name as is, or returns a quoted value containing the specified name with the special * characters (comma, equals, colon, quote, asterisk, or question mark) preceded with a backslash. * http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d329cf38/src/changes/changes.xml ---------------------------------------------------------------------- diff --git a/src/changes/changes.xml b/src/changes/changes.xml index ab11c0c..2bd8b73 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -24,6 +24,11 @@ </properties> <body> <release version="2.2" date="2015-??-??" description="GA Release 2.2"> + <action issue="LOG4J2-938" dev="rpopma" type="fix" due-to="Mauro Molinari"> + (JMX) To avoid memory leaks when web applications are restarted, JMX notifications are sent from + the caller thread in web applications. For non-web applications notifications are sent from a background thread + as before. + </action> <action issue="LOG4J2-957" dev="ggregory" type="fix" due-to="fatih guleryuz"> Missing toUpperCase("Locale.ENGLISH"). </action> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d329cf38/src/site/xdoc/manual/configuration.xml.vm ---------------------------------------------------------------------- diff --git a/src/site/xdoc/manual/configuration.xml.vm b/src/site/xdoc/manual/configuration.xml.vm index feeab2f..7165900 100644 --- a/src/site/xdoc/manual/configuration.xml.vm +++ b/src/site/xdoc/manual/configuration.xml.vm @@ -1424,6 +1424,16 @@ public class AwesomeTest { </td> </tr> <tr> + <td>log4j2.jmx.notify.async</td> + <td>false for web apps, true otherwise</td> + <td> + If <tt>true</tt>, log4j's JMX notifications are sent from a separate background thread, + otherwise they are sent from the caller thread. + If the <tt>javax.servlet.Servlet</tt> class is on the classpath, the default behaviour + is to use the caller thread to send JMX notifications. + </td> + </tr> + <tr> <td>log4j.skipJansi</td> <td>false</td> <td>
