Author: rpopma
Date: Thu Feb 6 13:48:54 2014
New Revision: 1565254
URL: http://svn.apache.org/r1565254
Log:
LOG4J2-511, LOG4J2-392 stop AsyncLoggerConfigs, AsyncAppenders first before
other appenders
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/BaseConfiguration.java
logging/log4j/log4j2/trunk/src/changes/changes.xml
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java?rev=1565254&r1=1565253&r2=1565254&view=diff
==============================================================================
---
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java
(original)
+++
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java
Thu Feb 6 13:48:54 2014
@@ -295,6 +295,9 @@ public class AsyncLogger extends Logger
// Must guarantee that publishing to the RingBuffer has stopped
// before we call disruptor.shutdown()
disruptor = null; // client code fails with NPE if log after stop = OK
+ if (temp == null) {
+ return; // stop() has already been called
+ }
temp.shutdown();
// wait up to 10 seconds for the ringbuffer to drain
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/BaseConfiguration.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/BaseConfiguration.java?rev=1565254&r1=1565253&r2=1565254&view=diff
==============================================================================
---
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/BaseConfiguration.java
(original)
+++
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/BaseConfiguration.java
Thu Feb 6 13:48:54 2014
@@ -23,19 +23,25 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.appender.AsyncAppender;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
+import org.apache.logging.log4j.core.async.AsyncLoggerConfig;
+import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
import org.apache.logging.log4j.core.config.plugins.PluginAliases;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
@@ -48,12 +54,15 @@ import org.apache.logging.log4j.core.con
import org.apache.logging.log4j.core.filter.AbstractFilterable;
import org.apache.logging.log4j.core.helpers.Constants;
import org.apache.logging.log4j.core.helpers.NameUtil;
+import org.apache.logging.log4j.core.impl.Log4jContextFactory;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.apache.logging.log4j.core.lookup.Interpolator;
import org.apache.logging.log4j.core.lookup.MapLookup;
import org.apache.logging.log4j.core.lookup.StrLookup;
import org.apache.logging.log4j.core.lookup.StrSubstitutor;
import org.apache.logging.log4j.core.net.Advertiser;
+import org.apache.logging.log4j.core.selector.ContextSelector;
+import org.apache.logging.log4j.spi.LoggerContextFactory;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.PropertiesUtil;
@@ -170,19 +179,60 @@ public class BaseConfiguration extends A
*/
@Override
public void stop() {
+
+ // LOG4J2-392 first stop AsyncLogger Disruptor thread
+ final LoggerContextFactory factory = LogManager.getFactory();
+ if (factory instanceof Log4jContextFactory) {
+ ContextSelector selector = ((Log4jContextFactory)
factory).getSelector();
+ if (selector instanceof AsyncLoggerContextSelector) { // all
loggers are async
+ // TODO until LOG4J2-493 is fixed we can only stop AsyncLogger
once!
+ // but LoggerContext.setConfiguration will call config.stop()
+ // every time the configuration changes...
+ //
+ // Uncomment the line below after LOG4J2-493 is fixed
+ //AsyncLogger.stop();
+ }
+ }
+ // similarly, first stop AsyncLoggerConfig Disruptor thread(s)
+ Set<LoggerConfig> alreadyStopped = new HashSet<LoggerConfig>();
+ for (final LoggerConfig logger : loggers.values()) {
+ if (logger instanceof AsyncLoggerConfig) {
+ logger.clearAppenders();
+ logger.stopFilter();
+ alreadyStopped.add(logger);
+ }
+ }
+ if (root instanceof AsyncLoggerConfig) {
+ root.stopFilter();
+ alreadyStopped.add(root);
+ }
+
// Stop the appenders in reverse order in case they still have
activity.
final Appender[] array = appenders.values().toArray(new
Appender[appenders.size()]);
+
+ // LOG4J2-511, LOG4J2-392 stop AsyncAppenders first
+ for (int i = array.length - 1; i >= 0; --i) {
+ if (array[i] instanceof AsyncAppender) {
+ array[i].stop();
+ }
+ }
for (int i = array.length - 1; i >= 0; --i) {
- array[i].stop();
+ if (array[i].isStarted()) { // then stop remaining Appenders
+ array[i].stop();
+ }
}
for (final LoggerConfig logger : loggers.values()) {
+ if (alreadyStopped.contains(logger)) {
+ continue;
+ }
logger.clearAppenders();
logger.stopFilter();
}
- root.stopFilter();
+ if (!alreadyStopped.contains(root)) {
+ root.stopFilter();
+ }
stopFilter();
- if (advertiser != null && advertisement != null)
- {
+ if (advertiser != null && advertisement != null) {
advertiser.unadvertise(advertisement);
}
}
Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/changes/changes.xml?rev=1565254&r1=1565253&r2=1565254&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/changes/changes.xml (original)
+++ logging/log4j/log4j2/trunk/src/changes/changes.xml Thu Feb 6 13:48:54 2014
@@ -21,6 +21,14 @@
</properties>
<body>
<release version="2.0-RC1" date="2014-MM-DD" description="Bug fixes and
enhancements">
+ <action issue="LOG4J2-511" dev="rpopma" type="fix" due-to="James
Pretorius">
+ Stop AsyncLoggerConfig Disruptor thread(s), then AsyncAppender
thread(s) first
+ before stopping other appenders.
+ </action>
+ <action issue="LOG4J2-392" dev="rpopma" type="fix" due-to="ilynaf, Andre
Bogus">
+ Stop AsyncLoggerConfig Disruptor thread(s), then AsyncAppender
thread(s) first
+ before stopping other appenders.
+ </action>
<action issue="LOG4J2-345" dev="rpopma" type="fix" due-to="Roland
Weiglhofer, Matt Sicker">
(OSGi) logging.log4j-1.2-api doesn't export the log4j API 1.2.
Dependent bundles can not be resolved.
</action>