You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rg...@apache.org on 2015/09/23 20:42:24 UTC
logging-log4j2 git commit: LOG4J2-1129 - Allow PatternLayout to
select a pattern to use based on some selection criteria
Repository: logging-log4j2
Updated Branches:
refs/heads/master fee199f66 -> fe021d94b
LOG4J2-1129 - Allow PatternLayout to select a pattern to use based on some selection criteria
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/fe021d94
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/fe021d94
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/fe021d94
Branch: refs/heads/master
Commit: fe021d94b385c52eb91b486bd26120630efef53d
Parents: fee199f
Author: Ralph Goers <rg...@nextiva.com>
Authored: Wed Sep 23 11:42:02 2015 -0700
Committer: Ralph Goers <rg...@nextiva.com>
Committed: Wed Sep 23 11:42:02 2015 -0700
----------------------------------------------------------------------
.../core/layout/MarkerPatternSelector.java | 125 +++++++++++++++
.../log4j/core/layout/PatternLayout.java | 97 +++++++++---
.../logging/log4j/core/layout/PatternMatch.java | 154 +++++++++++++++++++
.../log4j/core/layout/PatternSelector.java | 30 ++++
.../logging/log4j/core/PatternSelectorTest.java | 53 +++++++
.../core/appender/ConsoleAppenderTest.java | 2 +-
.../log4j/core/layout/PatternLayoutTest.java | 37 ++++-
.../test/resources/log4j-patternSelector.xml | 33 ++++
.../log4j/perf/jmh/PatternLayoutBenchmark.java | 16 +-
.../jmh/PatternLayoutComparisonBenchmark.java | 2 +-
src/changes/changes.xml | 3 +
11 files changed, 517 insertions(+), 35 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/fe021d94/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/MarkerPatternSelector.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/MarkerPatternSelector.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/MarkerPatternSelector.java
new file mode 100644
index 0000000..f54cf3a
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/MarkerPatternSelector.java
@@ -0,0 +1,125 @@
+/*
+ * 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.layout;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.Node;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.core.pattern.PatternFormatter;
+import org.apache.logging.log4j.core.pattern.PatternParser;
+import org.apache.logging.log4j.core.util.KeyValuePair;
+import org.apache.logging.log4j.status.StatusLogger;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Selects the pattern to use based on the Marker in the LogEvent.
+ */
+@Plugin(name = "MarkerPatternSelector", category = Node.CATEGORY, elementType = PatternSelector.ELEMENT_TYPE, printObject = true)
+public class MarkerPatternSelector implements PatternSelector {
+
+ private final Map<String, PatternFormatter[]> formatterMap = new HashMap<>();
+
+ private final Map<String, String> patternMap = new HashMap<>();
+
+ private final PatternFormatter[] defaultFormatters;
+
+ private final String defaultPattern;
+
+ private static Logger LOGGER = StatusLogger.getLogger();
+
+
+ public MarkerPatternSelector(final PatternMatch[] properties, final String defaultPattern,
+ final boolean alwaysWriteExceptions, final boolean noConsoleNoAnsi,
+ final Configuration config) {
+ final PatternParser parser = PatternLayout.createPatternParser(config);
+ for (PatternMatch property : properties) {
+ try {
+ List<PatternFormatter> list = parser.parse(property.getPattern(), alwaysWriteExceptions, noConsoleNoAnsi);
+ formatterMap.put(property.getKey(), list.toArray(new PatternFormatter[list.size()]));
+ patternMap.put(property.getKey(), property.getPattern());
+ } catch (RuntimeException ex) {
+ throw new IllegalArgumentException("Cannot parse pattern '" + property.getPattern() + "'", ex);
+ }
+ }
+ try {
+ List<PatternFormatter> list = parser.parse(defaultPattern, alwaysWriteExceptions, noConsoleNoAnsi);
+ defaultFormatters = list.toArray(new PatternFormatter[list.size()]);
+ this.defaultPattern = defaultPattern;
+ } catch (RuntimeException ex) {
+ throw new IllegalArgumentException("Cannot parse pattern '" + defaultPattern + "'", ex);
+ }
+ }
+
+ @Override
+ public PatternFormatter[] getFormatters(LogEvent event) {
+ Marker marker = event.getMarker();
+ if (marker == null) {
+ return defaultFormatters;
+ }
+ for (String key : formatterMap.keySet()) {
+ if (marker.isInstanceOf(key)) {
+ return formatterMap.get(key);
+ }
+ }
+ return defaultFormatters;
+ }
+
+
+ @PluginFactory
+ public static MarkerPatternSelector createSelector(@PluginElement("PatternMatch") final PatternMatch[] properties,
+ @PluginAttribute("defaultPattern") String defaultPattern,
+ @PluginAttribute(value = "alwaysWriteExceptions", defaultBoolean = true) final boolean alwaysWriteExceptions,
+ @PluginAttribute(value = "noConsoleNoAnsi", defaultBoolean = false) final boolean noConsoleNoAnsi,
+ @PluginConfiguration final Configuration config) {
+ if (defaultPattern == null) {
+ defaultPattern = PatternLayout.DEFAULT_CONVERSION_PATTERN;
+ }
+ if (properties == null || properties.length == 0) {
+ LOGGER.warn("No marker patterns were provided");
+ }
+ return new MarkerPatternSelector(properties, defaultPattern, alwaysWriteExceptions,
+ noConsoleNoAnsi, config);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ boolean first = true;
+ for (Map.Entry<String, String> entry : patternMap.entrySet()) {
+ if (!first) {
+ sb.append(", ");
+ }
+ sb.append("key=\"").append(entry.getKey()).append("\", pattern=\"").append(entry.getValue()).append("\"");
+ first = false;
+ }
+ if (!first) {
+ sb.append(", ");
+ }
+ sb.append("default=\"").append(defaultPattern).append("\"");
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/fe021d94/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
index 4ea5627..e5b78d3 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
@@ -93,6 +93,10 @@ public final class PatternLayout extends AbstractStringLayout {
*/
private final String conversionPattern;
+ private final PatternSelector patternSelector;
+
+ private final Serializer serializer;
+
/**
* The current Configuration.
@@ -111,6 +115,7 @@ public final class PatternLayout extends AbstractStringLayout {
* @param config The Configuration.
* @param replace The regular expression to match.
* @param pattern conversion pattern.
+ * @param patternSelector The PatternSelector.
* @param charset The character set.
* @param alwaysWriteExceptions Whether or not exceptions should always be handled in this pattern (if {@code true},
* exceptions will be written even if the pattern does not specify so).
@@ -119,21 +124,29 @@ public final class PatternLayout extends AbstractStringLayout {
* @param header
*/
private PatternLayout(final Configuration config, final RegexReplacement replace, final String pattern,
- final Charset charset, final boolean alwaysWriteExceptions, final boolean noConsoleNoAnsi,
+ final PatternSelector patternSelector, final Charset charset,
+ final boolean alwaysWriteExceptions, final boolean noConsoleNoAnsi,
final String header, final String footer) {
super(charset, toBytes(header, charset), toBytes(footer, charset));
this.replace = replace;
this.conversionPattern = pattern;
+ this.patternSelector = patternSelector;
this.config = config;
this.alwaysWriteExceptions = alwaysWriteExceptions;
this.noConsoleNoAnsi = noConsoleNoAnsi;
- final PatternParser parser = createPatternParser(config);
- try {
- List<PatternFormatter> list = parser.parse(pattern == null ? DEFAULT_CONVERSION_PATTERN : pattern,
- this.alwaysWriteExceptions, this.noConsoleNoAnsi);
- this.formatters = list.toArray(new PatternFormatter[0]);
- } catch (RuntimeException ex) {
- throw new IllegalArgumentException("Cannot parse pattern '" + pattern + "'", ex);
+ if (patternSelector == null) {
+ serializer = new PatternSerializer();
+ final PatternParser parser = createPatternParser(config);
+ try {
+ List<PatternFormatter> list = parser.parse(pattern == null ? DEFAULT_CONVERSION_PATTERN : pattern,
+ this.alwaysWriteExceptions, this.noConsoleNoAnsi);
+ this.formatters = list.toArray(new PatternFormatter[0]);
+ } catch (RuntimeException ex) {
+ throw new IllegalArgumentException("Cannot parse pattern '" + pattern + "'", ex);
+ }
+ } else {
+ this.formatters = null;
+ serializer = new PatternSelectorSerializer();
}
}
@@ -191,16 +204,7 @@ public final class PatternLayout extends AbstractStringLayout {
*/
@Override
public String toSerializable(final LogEvent event) {
- final StringBuilder buf = prepareStringBuilder(strBuilder);
- final int len = formatters.length;
- for (int i = 0; i < len; i++) {
- formatters[i].format(event, buf);
- }
- String str = buf.toString();
- if (replace != null) {
- str = replace.format(str);
- }
- return str;
+ return serializer.toSerializable(event);
}
/**
@@ -223,7 +227,7 @@ public final class PatternLayout extends AbstractStringLayout {
@Override
public String toString() {
- return conversionPattern;
+ return patternSelector == null ? conversionPattern : patternSelector.toString();
}
/**
@@ -250,6 +254,7 @@ public final class PatternLayout extends AbstractStringLayout {
@PluginFactory
public static PatternLayout createLayout(
@PluginAttribute(value = "pattern", defaultString = DEFAULT_CONVERSION_PATTERN) final String pattern,
+ @PluginElement("PatternSelector") final PatternSelector patternSelector,
@PluginConfiguration final Configuration config,
@PluginElement("Replace") final RegexReplacement replace,
@PluginAttribute(value = "charset", defaultString = "UTF-8") final Charset charset,
@@ -259,6 +264,7 @@ public final class PatternLayout extends AbstractStringLayout {
@PluginAttribute("footer") final String footer) {
return newBuilder()
.withPattern(pattern)
+ .withPatternSelector(patternSelector)
.withConfiguration(config)
.withRegexReplacement(replace)
.withCharset(charset)
@@ -269,6 +275,47 @@ public final class PatternLayout extends AbstractStringLayout {
.build();
}
+
+ private interface Serializer {
+
+ String toSerializable(final LogEvent event);
+ }
+
+ private class PatternSerializer implements Serializer {
+ @Override
+ public String toSerializable(final LogEvent event) {
+ final StringBuilder buf = strBuilder.get();
+ buf.setLength(0);
+ final int len = formatters.length;
+ for (int i = 0; i < len; i++) {
+ formatters[i].format(event, buf);
+ }
+ String str = buf.toString();
+ if (replace != null) {
+ str = replace.format(str);
+ }
+ return str;
+ }
+ }
+
+ private class PatternSelectorSerializer implements Serializer {
+ @Override
+ public String toSerializable(final LogEvent event) {
+ final StringBuilder buf = strBuilder.get();
+ buf.setLength(0);
+ PatternFormatter[] formatters = patternSelector.getFormatters(event);
+ final int len = formatters.length;
+ for (int i = 0; i < len; i++) {
+ formatters[i].format(event, buf);
+ }
+ String str = buf.toString();
+ if (replace != null) {
+ str = replace.format(str);
+ }
+ return str;
+ }
+ }
+
/**
* Creates a PatternLayout using the default options. These options include using UTF-8, the default conversion
* pattern, exceptions being written, and with ANSI escape codes.
@@ -300,6 +347,9 @@ public final class PatternLayout extends AbstractStringLayout {
@PluginBuilderAttribute
private String pattern = PatternLayout.DEFAULT_CONVERSION_PATTERN;
+ @PluginElement("PatternSelector")
+ private PatternSelector patternSelector = null;
+
@PluginConfiguration
private Configuration configuration = null;
@@ -332,6 +382,11 @@ public final class PatternLayout extends AbstractStringLayout {
return this;
}
+ public Builder withPatternSelector(final PatternSelector patternSelector) {
+ this.patternSelector = patternSelector;
+ return this;
+ }
+
public Builder withConfiguration(final Configuration configuration) {
this.configuration = configuration;
@@ -374,8 +429,8 @@ public final class PatternLayout extends AbstractStringLayout {
if (configuration == null) {
configuration = new DefaultConfiguration();
}
- return new PatternLayout(configuration, regexReplacement, pattern, charset, alwaysWriteExceptions,
- noConsoleNoAnsi, header, footer);
+ return new PatternLayout(configuration, regexReplacement, pattern, patternSelector, charset,
+ alwaysWriteExceptions, noConsoleNoAnsi, header, footer);
}
}
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/fe021d94/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternMatch.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternMatch.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternMatch.java
new file mode 100644
index 0000000..2633c54
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternMatch.java
@@ -0,0 +1,154 @@
+/*
+ * 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.layout;
+
+import org.apache.logging.log4j.core.config.Node;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
+/**
+ * PatternMatch configuration item.
+ *
+ * @since 2.4.1 implements {@link Serializable}
+ */
+@Plugin(name = "PatternMatch", category = Node.CATEGORY, printObject = true)
+public final class PatternMatch implements Serializable {
+
+ private static final long serialVersionUID = 4331228262821046877L;
+
+ private final String key;
+ private final String pattern;
+
+ /**
+ * Constructs a key/value pair. The constructor should only be called from test classes.
+ * @param key The key.
+ * @param pattern The value.
+ */
+ public PatternMatch(final String key, final String pattern) {
+ this.key = key;
+ this.pattern = pattern;
+ }
+
+ /**
+ * Returns the key.
+ * @return the key.
+ */
+ public String getKey() {
+ return key;
+ }
+
+ /**
+ * Returns the pattern.
+ * @return The pattern.
+ */
+ public String getPattern() {
+ return pattern;
+ }
+
+ @Override
+ public String toString() {
+ return key + '=' + pattern;
+ }
+
+ @PluginBuilderFactory
+ public static Builder newBuilder() {
+ return new Builder();
+ }
+
+ protected Object writeReplace() throws ObjectStreamException {
+ return newBuilder().setKey(this.key).setPattern(this.pattern);
+ }
+
+ private void readObject(final ObjectInputStream stream) throws InvalidObjectException {
+ throw new InvalidObjectException("Builder proxy required");
+ }
+
+ public static class Builder implements org.apache.logging.log4j.core.util.Builder<PatternMatch>, Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @PluginBuilderAttribute
+ private String key;
+
+ @PluginBuilderAttribute
+ private String pattern;
+
+ public Builder setKey(final String key) {
+ this.key = key;
+ return this;
+ }
+
+ public Builder setPattern(final String pattern) {
+ this.pattern = pattern;
+ return this;
+ }
+
+ @Override
+ public PatternMatch build() {
+ return new PatternMatch(key, pattern);
+ }
+
+ protected Object readResolve() throws ObjectStreamException {
+ return new PatternMatch(key, pattern);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((key == null) ? 0 : key.hashCode());
+ result = prime * result + ((pattern == null) ? 0 : pattern.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final PatternMatch other = (PatternMatch) obj;
+ if (key == null) {
+ if (other.key != null) {
+ return false;
+ }
+ } else if (!key.equals(other.key)) {
+ return false;
+ }
+ if (pattern == null) {
+ if (other.pattern != null) {
+ return false;
+ }
+ } else if (!pattern.equals(other.pattern)) {
+ return false;
+ }
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/fe021d94/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternSelector.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternSelector.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternSelector.java
new file mode 100644
index 0000000..78c9b49
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternSelector.java
@@ -0,0 +1,30 @@
+/*
+ * 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.layout;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.pattern.PatternFormatter;
+
+/**
+ * Allows different patterns to be used with the PatternLayout based on some selection criteria.
+ */
+public interface PatternSelector {
+
+ String ELEMENT_TYPE = "patternSelector";
+
+ PatternFormatter[] getFormatters(LogEvent event);
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/fe021d94/log4j-core/src/test/java/org/apache/logging/log4j/core/PatternSelectorTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/PatternSelectorTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/PatternSelectorTest.java
new file mode 100644
index 0000000..06a5ef3
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/PatternSelectorTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.LogManager;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.test.appender.ListAppender;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.junit.Assert.*;
+/**
+ *
+ */
+public class PatternSelectorTest {
+
+
+ private static final String CONFIG = "log4j-patternSelector.xml";
+
+ @ClassRule
+ public static LoggerContextRule context = new LoggerContextRule(CONFIG);
+
+ @Test
+ public void testPatternSelector() throws Exception {
+ org.apache.logging.log4j.Logger logger = LogManager.getLogger("TestPatternSelector");
+ logger.entry();
+ logger.info("Hello World");
+ logger.exit();
+ final ListAppender app = (ListAppender) context.getRequiredAppender("List");
+ assertNotNull("No ListAppender", app);
+ List<String> messages = app.getMessages();
+ assertNotNull("No Messages", messages);
+ assertTrue("Incorrect number of messages. Expected 3, Actual " + messages.size(), messages.size() == 3);
+ assertEquals("[TRACE] TestPatternSelector ====== o.a.l.l.c.PatternSelectorTest.testPatternSelector:42 entry ======\n", messages.get(0));
+ assertEquals("[INFO ] TestPatternSelector Hello World\n", messages.get(1));
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/fe021d94/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java
index 0c002a0..16417b9 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java
@@ -98,7 +98,7 @@ public class ConsoleAppenderTest {
mocks.replayAll();
systemSetter.systemSet(psMock);
- final Layout<String> layout = PatternLayout.createLayout(null, null, null, null, false, false, null, null);
+ final Layout<String> layout = PatternLayout.createLayout(null, null, null, null, null, false, false, null, null);
final ConsoleAppender app = ConsoleAppender.createAppender(layout, null, targetName, "Console", "false",
"false");
app.start();
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/fe021d94/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java
index bac234c..296492b 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java
@@ -24,14 +24,14 @@ import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.core.BasicConfigurationFactory;
-import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.Logger;
-import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.*;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
+import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.core.lookup.MainMapLookup;
+import org.apache.logging.log4j.core.util.KeyValuePair;
import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.util.Strings;
import org.junit.After;
@@ -263,4 +263,33 @@ public class PatternLayoutTest {
.withConfiguration(ctx.getConfiguration()).withCharset(StandardCharsets.UTF_8).build();
assertEquals(StandardCharsets.UTF_8, layout.getCharset());
}
+
+ @Test
+ public void testPatternSelector() throws Exception {
+ PatternMatch[] patterns = new PatternMatch[1];
+ patterns[0] = new PatternMatch("FLOW", "%d %-5p [%t]: ====== %C{1}.%M:%L %m ======%n");
+ PatternSelector selector = MarkerPatternSelector.createSelector(patterns, "%d %-5p [%t]: %m%n", true, true, ctx.getConfiguration());
+ final PatternLayout layout = PatternLayout.newBuilder().withPatternSelector(selector)
+ .withConfiguration(ctx.getConfiguration()).build();
+ final LogEvent event1 = Log4jLogEvent.newBuilder() //
+ .setLoggerName(this.getClass().getName()).setLoggerFqcn("org.apache.logging.log4j.core.layout.PatternLayoutTest$FauxLogger")
+ .setMarker(MarkerManager.getMarker("FLOW"))
+ .setLevel(Level.TRACE) //
+ .setIncludeLocation(true)
+ .setMessage(new SimpleMessage("entry")).build();
+ final String result1 = new FauxLogger().formatEvent(event1, layout);
+ assertTrue("Unexpected result: " + result1, result1.endsWith("====== PatternLayoutTest.testPatternSelector:280 entry ======\n"));
+ final LogEvent event2 = Log4jLogEvent.newBuilder() //
+ .setLoggerName(this.getClass().getName()).setLoggerFqcn("org.apache.logging.log4j.core.Logger") //
+ .setLevel(Level.INFO) //
+ .setMessage(new SimpleMessage("Hello, world 1!")).build();
+ final String result2 = new String(layout.toByteArray(event2));
+ assertTrue("Unexpected result: " + result2, result2.endsWith("Hello, world 1!\n"));
+ }
+
+ public class FauxLogger {
+ public String formatEvent(LogEvent event, Layout layout) {
+ return new String(layout.toByteArray(event));
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/fe021d94/log4j-core/src/test/resources/log4j-patternSelector.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-patternSelector.xml b/log4j-core/src/test/resources/log4j-patternSelector.xml
new file mode 100644
index 0000000..124aaf8
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-patternSelector.xml
@@ -0,0 +1,33 @@
+<?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="WARN">
+ <Appenders>
+ <List name="List">
+ <PatternLayout>
+ <MarkerPatternSelector defaultPattern="[%-5level] %c{1.} %msg%n">
+ <PatternMatch key="FLOW" pattern="[%-5level] %c{1.} ====== %C{1.}.%M:%L %msg ======%n"/>
+ </MarkerPatternSelector>
+ </PatternLayout>
+ </List>
+ </Appenders>
+ <Loggers>
+ <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/fe021d94/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/PatternLayoutBenchmark.java
----------------------------------------------------------------------
diff --git a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/PatternLayoutBenchmark.java b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/PatternLayoutBenchmark.java
index 70ee7d1..f66637a 100644
--- a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/PatternLayoutBenchmark.java
+++ b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/PatternLayoutBenchmark.java
@@ -58,14 +58,14 @@ public class PatternLayoutBenchmark {
private static final String DEFAULT_ENCODING = CHARSET_DEFAULT.name();
private static final String STRING_SHIFT_JIS = "SHIFT_JIS";
private static final Charset CHARSET_SHIFT_JIS = Charset.forName(STRING_SHIFT_JIS);
- private final PatternLayout PATTERN_M = PatternLayout.createLayout("%m%n", null, null, CHARSET_DEFAULT, false, true, null, null);
- private final PatternLayout PATTERN_SPACE = PatternLayout.createLayout(" ", null, null, CHARSET_DEFAULT, false, true, null, null);
- private final PatternLayout PATTERN_M_C = PatternLayout.createLayout("%c %m%n", null, null, CHARSET_DEFAULT, false, true, null, null);
- private final PatternLayout PATTERN_M_C_D = PatternLayout.createLayout("%d %c %m%n", null, null, CHARSET_DEFAULT, false, true, null, null);
- private final PatternLayout PATTERN_M_D = PatternLayout.createLayout("%d %m%n", null, null, CHARSET_DEFAULT, false, true, null, null);
- private final PatternLayout PATTERN_M_EX = PatternLayout.createLayout("%m %ex%n", null, null, CHARSET_DEFAULT, false, true, null, null);
- private final PatternLayout PATTERN_M_D_EX = PatternLayout.createLayout("%d %m%ex%n", null, null, CHARSET_DEFAULT, false, true, null, null);
- private final PatternLayout PATTERN_M_C_D_EX = PatternLayout.createLayout("%d %c %m%ex%n", null, null, CHARSET_DEFAULT, false, true, null, null);
+ private final PatternLayout PATTERN_M = PatternLayout.createLayout("%m%n", null, null, null, CHARSET_DEFAULT, false, true, null, null);
+ private final PatternLayout PATTERN_SPACE = PatternLayout.createLayout(" ", null, null, null, CHARSET_DEFAULT, false, true, null, null);
+ private final PatternLayout PATTERN_M_C = PatternLayout.createLayout("%c %m%n", null, null, null, CHARSET_DEFAULT, false, true, null, null);
+ private final PatternLayout PATTERN_M_C_D = PatternLayout.createLayout("%d %c %m%n", null, null, null, CHARSET_DEFAULT, false, true, null, null);
+ private final PatternLayout PATTERN_M_D = PatternLayout.createLayout("%d %m%n", null, null, null, CHARSET_DEFAULT, false, true, null, null);
+ private final PatternLayout PATTERN_M_EX = PatternLayout.createLayout("%m %ex%n", null, null, null, CHARSET_DEFAULT, false, true, null, null);
+ private final PatternLayout PATTERN_M_D_EX = PatternLayout.createLayout("%d %m%ex%n", null, null, null, CHARSET_DEFAULT, false, true, null, null);
+ private final PatternLayout PATTERN_M_C_D_EX = PatternLayout.createLayout("%d %c %m%ex%n", null, null, null, CHARSET_DEFAULT, false, true, null, null);
private static LogEvent createLogEvent() {
final Marker marker = null;
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/fe021d94/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/PatternLayoutComparisonBenchmark.java
----------------------------------------------------------------------
diff --git a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/PatternLayoutComparisonBenchmark.java b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/PatternLayoutComparisonBenchmark.java
index 3acd892..0919835 100644
--- a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/PatternLayoutComparisonBenchmark.java
+++ b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/PatternLayoutComparisonBenchmark.java
@@ -59,7 +59,7 @@ public class PatternLayoutComparisonBenchmark {
final static LogEvent LOG4J2EVENT = createLog4j2Event();
private static final Charset CHARSET_DEFAULT = Charset.defaultCharset();
private static final String LOG4JPATTERN = "%d %5p [%t] %c{1} %X{transactionId} - %m%n";
- private final PatternLayout LOG4J2_PATTERN_LAYOUT = PatternLayout.createLayout(LOG4JPATTERN,
+ private final PatternLayout LOG4J2_PATTERN_LAYOUT = PatternLayout.createLayout(LOG4JPATTERN, null,
null, null, CHARSET_DEFAULT, false, true, null, null);
private static LogEvent createLog4j2Event() {
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/fe021d94/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 93ba5f1..a8a0c8c 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -24,6 +24,9 @@
</properties>
<body>
<release version="2.4.1" date="2015-MM-DD" description="GA Release 2.4.1">
+ <action issue="LOG4J2-1129" dev="rgoers" type="add">
+ Allow PatternLayout to select a pattern to use based on some selection criteria"
+ </action>
<action issue="LOG4J2-1127" dev="ggregory" type="fix">
log4j2.xml cannot be parsed on Oracle Weblogic 12c</action>
<action issue="LOG4J2-1128" dev="ggregory" type="update">