You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by mi...@apache.org on 2016/10/03 16:54:43 UTC
logging-log4j2 git commit: LOG4J2-1623 Configurable JVM shutdown hook
timeout
Repository: logging-log4j2
Updated Branches:
refs/heads/LOG4J2-1623 [created] 705e27253
LOG4J2-1623 Configurable JVM shutdown hook timeout
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/705e2725
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/705e2725
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/705e2725
Branch: refs/heads/LOG4J2-1623
Commit: 705e27253ca14cdf0e50039cada041065e308aee
Parents: 3176c96
Author: Mikael St�ldal <mi...@magine.com>
Authored: Mon Oct 3 18:54:27 2016 +0200
Committer: Mikael St�ldal <mi...@magine.com>
Committed: Mon Oct 3 18:54:27 2016 +0200
----------------------------------------------------------------------
.../logging/log4j/core/LoggerContext.java | 9 ++--
.../core/config/AbstractConfiguration.java | 10 +++++
.../log4j/core/config/Configuration.java | 2 +
.../builder/api/ConfigurationBuilder.java | 7 ++++
.../config/builder/impl/BuiltConfiguration.java | 4 ++
.../impl/DefaultConfigurationBuilder.java | 14 +++++++
.../composite/CompositeConfiguration.java | 2 +
.../core/config/json/JsonConfiguration.java | 9 ++--
.../PropertiesConfigurationBuilder.java | 3 ++
.../log4j/core/config/xml/XmlConfiguration.java | 3 +-
.../core/ShutdownTimeoutConfigurationTest.java | 44 ++++++++++++++++++++
.../builder/ConfigurationBuilderTest.java | 5 ++-
.../resources/log4j-test-shutdownTimeout.xml | 38 +++++++++++++++++
src/changes/changes.xml | 5 +++
src/site/xdoc/manual/configuration.xml.vm | 8 +++-
15 files changed, 151 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/705e2725/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
index 7e13963..c964965 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
@@ -16,8 +16,6 @@
*/
package org.apache.logging.log4j.core;
-import static org.apache.logging.log4j.core.util.ShutdownCallbackRegistry.SHUTDOWN_HOOK_MARKER;
-
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
@@ -38,7 +36,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.core.config.ConfigurationListener;
-import org.apache.logging.log4j.core.config.ConfigurationSource; // SUPPRESS CHECKSTYLE
+import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.config.DefaultConfiguration;
import org.apache.logging.log4j.core.config.NullConfiguration;
import org.apache.logging.log4j.core.config.Reconfigurable;
@@ -56,6 +54,8 @@ import org.apache.logging.log4j.spi.LoggerRegistry;
import org.apache.logging.log4j.spi.Terminable;
import org.apache.logging.log4j.util.PropertiesUtil;
+import static org.apache.logging.log4j.core.util.ShutdownCallbackRegistry.SHUTDOWN_HOOK_MARKER;
+
/**
* The LoggerContext is the anchor for the logging system. It maintains a list of all the loggers requested by
* applications and a reference to the Configuration. The Configuration will contain the configured loggers, appenders,
@@ -265,6 +265,7 @@ public class LoggerContext extends AbstractLifeCycle
if (factory instanceof ShutdownCallbackRegistry) {
LOGGER.debug(SHUTDOWN_HOOK_MARKER, "Shutdown hook enabled. Registering a new one.");
try {
+ final long shutdownTimeoutMillis = this.configuration.getShutdownTimeoutMillis();
this.shutdownCallback = ((ShutdownCallbackRegistry) factory).addShutdownCallback(new Runnable() {
@Override
public void run() {
@@ -272,7 +273,7 @@ public class LoggerContext extends AbstractLifeCycle
final LoggerContext context = LoggerContext.this;
LOGGER.debug(SHUTDOWN_HOOK_MARKER, "Stopping LoggerContext[name={}, {}]",
context.getName(), context);
- context.stop();
+ context.stop(shutdownTimeoutMillis, TimeUnit.MILLISECONDS);
}
@Override
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/705e2725/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
index c740b8c..3a6a58e 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
@@ -102,6 +102,11 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement
protected boolean isShutdownHookEnabled = true;
/**
+ * Shutdown timeout in milliseconds.
+ */
+ protected long shutdownTimeoutMillis = 0;
+
+ /**
* The Script manager.
*/
protected ScriptManager scriptManager;
@@ -395,6 +400,11 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement
return isShutdownHookEnabled;
}
+ @Override
+ public long getShutdownTimeoutMillis() {
+ return shutdownTimeoutMillis;
+ }
+
public void setup() {
// default does nothing, subclasses do work.
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/705e2725/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configuration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configuration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configuration.java
index 1a55b48..95e6edc 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configuration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configuration.java
@@ -128,6 +128,8 @@ public interface Configuration extends Filterable {
boolean isShutdownHookEnabled();
+ long getShutdownTimeoutMillis();
+
ConfigurationScheduler getScheduler();
/**
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/705e2725/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/ConfigurationBuilder.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/ConfigurationBuilder.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/ConfigurationBuilder.java
index 4dc9b69..b115651 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/ConfigurationBuilder.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/ConfigurationBuilder.java
@@ -18,6 +18,7 @@ package org.apache.logging.log4j.core.config.builder.api;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.Filter;
@@ -367,6 +368,12 @@ public interface ConfigurationBuilder<T extends Configuration> extends Builder<T
*/
ConfigurationBuilder<T> setShutdownHook(String flag);
+ /**
+ * Specifies how long time appenders and other plugins will get to shutdown when the JVM shuts down.
+ * Default is zero. (Not used if {@link #setShutdownHook(String)} is set to "disable".)
+ * @return this builder instance.
+ */
+ ConfigurationBuilder<T> setShutdownTimeout(long timeout, TimeUnit timeUnit);
/**
* Sets the level of the StatusLogger.
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/705e2725/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java
index aa7761c..c241dfb 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java
@@ -147,6 +147,10 @@ public class BuiltConfiguration extends AbstractConfiguration {
isShutdownHookEnabled = !"disable".equalsIgnoreCase(flag);
}
+ public void setShutdownTimeoutMillis(long shutdownTimeoutMillis) {
+ this.shutdownTimeoutMillis = shutdownTimeoutMillis;
+ }
+
public void setMonitorInterval(final int intervalSeconds) {
if (this instanceof Reconfigurable && intervalSeconds > 0) {
final ConfigurationSource configSource = getConfigurationSource();
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/705e2725/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultConfigurationBuilder.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultConfigurationBuilder.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultConfigurationBuilder.java
index d8531d6..183094d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultConfigurationBuilder.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultConfigurationBuilder.java
@@ -22,6 +22,7 @@ import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
@@ -71,6 +72,7 @@ public class DefaultConfigurationBuilder<T extends BuiltConfiguration> implement
private String destination;
private String packages;
private String shutdownFlag;
+ private long shutdownTimeoutMillis;
private String advertiser;
private LoggerContext loggerContext;
private String name;
@@ -186,6 +188,9 @@ public class DefaultConfigurationBuilder<T extends BuiltConfiguration> implement
if (shutdownFlag != null) {
configuration.setShutdownHook(shutdownFlag);
}
+ if (shutdownTimeoutMillis > 0) {
+ configuration.setShutdownTimeoutMillis(shutdownTimeoutMillis);
+ }
if (advertiser != null) {
configuration.createAdvertiser(advertiser, source);
}
@@ -249,6 +254,9 @@ public class DefaultConfigurationBuilder<T extends BuiltConfiguration> implement
if (shutdownFlag != null) {
xmlWriter.writeAttribute("shutdownHook", shutdownFlag);
}
+ if (shutdownTimeoutMillis > 0) {
+ xmlWriter.writeAttribute("shutdownTimeout", String.valueOf(shutdownTimeoutMillis));
+ }
if (advertiser != null) {
xmlWriter.writeAttribute("advertiser", advertiser);
}
@@ -514,6 +522,12 @@ public class DefaultConfigurationBuilder<T extends BuiltConfiguration> implement
}
@Override
+ public ConfigurationBuilder<T> setShutdownTimeout(final long timeout, final TimeUnit timeUnit) {
+ this.shutdownTimeoutMillis = timeUnit.toMillis(timeout);
+ return this;
+ }
+
+ @Override
public ConfigurationBuilder<T> setStatusLevel(final Level level) {
this.level = level;
return this;
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/705e2725/log4j-core/src/main/java/org/apache/logging/log4j/core/config/composite/CompositeConfiguration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/composite/CompositeConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/composite/CompositeConfiguration.java
index fa941d7..e38c62b 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/composite/CompositeConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/composite/CompositeConfiguration.java
@@ -87,6 +87,8 @@ public class CompositeConfiguration extends AbstractConfiguration implements Rec
statusConfig.withDestination(value);
} else if ("shutdownHook".equalsIgnoreCase(key)) {
isShutdownHookEnabled = !"disable".equalsIgnoreCase(value);
+ } else if ("shutdownTimeout".equalsIgnoreCase(key)) {
+ shutdownTimeoutMillis = Long.parseLong(value);
} else if ("verbose".equalsIgnoreCase(key)) {
statusConfig.withVerbosity(value);
} else if ("packages".equalsIgnoreCase(key)) {
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/705e2725/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java
index 497496a..5b38dfb 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java
@@ -26,6 +26,9 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.AbstractConfiguration;
import org.apache.logging.log4j.core.config.Configuration;
@@ -40,10 +43,6 @@ import org.apache.logging.log4j.core.config.status.StatusConfiguration;
import org.apache.logging.log4j.core.util.FileWatcher;
import org.apache.logging.log4j.core.util.Patterns;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
/**
* Creates a Node hierarchy from a JSON file.
*/
@@ -81,6 +80,8 @@ public class JsonConfiguration extends AbstractConfiguration implements Reconfig
statusConfig.withDestination(value);
} else if ("shutdownHook".equalsIgnoreCase(key)) {
isShutdownHookEnabled = !"disable".equalsIgnoreCase(value);
+ } else if ("shutdownTimeout".equalsIgnoreCase(key)) {
+ shutdownTimeoutMillis = Long.parseLong(value);
} else if ("verbose".equalsIgnoreCase(entry.getKey())) {
statusConfig.withVerbosity(value);
} else if ("packages".equalsIgnoreCase(key)) {
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/705e2725/log4j-core/src/main/java/org/apache/logging/log4j/core/config/properties/PropertiesConfigurationBuilder.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/properties/PropertiesConfigurationBuilder.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/properties/PropertiesConfigurationBuilder.java
index a4362b7..3d24a9b 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/properties/PropertiesConfigurationBuilder.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/properties/PropertiesConfigurationBuilder.java
@@ -19,6 +19,7 @@ package org.apache.logging.log4j.core.config.properties;
import java.util.Map;
import java.util.Properties;
+import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.Appender;
@@ -54,6 +55,7 @@ public class PropertiesConfigurationBuilder extends ConfigurationBuilderFactory
private static final String ADVERTISER_KEY = "advertiser";
private static final String STATUS_KEY = "status";
private static final String SHUTDOWN_HOOK = "shutdownHook";
+ private static final String SHUTDOWN_TIMEOUT = "shutdownTimeout";
private static final String VERBOSE = "verbose";
private static final String DEST = "dest";
private static final String PACKAGES = "packages";
@@ -89,6 +91,7 @@ public class PropertiesConfigurationBuilder extends ConfigurationBuilderFactory
builder
.setStatusLevel(Level.toLevel(rootProperties.getProperty(STATUS_KEY), Level.ERROR))
.setShutdownHook(rootProperties.getProperty(SHUTDOWN_HOOK))
+ .setShutdownTimeout(Long.parseLong(rootProperties.getProperty(SHUTDOWN_TIMEOUT, "0")), TimeUnit.MILLISECONDS)
.setVerbosity(rootProperties.getProperty(VERBOSE))
.setDestination(rootProperties.getProperty(DEST))
.setPackages(rootProperties.getProperty(PACKAGES))
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/705e2725/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/XmlConfiguration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/XmlConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/XmlConfiguration.java
index 2608552..51f31d4 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/XmlConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/XmlConfiguration.java
@@ -24,7 +24,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
-
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -120,6 +119,8 @@ public class XmlConfiguration extends AbstractConfiguration implements Reconfigu
statusConfig.withDestination(value);
} else if ("shutdownHook".equalsIgnoreCase(key)) {
isShutdownHookEnabled = !"disable".equalsIgnoreCase(value);
+ } else if ("shutdownTimeout".equalsIgnoreCase(key)) {
+ shutdownTimeoutMillis = Long.parseLong(value);
} else if ("verbose".equalsIgnoreCase(key)) {
statusConfig.withVerbosity(value);
} else if ("packages".equalsIgnoreCase(key)) {
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/705e2725/log4j-core/src/test/java/org/apache/logging/log4j/core/ShutdownTimeoutConfigurationTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/ShutdownTimeoutConfigurationTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/ShutdownTimeoutConfigurationTest.java
new file mode 100644
index 0000000..5e0734c
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/ShutdownTimeoutConfigurationTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class ShutdownTimeoutConfigurationTest {
+
+ private static final String CONFIG = "log4j-test-shutdownTimeout.xml";
+
+ @ClassRule
+ public static LoggerContextRule context = new LoggerContextRule(CONFIG);
+
+ @Test
+ public void testShutdownFlag() {
+ final Configuration config = context.getConfiguration();
+ assertNotNull("No configuration", config);
+ assertEquals(5000, config.getShutdownTimeoutMillis());
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/705e2725/log4j-core/src/test/java/org/apache/logging/log4j/core/config/builder/ConfigurationBuilderTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/builder/ConfigurationBuilderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/builder/ConfigurationBuilderTest.java
index 2d48605..431ac01 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/builder/ConfigurationBuilderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/builder/ConfigurationBuilderTest.java
@@ -16,6 +16,8 @@
*/
package org.apache.logging.log4j.core.config.builder;
+import java.util.concurrent.TimeUnit;
+
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
@@ -36,6 +38,7 @@ public class ConfigurationBuilderTest {
private void addTestFixtures(final String name, final ConfigurationBuilder<BuiltConfiguration> builder) {
builder.setConfigurationName(name);
builder.setStatusLevel(Level.ERROR);
+ builder.setShutdownTimeout(5000, TimeUnit.MILLISECONDS);
builder.add(builder.newScriptFile("target/test-classes/scripts/filter.groovy").addIsWatched(true));
builder.add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.NEUTRAL)
.addAttribute("level", Level.DEBUG));
@@ -56,7 +59,7 @@ public class ConfigurationBuilderTest {
private final static String expectedXml =
"<?xml version='1.0' encoding='UTF-8'?>" + EOL +
- "<Configuration name=\"config name\" status=\"ERROR\" packages=\"foo,bar\">" + EOL +
+ "<Configuration name=\"config name\" status=\"ERROR\" packages=\"foo,bar\" shutdownTimeout=\"5000\">" + EOL +
INDENT + "<Properties>" + EOL +
INDENT + INDENT + "<Property name=\"MyKey\">MyValue</Property>" + EOL +
INDENT + "</Properties>" + EOL +
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/705e2725/log4j-core/src/test/resources/log4j-test-shutdownTimeout.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-test-shutdownTimeout.xml b/log4j-core/src/test/resources/log4j-test-shutdownTimeout.xml
new file mode 100644
index 0000000..19b25c9
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-test-shutdownTimeout.xml
@@ -0,0 +1,38 @@
+<?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="XMLConfigTest" monitorInterval="5" shutdownTimeout="5000">
+ <Appenders>
+ <Console name="STDOUT">
+ <PatternLayout pattern="%m MDC%X%n"/>
+ </Console>
+ <List name="List">
+ </List>
+ </Appenders>
+
+ <Loggers>
+ <Logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
+ <AppenderRef ref="STDOUT"/>
+ </Logger>>
+
+ <Root level="trace">
+ <AppenderRef ref="List"/>
+ </Root>
+ </Loggers>
+
+</Configuration>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/705e2725/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index cd2f379..6bd144c 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -23,6 +23,11 @@
<title>Changes</title>
</properties>
<body>
+ <release version="2.7.1" date="2016-XX-XX" description="GA Release 2.7.1">
+ <action issue="LOG4J2-1623" dev="mikes" type="fix">
+ Configurable JVM shutdown hook timeout.
+ </action>
+ </release>
<release version="2.7" date="2016-10-02" description="GA Release 2.7">
<action issue="LOG4J2-1618" dev="rpopma" type="fix" due-to="Raman Gupta">
Fixed ClassCastException when using JUL logging during shutdown.
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/705e2725/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 60419a4..acd41fd 100644
--- a/src/site/xdoc/manual/configuration.xml.vm
+++ b/src/site/xdoc/manual/configuration.xml.vm
@@ -408,6 +408,10 @@ public class Bar {
shutdown hook is enabled by default but may be disabled by setting this attribute to "disable"</td>
</tr>
<tr>
+ <td>shutdownTimeout</td>
+ <td>Specifies how many milliseconds appenders and other plugins will get to shutdown when the JVM shuts down.
+ Default is zero. (Not used if <tt>shutdownHook</tt> is set to "disable".)</td>
+ <tr>
<td>status</td>
<td>The level of internal Log4j events that should be logged to the console.
Valid values for this attribute are "trace", "debug", "info", "warn", "error" and "fatal".
@@ -841,8 +845,8 @@ public class Bar {
</p>
<p>
Properties configuration files support the advertiser, monitorInterval, name, packages, shutdownHook,
- status, verbose, and dest attrbutes. See <a href="#ConfigurationSyntax">Configuration Syntax</a> for the
- definitions of these attributes.
+ shutdownTimeout, status, verbose, and dest attrbutes. See <a href="#ConfigurationSyntax">Configuration Syntax</a>
+ for the definitions of these attributes.
</p>
<pre class="prettyprint linenums">
status = error
Re: logging-log4j2 git commit: LOG4J2-1623 Configurable JVM shutdown
hook timeout
Posted by Mikael Ståldal <mi...@magine.com>.
That might make sense, but I propose we do that separately since it's not
related to what I am working on.
On Mon, Oct 3, 2016 at 11:28 PM, Gary Gregory <ga...@gmail.com>
wrote:
> WRT:
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7
> 05e2725/log4j-core/src/main/java/org/apache/logging/log4j/co
> re/config/composite/CompositeConfiguration.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/composite/CompositeConfiguration.java b/log4j-core/src/main/java/org
> /apache/logging/log4j/core/config/composite/CompositeConfiguration.java
> index fa941d7..e38c62b 100644
> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/composite/CompositeConfiguration.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/composite/CompositeConfiguration.java
> @@ -87,6 +87,8 @@ public class CompositeConfiguration extends
> AbstractConfiguration implements Rec
> statusConfig.withDestination(value);
> } else if ("shutdownHook".equalsIgnoreCase(key)) {
> isShutdownHookEnabled = !"disable".equalsIgnoreCase(va
> lue);
> + } else if ("shutdownTimeout".equalsIgnoreCase(key)) {
> + shutdownTimeoutMillis = Long.parseLong(value);
> } else if ("verbose".equalsIgnoreCase(key)) {
> statusConfig.withVerbosity(value);
> } else if ("packages".equalsIgnoreCase(key)) {
>
> How about a switch on String instead of an old-school cascading if-else?
>
> Gary
>
> ---------- Forwarded message ----------
> From: <mi...@apache.org>
> Date: Mon, Oct 3, 2016 at 9:54 AM
> Subject: logging-log4j2 git commit: LOG4J2-1623 Configurable JVM shutdown
> hook timeout
> To: commits@logging.apache.org
>
>
> Repository: logging-log4j2
> Updated Branches:
> refs/heads/LOG4J2-1623 [created] 705e27253
>
>
> LOG4J2-1623 Configurable JVM shutdown hook timeout
>
>
> Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
> Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit
> /705e2725
> Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/705e2725
> Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/705e2725
>
> Branch: refs/heads/LOG4J2-1623
> Commit: 705e27253ca14cdf0e50039cada041065e308aee
> Parents: 3176c96
> Author: Mikael Ståldal <mi...@magine.com>
> Authored: Mon Oct 3 18:54:27 2016 +0200
> Committer: Mikael Ståldal <mi...@magine.com>
> Committed: Mon Oct 3 18:54:27 2016 +0200
>
> ----------------------------------------------------------------------
> .../logging/log4j/core/LoggerContext.java | 9 ++--
> .../core/config/AbstractConfiguration.java | 10 +++++
> .../log4j/core/config/Configuration.java | 2 +
> .../builder/api/ConfigurationBuilder.java | 7 ++++
> .../config/builder/impl/BuiltConfiguration.java | 4 ++
> .../impl/DefaultConfigurationBuilder.java | 14 +++++++
> .../composite/CompositeConfiguration.java | 2 +
> .../core/config/json/JsonConfiguration.java | 9 ++--
> .../PropertiesConfigurationBuilder.java | 3 ++
> .../log4j/core/config/xml/XmlConfiguration.java | 3 +-
> .../core/ShutdownTimeoutConfigurationTest.java | 44 ++++++++++++++++++++
> .../builder/ConfigurationBuilderTest.java | 5 ++-
> .../resources/log4j-test-shutdownTimeout.xml | 38 +++++++++++++++++
> src/changes/changes.xml | 5 +++
> src/site/xdoc/manual/configuration.xml.vm | 8 +++-
> 15 files changed, 151 insertions(+), 12 deletions(-)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7
> 05e2725/log4j-core/src/main/java/org/apache/logging/log4j/co
> re/LoggerContext.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
> b/log4j-core/src/main/java/org/apache/logging/log4j/core/Log
> gerContext.java
> index 7e13963..c964965 100644
> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/Log
> gerContext.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/Log
> gerContext.java
> @@ -16,8 +16,6 @@
> */
> package org.apache.logging.log4j.core;
>
> -import static org.apache.logging.log4j.core.
> util.ShutdownCallbackRegistry.SHUTDOWN_HOOK_MARKER;
> -
> import java.beans.PropertyChangeEvent;
> import java.beans.PropertyChangeListener;
> import java.io.File;
> @@ -38,7 +36,7 @@ import org.apache.logging.log4j.LogManager;
> import org.apache.logging.log4j.core.config.Configuration;
> import org.apache.logging.log4j.core.config.ConfigurationFactory;
> import org.apache.logging.log4j.core.config.ConfigurationListener;
> -import org.apache.logging.log4j.core.config.ConfigurationSource; //
> SUPPRESS CHECKSTYLE
> +import org.apache.logging.log4j.core.config.ConfigurationSource;
> import org.apache.logging.log4j.core.config.DefaultConfiguration;
> import org.apache.logging.log4j.core.config.NullConfiguration;
> import org.apache.logging.log4j.core.config.Reconfigurable;
> @@ -56,6 +54,8 @@ import org.apache.logging.log4j.spi.LoggerRegistry;
> import org.apache.logging.log4j.spi.Terminable;
> import org.apache.logging.log4j.util.PropertiesUtil;
>
> +import static org.apache.logging.log4j.core.
> util.ShutdownCallbackRegistry.SHUTDOWN_HOOK_MARKER;
> +
> /**
> * The LoggerContext is the anchor for the logging system. It maintains a
> list of all the loggers requested by
> * applications and a reference to the Configuration. The Configuration
> will contain the configured loggers, appenders,
> @@ -265,6 +265,7 @@ public class LoggerContext extends AbstractLifeCycle
> if (factory instanceof ShutdownCallbackRegistry) {
> LOGGER.debug(SHUTDOWN_HOOK_MARKER, "Shutdown hook
> enabled. Registering a new one.");
> try {
> + final long shutdownTimeoutMillis =
> this.configuration.getShutdownTimeoutMillis();
> this.shutdownCallback = ((ShutdownCallbackRegistry)
> factory).addShutdownCallback(new Runnable() {
> @Override
> public void run() {
> @@ -272,7 +273,7 @@ public class LoggerContext extends AbstractLifeCycle
> final LoggerContext context =
> LoggerContext.this;
> LOGGER.debug(SHUTDOWN_HOOK_MARKER, "Stopping
> LoggerContext[name={}, {}]",
> context.getName(), context);
> - context.stop();
> + context.stop(shutdownTimeoutMillis,
> TimeUnit.MILLISECONDS);
> }
>
> @Override
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7
> 05e2725/log4j-core/src/main/java/org/apache/logging/log4j/co
> re/config/AbstractConfiguration.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
> b/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/AbstractConfiguration.java
> index c740b8c..3a6a58e 100644
> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/AbstractConfiguration.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/AbstractConfiguration.java
> @@ -102,6 +102,11 @@ public abstract class AbstractConfiguration extends
> AbstractFilterable implement
> protected boolean isShutdownHookEnabled = true;
>
> /**
> + * Shutdown timeout in milliseconds.
> + */
> + protected long shutdownTimeoutMillis = 0;
> +
> + /**
> * The Script manager.
> */
> protected ScriptManager scriptManager;
> @@ -395,6 +400,11 @@ public abstract class AbstractConfiguration extends
> AbstractFilterable implement
> return isShutdownHookEnabled;
> }
>
> + @Override
> + public long getShutdownTimeoutMillis() {
> + return shutdownTimeoutMillis;
> + }
> +
> public void setup() {
> // default does nothing, subclasses do work.
> }
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7
> 05e2725/log4j-core/src/main/java/org/apache/logging/log4j/co
> re/config/Configuration.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configuration.java
> b/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/Configuration.java
> index 1a55b48..95e6edc 100644
> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/Configuration.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/Configuration.java
> @@ -128,6 +128,8 @@ public interface Configuration extends Filterable {
>
> boolean isShutdownHookEnabled();
>
> + long getShutdownTimeoutMillis();
> +
> ConfigurationScheduler getScheduler();
>
> /**
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7
> 05e2725/log4j-core/src/main/java/org/apache/logging/log4j/co
> re/config/builder/api/ConfigurationBuilder.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/builder/api/ConfigurationBuilder.java b/log4j-core/src/main/java/org
> /apache/logging/log4j/core/config/builder/api/ConfigurationBuilder.java
> index 4dc9b69..b115651 100644
> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/builder/api/ConfigurationBuilder.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/builder/api/ConfigurationBuilder.java
> @@ -18,6 +18,7 @@ package org.apache.logging.log4j.core.
> config.builder.api;
>
> import java.io.IOException;
> import java.io.OutputStream;
> +import java.util.concurrent.TimeUnit;
>
> import org.apache.logging.log4j.Level;
> import org.apache.logging.log4j.core.Filter;
> @@ -367,6 +368,12 @@ public interface ConfigurationBuilder<T extends
> Configuration> extends Builder<T
> */
> ConfigurationBuilder<T> setShutdownHook(String flag);
>
> + /**
> + * Specifies how long time appenders and other plugins will get to
> shutdown when the JVM shuts down.
> + * Default is zero. (Not used if {@link #setShutdownHook(String)} is
> set to "disable".)
> + * @return this builder instance.
> + */
> + ConfigurationBuilder<T> setShutdownTimeout(long timeout, TimeUnit
> timeUnit);
>
> /**
> * Sets the level of the StatusLogger.
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7
> 05e2725/log4j-core/src/main/java/org/apache/logging/log4j/co
> re/config/builder/impl/BuiltConfiguration.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/builder/impl/BuiltConfiguration.java b/log4j-core/src/main/java/org
> /apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java
> index aa7761c..c241dfb 100644
> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/builder/impl/BuiltConfiguration.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/builder/impl/BuiltConfiguration.java
> @@ -147,6 +147,10 @@ public class BuiltConfiguration extends
> AbstractConfiguration {
> isShutdownHookEnabled = !"disable".equalsIgnoreCase(flag);
> }
>
> + public void setShutdownTimeoutMillis(long shutdownTimeoutMillis) {
> + this.shutdownTimeoutMillis = shutdownTimeoutMillis;
> + }
> +
> public void setMonitorInterval(final int intervalSeconds) {
> if (this instanceof Reconfigurable && intervalSeconds > 0) {
> final ConfigurationSource configSource =
> getConfigurationSource();
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7
> 05e2725/log4j-core/src/main/java/org/apache/logging/log4j/co
> re/config/builder/impl/DefaultConfigurationBuilder.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/builder/impl/DefaultConfigurationBuilder.java
> b/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/builder/impl/DefaultConfigurationBuilder.java
> index d8531d6..183094d 100644
> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/builder/impl/DefaultConfigurationBuilder.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/builder/impl/DefaultConfigurationBuilder.java
> @@ -22,6 +22,7 @@ import java.io.StringWriter;
> import java.lang.reflect.Constructor;
> import java.util.List;
> import java.util.Map;
> +import java.util.concurrent.TimeUnit;
> import javax.xml.stream.XMLOutputFactory;
> import javax.xml.stream.XMLStreamException;
> import javax.xml.stream.XMLStreamWriter;
> @@ -71,6 +72,7 @@ public class DefaultConfigurationBuilder<T extends
> BuiltConfiguration> implement
> private String destination;
> private String packages;
> private String shutdownFlag;
> + private long shutdownTimeoutMillis;
> private String advertiser;
> private LoggerContext loggerContext;
> private String name;
> @@ -186,6 +188,9 @@ public class DefaultConfigurationBuilder<T extends
> BuiltConfiguration> implement
> if (shutdownFlag != null) {
> configuration.setShutdownHook(shutdownFlag);
> }
> + if (shutdownTimeoutMillis > 0) {
> + configuration.setShutdownTimeo
> utMillis(shutdownTimeoutMillis);
> + }
> if (advertiser != null) {
> configuration.createAdvertiser(advertiser, source);
> }
> @@ -249,6 +254,9 @@ public class DefaultConfigurationBuilder<T extends
> BuiltConfiguration> implement
> if (shutdownFlag != null) {
> xmlWriter.writeAttribute("shutdownHook", shutdownFlag);
> }
> + if (shutdownTimeoutMillis > 0) {
> + xmlWriter.writeAttribute("shutdownTimeout",
> String.valueOf(shutdownTimeoutMillis));
> + }
> if (advertiser != null) {
> xmlWriter.writeAttribute("advertiser", advertiser);
> }
> @@ -514,6 +522,12 @@ public class DefaultConfigurationBuilder<T extends
> BuiltConfiguration> implement
> }
>
> @Override
> + public ConfigurationBuilder<T> setShutdownTimeout(final long timeout,
> final TimeUnit timeUnit) {
> + this.shutdownTimeoutMillis = timeUnit.toMillis(timeout);
> + return this;
> + }
> +
> + @Override
> public ConfigurationBuilder<T> setStatusLevel(final Level level) {
> this.level = level;
> return this;
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7
> 05e2725/log4j-core/src/main/java/org/apache/logging/log4j/co
> re/config/composite/CompositeConfiguration.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/composite/CompositeConfiguration.java b/log4j-core/src/main/java/org
> /apache/logging/log4j/core/config/composite/CompositeConfiguration.java
> index fa941d7..e38c62b 100644
> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/composite/CompositeConfiguration.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/composite/CompositeConfiguration.java
> @@ -87,6 +87,8 @@ public class CompositeConfiguration extends
> AbstractConfiguration implements Rec
> statusConfig.withDestination(value);
> } else if ("shutdownHook".equalsIgnoreCase(key)) {
> isShutdownHookEnabled = !"disable".equalsIgnoreCase(va
> lue);
> + } else if ("shutdownTimeout".equalsIgnoreCase(key)) {
> + shutdownTimeoutMillis = Long.parseLong(value);
> } else if ("verbose".equalsIgnoreCase(key)) {
> statusConfig.withVerbosity(value);
> } else if ("packages".equalsIgnoreCase(key)) {
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7
> 05e2725/log4j-core/src/main/java/org/apache/logging/log4j/co
> re/config/json/JsonConfiguration.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/json/JsonConfiguration.java b/log4j-core/src/main/java/org
> /apache/logging/log4j/core/config/json/JsonConfiguration.java
> index 497496a..5b38dfb 100644
> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/json/JsonConfiguration.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/json/JsonConfiguration.java
> @@ -26,6 +26,9 @@ import java.util.Iterator;
> import java.util.List;
> import java.util.Map;
>
> +import com.fasterxml.jackson.core.JsonParser;
> +import com.fasterxml.jackson.databind.JsonNode;
> +import com.fasterxml.jackson.databind.ObjectMapper;
> import org.apache.logging.log4j.core.LoggerContext;
> import org.apache.logging.log4j.core.config.AbstractConfiguration;
> import org.apache.logging.log4j.core.config.Configuration;
> @@ -40,10 +43,6 @@ import org.apache.logging.log4j.core.
> config.status.StatusConfiguration;
> import org.apache.logging.log4j.core.util.FileWatcher;
> import org.apache.logging.log4j.core.util.Patterns;
>
> -import com.fasterxml.jackson.core.JsonParser;
> -import com.fasterxml.jackson.databind.JsonNode;
> -import com.fasterxml.jackson.databind.ObjectMapper;
> -
> /**
> * Creates a Node hierarchy from a JSON file.
> */
> @@ -81,6 +80,8 @@ public class JsonConfiguration extends
> AbstractConfiguration implements Reconfig
> statusConfig.withDestination(value);
> } else if ("shutdownHook".equalsIgnoreCase(key)) {
> isShutdownHookEnabled = !"disable".equalsIgnoreCase(va
> lue);
> + } else if ("shutdownTimeout".equalsIgnoreCase(key)) {
> + shutdownTimeoutMillis = Long.parseLong(value);
> } else if ("verbose".equalsIgnoreCase(entry.getKey())) {
> statusConfig.withVerbosity(value);
> } else if ("packages".equalsIgnoreCase(key)) {
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7
> 05e2725/log4j-core/src/main/java/org/apache/logging/log4j/co
> re/config/properties/PropertiesConfigurationBuilder.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/properties/PropertiesConfigurationBuilder.java
> b/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/properties/PropertiesConfigurationBuilder.java
> index a4362b7..3d24a9b 100644
> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/properties/PropertiesConfigurationBuilder.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/properties/PropertiesConfigurationBuilder.java
> @@ -19,6 +19,7 @@ package org.apache.logging.log4j.core.config.properties;
>
> import java.util.Map;
> import java.util.Properties;
> +import java.util.concurrent.TimeUnit;
>
> import org.apache.logging.log4j.Level;
> import org.apache.logging.log4j.core.Appender;
> @@ -54,6 +55,7 @@ public class PropertiesConfigurationBuilder extends
> ConfigurationBuilderFactory
> private static final String ADVERTISER_KEY = "advertiser";
> private static final String STATUS_KEY = "status";
> private static final String SHUTDOWN_HOOK = "shutdownHook";
> + private static final String SHUTDOWN_TIMEOUT = "shutdownTimeout";
> private static final String VERBOSE = "verbose";
> private static final String DEST = "dest";
> private static final String PACKAGES = "packages";
> @@ -89,6 +91,7 @@ public class PropertiesConfigurationBuilder extends
> ConfigurationBuilderFactory
> builder
> .setStatusLevel(Level.toLevel(rootProperties.getProperty(STATUS_KEY),
> Level.ERROR))
> .setShutdownHook(rootProperties.getProperty(SHUTDOWN_HOOK))
> + .setShutdownTimeout(Long.parseLong(rootProperties.getProperty(SHUTDOWN_TIMEOUT,
> "0")), TimeUnit.MILLISECONDS)
> .setVerbosity(rootProperties.getProperty(VERBOSE))
> .setDestination(rootProperties.getProperty(DEST))
> .setPackages(rootProperties.getProperty(PACKAGES))
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7
> 05e2725/log4j-core/src/main/java/org/apache/logging/log4j/co
> re/config/xml/XmlConfiguration.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/XmlConfiguration.java
> b/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/xml/XmlConfiguration.java
> index 2608552..51f31d4 100644
> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/xml/XmlConfiguration.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/con
> fig/xml/XmlConfiguration.java
> @@ -24,7 +24,6 @@ import java.util.ArrayList;
> import java.util.Arrays;
> import java.util.List;
> import java.util.Map;
> -
> import javax.xml.XMLConstants;
> import javax.xml.parsers.DocumentBuilder;
> import javax.xml.parsers.DocumentBuilderFactory;
> @@ -120,6 +119,8 @@ public class XmlConfiguration extends
> AbstractConfiguration implements Reconfigu
> statusConfig.withDestination(value);
> } else if ("shutdownHook".equalsIgnoreCase(key)) {
> isShutdownHookEnabled = !"disable".equalsIgnoreCase(va
> lue);
> + } else if ("shutdownTimeout".equalsIgnoreCase(key)) {
> + shutdownTimeoutMillis = Long.parseLong(value);
> } else if ("verbose".equalsIgnoreCase(key)) {
> statusConfig.withVerbosity(value);
> } else if ("packages".equalsIgnoreCase(key)) {
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7
> 05e2725/log4j-core/src/test/java/org/apache/logging/log4j/co
> re/ShutdownTimeoutConfigurationTest.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/Shu
> tdownTimeoutConfigurationTest.java b/log4j-core/src/test/java/org
> /apache/logging/log4j/core/ShutdownTimeoutConfigurationTest.java
> new file mode 100644
> index 0000000..5e0734c
> --- /dev/null
> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/Shu
> tdownTimeoutConfigurationTest.java
> @@ -0,0 +1,44 @@
> +/*
> + * 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;
> +
> +import org.apache.logging.log4j.core.config.Configuration;
> +import org.apache.logging.log4j.junit.LoggerContextRule;
> +import org.junit.ClassRule;
> +import org.junit.Test;
> +
> +import static org.junit.Assert.*;
> +
> +/**
> + *
> + */
> +public class ShutdownTimeoutConfigurationTest {
> +
> + private static final String CONFIG = "log4j-test-shutdownTimeout.xm
> l";
> +
> + @ClassRule
> + public static LoggerContextRule context = new
> LoggerContextRule(CONFIG);
> +
> + @Test
> + public void testShutdownFlag() {
> + final Configuration config = context.getConfiguration();
> + assertNotNull("No configuration", config);
> + assertEquals(5000, config.getShutdownTimeoutMillis());
> + }
> +
> +}
> +
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7
> 05e2725/log4j-core/src/test/java/org/apache/logging/log4j/co
> re/config/builder/ConfigurationBuilderTest.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/con
> fig/builder/ConfigurationBuilderTest.java b/log4j-core/src/test/java/org
> /apache/logging/log4j/core/config/builder/ConfigurationBuilderTest.java
> index 2d48605..431ac01 100644
> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/con
> fig/builder/ConfigurationBuilderTest.java
> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/con
> fig/builder/ConfigurationBuilderTest.java
> @@ -16,6 +16,8 @@
> */
> package org.apache.logging.log4j.core.config.builder;
>
> +import java.util.concurrent.TimeUnit;
> +
> import org.apache.logging.log4j.Level;
> import org.apache.logging.log4j.core.Filter;
> import org.apache.logging.log4j.core.appender.ConsoleAppender;
> @@ -36,6 +38,7 @@ public class ConfigurationBuilderTest {
> private void addTestFixtures(final String name, final
> ConfigurationBuilder<BuiltConfiguration> builder) {
> builder.setConfigurationName(name);
> builder.setStatusLevel(Level.ERROR);
> + builder.setShutdownTimeout(5000, TimeUnit.MILLISECONDS);
> builder.add(builder.newScriptFile("target/test-classes/
> scripts/filter.groovy").addIsWatched(true));
> builder.add(builder.newFilter("ThresholdFilter",
> Filter.Result.ACCEPT, Filter.Result.NEUTRAL)
> .addAttribute("level", Level.DEBUG));
> @@ -56,7 +59,7 @@ public class ConfigurationBuilderTest {
>
> private final static String expectedXml =
> "<?xml version='1.0' encoding='UTF-8'?>" + EOL +
> - "<Configuration name=\"config name\" status=\"ERROR\"
> packages=\"foo,bar\">" + EOL +
> + "<Configuration name=\"config name\" status=\"ERROR\"
> packages=\"foo,bar\" shutdownTimeout=\"5000\">" + EOL +
> INDENT + "<Properties>" + EOL +
> INDENT + INDENT + "<Property
> name=\"MyKey\">MyValue</Property>" + EOL +
> INDENT + "</Properties>" + EOL +
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7
> 05e2725/log4j-core/src/test/resources/log4j-test-shutdownTimeout.xml
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/test/resources/log4j-test-shutdownTimeout.xml
> b/log4j-core/src/test/resources/log4j-test-shutdownTimeout.xml
> new file mode 100644
> index 0000000..19b25c9
> --- /dev/null
> +++ b/log4j-core/src/test/resources/log4j-test-shutdownTimeout.xml
> @@ -0,0 +1,38 @@
> +<?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="XMLConfigTest" monitorInterval="5"
> shutdownTimeout="5000">
> + <Appenders>
> + <Console name="STDOUT">
> + <PatternLayout pattern="%m MDC%X%n"/>
> + </Console>
> + <List name="List">
> + </List>
> + </Appenders>
> +
> + <Loggers>
> + <Logger name="org.apache.logging.log4j.test1" level="debug"
> additivity="false">
> + <AppenderRef ref="STDOUT"/>
> + </Logger>>
> +
> + <Root level="trace">
> + <AppenderRef ref="List"/>
> + </Root>
> + </Loggers>
> +
> +</Configuration>
> \ No newline at end of file
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7
> 05e2725/src/changes/changes.xml
> ----------------------------------------------------------------------
> diff --git a/src/changes/changes.xml b/src/changes/changes.xml
> index cd2f379..6bd144c 100644
> --- a/src/changes/changes.xml
> +++ b/src/changes/changes.xml
> @@ -23,6 +23,11 @@
> <title>Changes</title>
> </properties>
> <body>
> + <release version="2.7.1" date="2016-XX-XX" description="GA Release
> 2.7.1">
> + <action issue="LOG4J2-1623" dev="mikes" type="fix">
> + Configurable JVM shutdown hook timeout.
> + </action>
> + </release>
> <release version="2.7" date="2016-10-02" description="GA Release 2.7">
> <action issue="LOG4J2-1618" dev="rpopma" type="fix" due-to="Raman
> Gupta">
> Fixed ClassCastException when using JUL logging during shutdown.
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7
> 05e2725/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 60419a4..acd41fd 100644
> --- a/src/site/xdoc/manual/configuration.xml.vm
> +++ b/src/site/xdoc/manual/configuration.xml.vm
> @@ -408,6 +408,10 @@ public class Bar {
> shutdown hook is enabled by default but may be disabled
> by setting this attribute to "disable"</td>
> </tr>
> <tr>
> + <td>shutdownTimeout</td>
> + <td>Specifies how many milliseconds appenders and other
> plugins will get to shutdown when the JVM shuts down.
> + Default is zero. (Not used if <tt>shutdownHook</tt> is
> set to "disable".)</td>
> + <tr>
> <td>status</td>
> <td>The level of internal Log4j events that should be
> logged to the console.
> Valid values for this attribute are "trace", "debug",
> "info", "warn", "error" and "fatal".
> @@ -841,8 +845,8 @@ public class Bar {
> </p>
> <p>
> Properties configuration files support the advertiser,
> monitorInterval, name, packages, shutdownHook,
> - status, verbose, and dest attrbutes. See <a
> href="#ConfigurationSyntax">Configuration Syntax</a> for the
> - definitions of these attributes.
> + shutdownTimeout, status, verbose, and dest attrbutes. See
> <a href="#ConfigurationSyntax">Configuration Syntax</a>
> + for the definitions of these attributes.
> </p>
> <pre class="prettyprint linenums">
> status = error
>
>
>
>
> --
> E-Mail: garydgregory@gmail.com | ggregory@apache.org
> Java Persistence with Hibernate, Second Edition
> <http://www.manning.com/bauer3/>
> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
> Spring Batch in Action <http://www.manning.com/templier/>
> Blog: http://garygregory.wordpress.com
> Home: http://garygregory.com/
> Tweet! http://twitter.com/GaryGregory
>
--
[image: MagineTV]
*Mikael Ståldal*
Senior software developer
*Magine TV*
mikael.staldal@magine.com
Grev Turegatan 3 | 114 46 Stockholm, Sweden | www.magine.com
Privileged and/or Confidential Information may be contained in this
message. If you are not the addressee indicated in this message
(or responsible for delivery of the message to such a person), you may not
copy or deliver this message to anyone. In such case,
you should destroy this message and kindly notify the sender by reply
email.
Fwd: logging-log4j2 git commit: LOG4J2-1623 Configurable JVM shutdown
hook timeout
Posted by Gary Gregory <ga...@gmail.com>.
WRT:
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
705e2725/log4j-core/src/main/java/org/apache/logging/log4j/
core/config/composite/CompositeConfiguration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/composite/CompositeConfiguration.java b/log4j-core/src/main/java/
org/apache/logging/log4j/core/config/composite/CompositeConfiguration.java
index fa941d7..e38c62b 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/composite/CompositeConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/composite/CompositeConfiguration.java
@@ -87,6 +87,8 @@ public class CompositeConfiguration extends
AbstractConfiguration implements Rec
statusConfig.withDestination(value);
} else if ("shutdownHook".equalsIgnoreCase(key)) {
isShutdownHookEnabled = !"disable".equalsIgnoreCase(value);
+ } else if ("shutdownTimeout".equalsIgnoreCase(key)) {
+ shutdownTimeoutMillis = Long.parseLong(value);
} else if ("verbose".equalsIgnoreCase(key)) {
statusConfig.withVerbosity(value);
} else if ("packages".equalsIgnoreCase(key)) {
How about a switch on String instead of an old-school cascading if-else?
Gary
---------- Forwarded message ----------
From: <mi...@apache.org>
Date: Mon, Oct 3, 2016 at 9:54 AM
Subject: logging-log4j2 git commit: LOG4J2-1623 Configurable JVM shutdown
hook timeout
To: commits@logging.apache.org
Repository: logging-log4j2
Updated Branches:
refs/heads/LOG4J2-1623 [created] 705e27253
LOG4J2-1623 Configurable JVM shutdown hook timeout
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/
commit/705e2725
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/705e2725
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/705e2725
Branch: refs/heads/LOG4J2-1623
Commit: 705e27253ca14cdf0e50039cada041065e308aee
Parents: 3176c96
Author: Mikael Ståldal <mi...@magine.com>
Authored: Mon Oct 3 18:54:27 2016 +0200
Committer: Mikael Ståldal <mi...@magine.com>
Committed: Mon Oct 3 18:54:27 2016 +0200
----------------------------------------------------------------------
.../logging/log4j/core/LoggerContext.java | 9 ++--
.../core/config/AbstractConfiguration.java | 10 +++++
.../log4j/core/config/Configuration.java | 2 +
.../builder/api/ConfigurationBuilder.java | 7 ++++
.../config/builder/impl/BuiltConfiguration.java | 4 ++
.../impl/DefaultConfigurationBuilder.java | 14 +++++++
.../composite/CompositeConfiguration.java | 2 +
.../core/config/json/JsonConfiguration.java | 9 ++--
.../PropertiesConfigurationBuilder.java | 3 ++
.../log4j/core/config/xml/XmlConfiguration.java | 3 +-
.../core/ShutdownTimeoutConfigurationTest.java | 44 ++++++++++++++++++++
.../builder/ConfigurationBuilderTest.java | 5 ++-
.../resources/log4j-test-shutdownTimeout.xml | 38 +++++++++++++++++
src/changes/changes.xml | 5 +++
src/site/xdoc/manual/configuration.xml.vm | 8 +++-
15 files changed, 151 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
705e2725/log4j-core/src/main/java/org/apache/logging/log4j/
core/LoggerContext.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
index 7e13963..c964965 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/
LoggerContext.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/
LoggerContext.java
@@ -16,8 +16,6 @@
*/
package org.apache.logging.log4j.core;
-import static org.apache.logging.log4j.core.util.ShutdownCallbackRegistry.
SHUTDOWN_HOOK_MARKER;
-
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
@@ -38,7 +36,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.core.config.ConfigurationListener;
-import org.apache.logging.log4j.core.config.ConfigurationSource; //
SUPPRESS CHECKSTYLE
+import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.config.DefaultConfiguration;
import org.apache.logging.log4j.core.config.NullConfiguration;
import org.apache.logging.log4j.core.config.Reconfigurable;
@@ -56,6 +54,8 @@ import org.apache.logging.log4j.spi.LoggerRegistry;
import org.apache.logging.log4j.spi.Terminable;
import org.apache.logging.log4j.util.PropertiesUtil;
+import static org.apache.logging.log4j.core.util.ShutdownCallbackRegistry.
SHUTDOWN_HOOK_MARKER;
+
/**
* The LoggerContext is the anchor for the logging system. It maintains a
list of all the loggers requested by
* applications and a reference to the Configuration. The Configuration
will contain the configured loggers, appenders,
@@ -265,6 +265,7 @@ public class LoggerContext extends AbstractLifeCycle
if (factory instanceof ShutdownCallbackRegistry) {
LOGGER.debug(SHUTDOWN_HOOK_MARKER, "Shutdown hook enabled.
Registering a new one.");
try {
+ final long shutdownTimeoutMillis = this.configuration.
getShutdownTimeoutMillis();
this.shutdownCallback = ((ShutdownCallbackRegistry)
factory).addShutdownCallback(new Runnable() {
@Override
public void run() {
@@ -272,7 +273,7 @@ public class LoggerContext extends AbstractLifeCycle
final LoggerContext context =
LoggerContext.this;
LOGGER.debug(SHUTDOWN_HOOK_MARKER, "Stopping
LoggerContext[name={}, {}]",
context.getName(), context);
- context.stop();
+ context.stop(shutdownTimeoutMillis,
TimeUnit.MILLISECONDS);
}
@Override
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
705e2725/log4j-core/src/main/java/org/apache/logging/log4j/core/config/
AbstractConfiguration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/AbstractConfiguration.java b/log4j-core/src/main/java/
org/apache/logging/log4j/core/config/AbstractConfiguration.java
index c740b8c..3a6a58e 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/AbstractConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/AbstractConfiguration.java
@@ -102,6 +102,11 @@ public abstract class AbstractConfiguration extends
AbstractFilterable implement
protected boolean isShutdownHookEnabled = true;
/**
+ * Shutdown timeout in milliseconds.
+ */
+ protected long shutdownTimeoutMillis = 0;
+
+ /**
* The Script manager.
*/
protected ScriptManager scriptManager;
@@ -395,6 +400,11 @@ public abstract class AbstractConfiguration extends
AbstractFilterable implement
return isShutdownHookEnabled;
}
+ @Override
+ public long getShutdownTimeoutMillis() {
+ return shutdownTimeoutMillis;
+ }
+
public void setup() {
// default does nothing, subclasses do work.
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
705e2725/log4j-core/src/main/java/org/apache/logging/log4j/
core/config/Configuration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configuration.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/Configuration.java
index 1a55b48..95e6edc 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/Configuration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/Configuration.java
@@ -128,6 +128,8 @@ public interface Configuration extends Filterable {
boolean isShutdownHookEnabled();
+ long getShutdownTimeoutMillis();
+
ConfigurationScheduler getScheduler();
/**
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
705e2725/log4j-core/src/main/java/org/apache/logging/log4j/
core/config/builder/api/ConfigurationBuilder.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/builder/api/ConfigurationBuilder.java b/log4j-core/src/main/java/
org/apache/logging/log4j/core/config/builder/api/ConfigurationBuilder.java
index 4dc9b69..b115651 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/builder/api/ConfigurationBuilder.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/builder/api/ConfigurationBuilder.java
@@ -18,6 +18,7 @@ package org.apache.logging.log4j.core.config.builder.api;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.Filter;
@@ -367,6 +368,12 @@ public interface ConfigurationBuilder<T extends
Configuration> extends Builder<T
*/
ConfigurationBuilder<T> setShutdownHook(String flag);
+ /**
+ * Specifies how long time appenders and other plugins will get to
shutdown when the JVM shuts down.
+ * Default is zero. (Not used if {@link #setShutdownHook(String)} is
set to "disable".)
+ * @return this builder instance.
+ */
+ ConfigurationBuilder<T> setShutdownTimeout(long timeout, TimeUnit
timeUnit);
/**
* Sets the level of the StatusLogger.
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
705e2725/log4j-core/src/main/java/org/apache/logging/log4j/
core/config/builder/impl/BuiltConfiguration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/builder/impl/BuiltConfiguration.java b/log4j-core/src/main/java/
org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java
index aa7761c..c241dfb 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/builder/impl/BuiltConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/builder/impl/BuiltConfiguration.java
@@ -147,6 +147,10 @@ public class BuiltConfiguration extends
AbstractConfiguration {
isShutdownHookEnabled = !"disable".equalsIgnoreCase(flag);
}
+ public void setShutdownTimeoutMillis(long shutdownTimeoutMillis) {
+ this.shutdownTimeoutMillis = shutdownTimeoutMillis;
+ }
+
public void setMonitorInterval(final int intervalSeconds) {
if (this instanceof Reconfigurable && intervalSeconds > 0) {
final ConfigurationSource configSource =
getConfigurationSource();
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
705e2725/log4j-core/src/main/java/org/apache/logging/log4j/
core/config/builder/impl/DefaultConfigurationBuilder.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/builder/impl/DefaultConfigurationBuilder.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/builder/impl/DefaultConfigurationBuilder.java
index d8531d6..183094d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/builder/impl/DefaultConfigurationBuilder.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/builder/impl/DefaultConfigurationBuilder.java
@@ -22,6 +22,7 @@ import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
@@ -71,6 +72,7 @@ public class DefaultConfigurationBuilder<T extends
BuiltConfiguration> implement
private String destination;
private String packages;
private String shutdownFlag;
+ private long shutdownTimeoutMillis;
private String advertiser;
private LoggerContext loggerContext;
private String name;
@@ -186,6 +188,9 @@ public class DefaultConfigurationBuilder<T extends
BuiltConfiguration> implement
if (shutdownFlag != null) {
configuration.setShutdownHook(shutdownFlag);
}
+ if (shutdownTimeoutMillis > 0) {
+ configuration.setShutdownTimeoutMillis(
shutdownTimeoutMillis);
+ }
if (advertiser != null) {
configuration.createAdvertiser(advertiser, source);
}
@@ -249,6 +254,9 @@ public class DefaultConfigurationBuilder<T extends
BuiltConfiguration> implement
if (shutdownFlag != null) {
xmlWriter.writeAttribute("shutdownHook", shutdownFlag);
}
+ if (shutdownTimeoutMillis > 0) {
+ xmlWriter.writeAttribute("shutdownTimeout", String.valueOf(
shutdownTimeoutMillis));
+ }
if (advertiser != null) {
xmlWriter.writeAttribute("advertiser", advertiser);
}
@@ -514,6 +522,12 @@ public class DefaultConfigurationBuilder<T extends
BuiltConfiguration> implement
}
@Override
+ public ConfigurationBuilder<T> setShutdownTimeout(final long timeout,
final TimeUnit timeUnit) {
+ this.shutdownTimeoutMillis = timeUnit.toMillis(timeout);
+ return this;
+ }
+
+ @Override
public ConfigurationBuilder<T> setStatusLevel(final Level level) {
this.level = level;
return this;
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
705e2725/log4j-core/src/main/java/org/apache/logging/log4j/
core/config/composite/CompositeConfiguration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/composite/CompositeConfiguration.java b/log4j-core/src/main/java/
org/apache/logging/log4j/core/config/composite/CompositeConfiguration.java
index fa941d7..e38c62b 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/composite/CompositeConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/composite/CompositeConfiguration.java
@@ -87,6 +87,8 @@ public class CompositeConfiguration extends
AbstractConfiguration implements Rec
statusConfig.withDestination(value);
} else if ("shutdownHook".equalsIgnoreCase(key)) {
isShutdownHookEnabled = !"disable".equalsIgnoreCase(value);
+ } else if ("shutdownTimeout".equalsIgnoreCase(key)) {
+ shutdownTimeoutMillis = Long.parseLong(value);
} else if ("verbose".equalsIgnoreCase(key)) {
statusConfig.withVerbosity(value);
} else if ("packages".equalsIgnoreCase(key)) {
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
705e2725/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/
JsonConfiguration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/json/JsonConfiguration.java b/log4j-core/src/main/java/
org/apache/logging/log4j/core/config/json/JsonConfiguration.java
index 497496a..5b38dfb 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/json/JsonConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/json/JsonConfiguration.java
@@ -26,6 +26,9 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.AbstractConfiguration;
import org.apache.logging.log4j.core.config.Configuration;
@@ -40,10 +43,6 @@ import org.apache.logging.log4j.core.config.status.
StatusConfiguration;
import org.apache.logging.log4j.core.util.FileWatcher;
import org.apache.logging.log4j.core.util.Patterns;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
/**
* Creates a Node hierarchy from a JSON file.
*/
@@ -81,6 +80,8 @@ public class JsonConfiguration extends
AbstractConfiguration implements Reconfig
statusConfig.withDestination(value);
} else if ("shutdownHook".equalsIgnoreCase(key)) {
isShutdownHookEnabled = !"disable".equalsIgnoreCase(
value);
+ } else if ("shutdownTimeout".equalsIgnoreCase(key)) {
+ shutdownTimeoutMillis = Long.parseLong(value);
} else if ("verbose".equalsIgnoreCase(entry.getKey())) {
statusConfig.withVerbosity(value);
} else if ("packages".equalsIgnoreCase(key)) {
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
705e2725/log4j-core/src/main/java/org/apache/logging/log4j/
core/config/properties/PropertiesConfigurationBuilder.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/properties/PropertiesConfigurationBuilder.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/properties/
PropertiesConfigurationBuilder.java
index a4362b7..3d24a9b 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/properties/PropertiesConfigurationBuilder.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/properties/PropertiesConfigurationBuilder.java
@@ -19,6 +19,7 @@ package org.apache.logging.log4j.core.config.properties;
import java.util.Map;
import java.util.Properties;
+import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.Appender;
@@ -54,6 +55,7 @@ public class PropertiesConfigurationBuilder extends
ConfigurationBuilderFactory
private static final String ADVERTISER_KEY = "advertiser";
private static final String STATUS_KEY = "status";
private static final String SHUTDOWN_HOOK = "shutdownHook";
+ private static final String SHUTDOWN_TIMEOUT = "shutdownTimeout";
private static final String VERBOSE = "verbose";
private static final String DEST = "dest";
private static final String PACKAGES = "packages";
@@ -89,6 +91,7 @@ public class PropertiesConfigurationBuilder extends
ConfigurationBuilderFactory
builder
.setStatusLevel(Level.toLevel(rootProperties.getProperty(STATUS_KEY),
Level.ERROR))
.setShutdownHook(rootProperties.getProperty(SHUTDOWN_HOOK))
+ .setShutdownTimeout(Long.parseLong(rootProperties.getProperty(SHUTDOWN_TIMEOUT,
"0")), TimeUnit.MILLISECONDS)
.setVerbosity(rootProperties.getProperty(VERBOSE))
.setDestination(rootProperties.getProperty(DEST))
.setPackages(rootProperties.getProperty(PACKAGES))
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
705e2725/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/
XmlConfiguration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/xml/XmlConfiguration.java b/log4j-core/src/main/java/
org/apache/logging/log4j/core/config/xml/XmlConfiguration.java
index 2608552..51f31d4 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/xml/XmlConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/
config/xml/XmlConfiguration.java
@@ -24,7 +24,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
-
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -120,6 +119,8 @@ public class XmlConfiguration extends
AbstractConfiguration implements Reconfigu
statusConfig.withDestination(value);
} else if ("shutdownHook".equalsIgnoreCase(key)) {
isShutdownHookEnabled = !"disable".equalsIgnoreCase(
value);
+ } else if ("shutdownTimeout".equalsIgnoreCase(key)) {
+ shutdownTimeoutMillis = Long.parseLong(value);
} else if ("verbose".equalsIgnoreCase(key)) {
statusConfig.withVerbosity(value);
} else if ("packages".equalsIgnoreCase(key)) {
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
705e2725/log4j-core/src/test/java/org/apache/logging/log4j/core/
ShutdownTimeoutConfigurationTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/
ShutdownTimeoutConfigurationTest.java b/log4j-core/src/test/java/
org/apache/logging/log4j/core/ShutdownTimeoutConfigurationTest.java
new file mode 100644
index 0000000..5e0734c
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/
ShutdownTimeoutConfigurationTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class ShutdownTimeoutConfigurationTest {
+
+ private static final String CONFIG = "log4j-test-shutdownTimeout.xml";
+
+ @ClassRule
+ public static LoggerContextRule context = new
LoggerContextRule(CONFIG);
+
+ @Test
+ public void testShutdownFlag() {
+ final Configuration config = context.getConfiguration();
+ assertNotNull("No configuration", config);
+ assertEquals(5000, config.getShutdownTimeoutMillis());
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
705e2725/log4j-core/src/test/java/org/apache/logging/log4j/
core/config/builder/ConfigurationBuilderTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/
config/builder/ConfigurationBuilderTest.java b/log4j-core/src/test/java/
org/apache/logging/log4j/core/config/builder/ConfigurationBuilderTest.java
index 2d48605..431ac01 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/builder/
ConfigurationBuilderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/builder/
ConfigurationBuilderTest.java
@@ -16,6 +16,8 @@
*/
package org.apache.logging.log4j.core.config.builder;
+import java.util.concurrent.TimeUnit;
+
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
@@ -36,6 +38,7 @@ public class ConfigurationBuilderTest {
private void addTestFixtures(final String name, final
ConfigurationBuilder<BuiltConfiguration> builder) {
builder.setConfigurationName(name);
builder.setStatusLevel(Level.ERROR);
+ builder.setShutdownTimeout(5000, TimeUnit.MILLISECONDS);
builder.add(builder.newScriptFile("target/test-
classes/scripts/filter.groovy").addIsWatched(true));
builder.add(builder.newFilter("ThresholdFilter",
Filter.Result.ACCEPT, Filter.Result.NEUTRAL)
.addAttribute("level", Level.DEBUG));
@@ -56,7 +59,7 @@ public class ConfigurationBuilderTest {
private final static String expectedXml =
"<?xml version='1.0' encoding='UTF-8'?>" + EOL +
- "<Configuration name=\"config name\" status=\"ERROR\"
packages=\"foo,bar\">" + EOL +
+ "<Configuration name=\"config name\" status=\"ERROR\"
packages=\"foo,bar\" shutdownTimeout=\"5000\">" + EOL +
INDENT + "<Properties>" + EOL +
INDENT + INDENT + "<Property
name=\"MyKey\">MyValue</Property>"
+ EOL +
INDENT + "</Properties>" + EOL +
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
705e2725/log4j-core/src/test/resources/log4j-test-shutdownTimeout.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-test-shutdownTimeout.xml
b/log4j-core/src/test/resources/log4j-test-shutdownTimeout.xml
new file mode 100644
index 0000000..19b25c9
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-test-shutdownTimeout.xml
@@ -0,0 +1,38 @@
+<?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="XMLConfigTest" monitorInterval="5"
shutdownTimeout="5000">
+ <Appenders>
+ <Console name="STDOUT">
+ <PatternLayout pattern="%m MDC%X%n"/>
+ </Console>
+ <List name="List">
+ </List>
+ </Appenders>
+
+ <Loggers>
+ <Logger name="org.apache.logging.log4j.test1" level="debug"
additivity="false">
+ <AppenderRef ref="STDOUT"/>
+ </Logger>>
+
+ <Root level="trace">
+ <AppenderRef ref="List"/>
+ </Root>
+ </Loggers>
+
+</Configuration>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
705e2725/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index cd2f379..6bd144c 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -23,6 +23,11 @@
<title>Changes</title>
</properties>
<body>
+ <release version="2.7.1" date="2016-XX-XX" description="GA Release
2.7.1">
+ <action issue="LOG4J2-1623" dev="mikes" type="fix">
+ Configurable JVM shutdown hook timeout.
+ </action>
+ </release>
<release version="2.7" date="2016-10-02" description="GA Release 2.7">
<action issue="LOG4J2-1618" dev="rpopma" type="fix" due-to="Raman
Gupta">
Fixed ClassCastException when using JUL logging during shutdown.
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
705e2725/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 60419a4..acd41fd 100644
--- a/src/site/xdoc/manual/configuration.xml.vm
+++ b/src/site/xdoc/manual/configuration.xml.vm
@@ -408,6 +408,10 @@ public class Bar {
shutdown hook is enabled by default but may be disabled
by setting this attribute to "disable"</td>
</tr>
<tr>
+ <td>shutdownTimeout</td>
+ <td>Specifies how many milliseconds appenders and other
plugins will get to shutdown when the JVM shuts down.
+ Default is zero. (Not used if <tt>shutdownHook</tt> is
set to "disable".)</td>
+ <tr>
<td>status</td>
<td>The level of internal Log4j events that should be
logged to the console.
Valid values for this attribute are "trace", "debug",
"info", "warn", "error" and "fatal".
@@ -841,8 +845,8 @@ public class Bar {
</p>
<p>
Properties configuration files support the advertiser,
monitorInterval, name, packages, shutdownHook,
- status, verbose, and dest attrbutes. See <a
href="#ConfigurationSyntax">Configuration Syntax</a> for the
- definitions of these attributes.
+ shutdownTimeout, status, verbose, and dest attrbutes. See <a
href="#ConfigurationSyntax">Configuration Syntax</a>
+ for the definitions of these attributes.
</p>
<pre class="prettyprint linenums">
status = error
--
E-Mail: garydgregory@gmail.com | ggregory@apache.org
Java Persistence with Hibernate, Second Edition
<http://www.manning.com/bauer3/>
JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
Spring Batch in Action <http://www.manning.com/templier/>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory