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/08/21 13:45:22 UTC
logging-log4j2 git commit: Fix XML configuration formatting
Repository: logging-log4j2
Updated Branches:
refs/heads/LOG4J2-1528 b1e8f6f3e -> 872359805
Fix XML configuration formatting
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/87235980
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/87235980
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/87235980
Branch: refs/heads/LOG4J2-1528
Commit: 8723598057dd938be060961988f6d460f82dfe90
Parents: b1e8f6f
Author: Mikael St�ldal <mi...@staldal.nu>
Authored: Sun Aug 21 15:44:28 2016 +0200
Committer: Mikael St�ldal <mi...@staldal.nu>
Committed: Sun Aug 21 15:44:28 2016 +0200
----------------------------------------------------------------------
.../core/config/AbstractConfiguration.java | 189 +++++++++++++++++--
.../impl/DefaultConfigurationBuilder.java | 27 ++-
.../builder/ConfigurationBuilderTest.java | 58 +++++-
3 files changed, 245 insertions(+), 29 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/87235980/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 a152ea7..f123991 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
@@ -16,24 +16,6 @@
*/
package org.apache.logging.log4j.core.config;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-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.core.Appender;
import org.apache.logging.log4j.core.Filter;
@@ -65,6 +47,29 @@ import org.apache.logging.log4j.core.util.NanoClock;
import org.apache.logging.log4j.core.util.WatchManager;
import org.apache.logging.log4j.util.PropertiesUtil;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
/**
* The base Configuration. Many configuration implementations will extend this class.
*/
@@ -181,6 +186,154 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement
return rootNode;
}
+ private static final List<String> SECTION_NAMES =
+ Arrays.asList("Properties", "Scripts", "CustomLevels", "Filters", "Appenders", "Loggers");
+
+ public void writeXmlConfiguration(final OutputStream output) throws IOException {
+ try {
+ XMLStreamWriter xmlWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(output);
+ writeXmlConfiguration(xmlWriter);
+ xmlWriter.close();
+ } catch (XMLStreamException e) {
+ if (e.getNestedException() instanceof IOException) {
+ throw (IOException)e.getNestedException();
+ } else {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public String toXmlConfiguration() {
+ StringWriter sw = new StringWriter();
+ try {
+ XMLStreamWriter xmlWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(sw);
+ writeXmlConfiguration(xmlWriter);
+ xmlWriter.close();
+ } catch (XMLStreamException e) {
+ throw new RuntimeException(e);
+ }
+ return sw.toString();
+ }
+
+ private void writeXmlConfiguration(XMLStreamWriter xmlWriter) throws XMLStreamException {
+ xmlWriter.writeStartDocument();
+ xmlWriter.writeCharacters(System.lineSeparator());
+
+ xmlWriter.writeStartElement("Configuration");
+
+ if (name != null) {
+ xmlWriter.writeAttribute("name", getName());
+ }
+ /* TODO status logger config
+ if (level != null) {
+ xmlWriter.writeAttribute("status", level.name());
+ }
+ if (verbosity != null) {
+ xmlWriter.writeAttribute("verbose", verbosity);
+ }
+ if (destination != null) {
+ xmlWriter.writeAttribute("dest", destination);
+ }
+ */
+ if (!getPluginPackages().isEmpty()) {
+ xmlWriter.writeAttribute("packages", getPluginPackages().toString()); // TODO comma-separated string
+ }
+ if (!isShutdownHookEnabled()) {
+ xmlWriter.writeAttribute("shutdownHook", "disable");
+ }
+ if (advertiserNode != null) {
+ xmlWriter.writeAttribute("advertiser", advertiserNode.getName());
+ }
+ if (getWatchManager().getIntervalSeconds() > 0) {
+ xmlWriter.writeAttribute("monitorInterval", String.valueOf(getWatchManager().getIntervalSeconds()));
+ }
+
+ xmlWriter.writeCharacters(System.lineSeparator());
+
+ writeXmlSection(xmlWriter, lookupSection("Properties"));
+ writeXmlSection(xmlWriter, lookupSection("Scripts"));
+ writeXmlSection(xmlWriter, lookupSection("CustomLevels")); // TODO customLevel level vs intLevel
+ Node filters = lookupSection("Filters");
+ if (filters != null) {
+ writeXmlSection(xmlWriter, filters);
+ } else {
+ Node filter = lookupFilter();
+ if (filter != null) {
+ writeXmlNode(xmlWriter, filter, 1);
+ }
+ }
+
+ writeXmlSection(xmlWriter, lookupSection("Appenders"));
+ writeXmlSection(xmlWriter, lookupSection("Loggers"));
+
+ xmlWriter.writeEndElement(); // "Configuration"
+ xmlWriter.writeCharacters(System.lineSeparator());
+
+ xmlWriter.writeEndDocument();
+ }
+
+ private Node lookupSection(String name) {
+ for (final Node child : rootNode.getChildren()) {
+ if (child.getName().equalsIgnoreCase(name)) {
+ return child;
+ }
+ }
+ return null;
+ }
+
+ private Node lookupFilter() {
+ for (final Node child : rootNode.getChildren()) {
+ if (!SECTION_NAMES.contains(child.getName())) {
+ return child;
+ }
+ }
+ return null;
+ }
+
+ private void writeXmlSection(XMLStreamWriter xmlWriter, Node node) throws XMLStreamException {
+ if (node != null && (!node.getAttributes().isEmpty() || !node.getChildren().isEmpty() || node.getValue() != null)) {
+ writeXmlNode(xmlWriter, node, 1);
+ }
+ }
+
+ private void writeXmlNode(XMLStreamWriter xmlWriter, Node node, int nesting) throws XMLStreamException {
+ if (!node.getChildren().isEmpty() || node.getValue() != null) {
+ writeXmlIndent(xmlWriter, nesting);
+ xmlWriter.writeStartElement(node.getName());
+ writeXmlAttributes(xmlWriter, node);
+ if (!node.getChildren().isEmpty()) {
+ xmlWriter.writeCharacters(System.lineSeparator());
+ }
+ for (Node childNode : node.getChildren()) {
+ writeXmlNode(xmlWriter, childNode, nesting + 1);
+ }
+ if (node.getValue() != null) {
+ xmlWriter.writeCharacters(node.getValue());
+ }
+ if (!node.getChildren().isEmpty()) {
+ writeXmlIndent(xmlWriter, nesting);
+ }
+ xmlWriter.writeEndElement();
+ } else {
+ writeXmlIndent(xmlWriter, nesting);
+ xmlWriter.writeEmptyElement(node.getName());
+ writeXmlAttributes(xmlWriter, node);
+ }
+ xmlWriter.writeCharacters(System.lineSeparator());
+ }
+
+ private void writeXmlIndent(XMLStreamWriter xmlWriter, int nesting) throws XMLStreamException {
+ for (int i = 0; i < nesting; i++) {
+ xmlWriter.writeCharacters("\t");
+ }
+ }
+
+ private void writeXmlAttributes(XMLStreamWriter xmlWriter, Node node) throws XMLStreamException {
+ for (Map.Entry<String, String> attribute : node.getAttributes().entrySet()) {
+ xmlWriter.writeAttribute(attribute.getKey(), attribute.getValue());
+ }
+ }
+
@Override
public AsyncLoggerConfigDelegate getAsyncLoggerConfigDelegate() {
// lazily instantiate only when requested by AsyncLoggers:
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/87235980/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 47688f7..e3de1ae 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
@@ -255,11 +255,16 @@ public class DefaultConfigurationBuilder<T extends BuiltConfiguration> implement
xmlWriter.writeCharacters(System.lineSeparator());
- for (Component component : root.getComponents()) {
- if (!component.getAttributes().isEmpty() || !component.getComponents().isEmpty() || component.getValue() != null) {
- writeXmlComponent(xmlWriter, component, 1);
- }
+ writeXmlSection(xmlWriter, properties);
+ writeXmlSection(xmlWriter, scripts);
+ writeXmlSection(xmlWriter, customLevels); // TODO customLevel level vs intLevel
+ if (filters.getComponents().size() == 1) {
+ writeXmlComponent(xmlWriter, filters.getComponents().get(0), 1);
+ } else if (filters.getComponents().size() > 1) {
+ writeXmlSection(xmlWriter, filters);
}
+ writeXmlSection(xmlWriter, appenders);
+ writeXmlSection(xmlWriter, loggers);
xmlWriter.writeEndElement(); // "Configuration"
xmlWriter.writeCharacters(System.lineSeparator());
@@ -267,19 +272,29 @@ public class DefaultConfigurationBuilder<T extends BuiltConfiguration> implement
xmlWriter.writeEndDocument();
}
+ private void writeXmlSection(XMLStreamWriter xmlWriter, Component component) throws XMLStreamException {
+ if (!component.getAttributes().isEmpty() || !component.getComponents().isEmpty() || component.getValue() != null) {
+ writeXmlComponent(xmlWriter, component, 1);
+ }
+ }
+
private void writeXmlComponent(XMLStreamWriter xmlWriter, Component component, int nesting) throws XMLStreamException {
if (!component.getComponents().isEmpty() || component.getValue() != null) {
writeXmlIndent(xmlWriter, nesting);
xmlWriter.writeStartElement(component.getPluginType());
writeXmlAttributes(xmlWriter, component);
- xmlWriter.writeCharacters(System.lineSeparator());
+ if (!component.getComponents().isEmpty()) {
+ xmlWriter.writeCharacters(System.lineSeparator());
+ }
for (Component subComponent : component.getComponents()) {
writeXmlComponent(xmlWriter, subComponent, nesting + 1);
}
if (component.getValue() != null) {
xmlWriter.writeCharacters(component.getValue());
}
- writeXmlIndent(xmlWriter, nesting);
+ if (!component.getComponents().isEmpty()) {
+ writeXmlIndent(xmlWriter, nesting);
+ }
xmlWriter.writeEndElement();
} else {
writeXmlIndent(xmlWriter, nesting);
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/87235980/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 3d8c4d2..b4b2bff 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 org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.config.AbstractConfiguration;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
@@ -25,15 +27,19 @@ import static org.junit.Assert.assertEquals;
public class ConfigurationBuilderTest {
- private final static String expectedXml =
+ private final static String expectedXml1 =
"<?xml version='1.0' encoding='UTF-8'?>" + System.lineSeparator() +
"<Configuration name=\"config name\" status=\"ERROR\">" + System.lineSeparator() +
+ "\t<Properties>" + System.lineSeparator() +
+ "\t\t<Property name=\"MyKey\">MyValue</Property>" + System.lineSeparator() +
+ "\t</Properties>" + System.lineSeparator() +
"\t<Scripts>" + System.lineSeparator() +
"\t\t<ScriptFile path=\"target/test-classes/scripts/filter.groovy\" name=\"target/test-classes/scripts/filter.groovy\" isWatched=\"true\"/>" + System.lineSeparator() +
"\t</Scripts>" + System.lineSeparator() +
- "\t<Filters>" + System.lineSeparator() +
- "\t\t<ThresholdFilter onMatch=\"ACCEPT\" level=\"DEBUG\" onMisMatch=\"NEUTRAL\"/>" + System.lineSeparator() +
- "\t</Filters>" + System.lineSeparator() +
+ "\t<CustomLevels>" + System.lineSeparator() +
+ "\t\t<CustomLevel intLevel=\"17\" name=\"Panic\"/>" + System.lineSeparator() +
+ "\t</CustomLevels>" + System.lineSeparator() +
+ "\t<ThresholdFilter onMatch=\"ACCEPT\" level=\"DEBUG\" onMisMatch=\"NEUTRAL\"/>" + System.lineSeparator() +
"\t<Appenders>" + System.lineSeparator() +
"\t\t<CONSOLE name=\"Stdout\" target=\"SYSTEM_OUT\">" + System.lineSeparator() +
"\t\t\t<PatternLayout pattern=\"%d [%t] %-5level: %msg%n%throwable\"/>" + System.lineSeparator() +
@@ -54,8 +60,50 @@ public class ConfigurationBuilderTest {
public void testXmlConstructing() throws Exception {
final ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
CustomConfigurationFactory.addTestFixtures("config name", builder);
+ builder.addProperty("MyKey", "MyValue");
+ builder.add(builder.newCustomLevel("Panic", 17));
final String xmlConfiguration = builder.toXmlConfiguration();
- assertEquals(expectedXml, xmlConfiguration);
+ assertEquals(expectedXml1, xmlConfiguration);
}
+ private final static String expectedXml2 =
+ "<?xml version='1.0' encoding='UTF-8'?>" + System.lineSeparator() +
+ "<Configuration name=\"config name\" status=\"ERROR\">" + System.lineSeparator() +
+ "\t<Properties>" + System.lineSeparator() +
+ "\t\t<Property name=\"MyKey\">MyValue</Property>" + System.lineSeparator() +
+ "\t</Properties>" + System.lineSeparator() +
+ "\t<Scripts>" + System.lineSeparator() +
+ "\t\t<ScriptFile name=\"target/test-classes/scripts/filter.groovy\" path=\"target/test-classes/scripts/filter.groovy\" isWatched=\"true\"/>" + System.lineSeparator() +
+ "\t</Scripts>" + System.lineSeparator() +
+ "\t<CustomLevels>" + System.lineSeparator() +
+ "\t\t<CustomLevel name=\"Panic\" intLevel=\"17\"/>" + System.lineSeparator() +
+ "\t</CustomLevels>" + System.lineSeparator() +
+ "\t<ThresholdFilter onMatch=\"ACCEPT\" level=\"DEBUG\" onMisMatch=\"NEUTRAL\"/>" + System.lineSeparator() +
+ "\t<Appenders>" + System.lineSeparator() +
+ "\t\t<CONSOLE name=\"Stdout\" target=\"SYSTEM_OUT\">" + System.lineSeparator() +
+ "\t\t\t<PatternLayout pattern=\"%d [%t] %-5level: %msg%n%throwable\"/>" + System.lineSeparator() +
+ "\t\t\t<MarkerFilter onMatch=\"DENY\" onMisMatch=\"NEUTRAL\" marker=\"FLOW\"/>" + System.lineSeparator() +
+ "\t\t</CONSOLE>" + System.lineSeparator() +
+ "\t</Appenders>" + System.lineSeparator() +
+ "\t<Loggers>" + System.lineSeparator() +
+ "\t\t<Logger name=\"org.apache.logging.log4j\" additivity=\"false\" level=\"DEBUG\" includeLocation=\"true\">" + System.lineSeparator() +
+ "\t\t\t<AppenderRef ref=\"Stdout\"/>" + System.lineSeparator() +
+ "\t\t</Logger>" + System.lineSeparator() +
+ "\t\t<Root level=\"ERROR\" includeLocation=\"true\">" + System.lineSeparator() +
+ "\t\t\t<AppenderRef ref=\"Stdout\"/>" + System.lineSeparator() +
+ "\t\t</Root>" + System.lineSeparator() +
+ "\t</Loggers>" + System.lineSeparator() +
+ "</Configuration>" + System.lineSeparator();
+
+ @Test
+ public void testXmlConstructingWithAbstractConfiguration() throws Exception {
+ final ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
+ CustomConfigurationFactory.addTestFixtures("config name", builder);
+ builder.addProperty("MyKey", "MyValue");
+ builder.add(builder.newCustomLevel("Panic", 17));
+ AbstractConfiguration configuration = builder.build(false);
+ configuration.setup();
+ final String xmlConfiguration = configuration.toXmlConfiguration();
+ assertEquals(expectedXml2, xmlConfiguration);
+ }
}