Repository: logging-log4j2
Updated Branches:
refs/heads/master e40e631e9 -> 26a8e2aae
[LOG4J2-1015] Add a way to route messages based on the %marker in Layout
for RoutingAppender. To discuss: The configuration calls for
"$${marker:}" as opposed to "$${marker}" which is not obvious or pretty,
it's just the way variable substitutions work ATM.
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/26a8e2aa
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/26a8e2aa
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/26a8e2aa
Branch: refs/heads/master
Commit: 26a8e2aaeb3166a0ff8e7daa593cce6f00ff9453
Parents: e40e631
Author: Gary Gregory <[email protected]>
Authored: Mon May 18 22:46:41 2015 -0700
Committer: Gary Gregory <[email protected]>
Committed: Mon May 18 22:46:41 2015 -0700
----------------------------------------------------------------------
.../org/apache/logging/log4j/MarkerManager.java | 11 +++
.../logging/log4j/core/lookup/Interpolator.java | 1 +
.../logging/log4j/core/lookup/MarkerLookup.java | 46 +++++++++++
.../core/lookup/MarkerLookupConfigTest.java | 59 ++++++++++++++
.../log4j/core/lookup/MarkerLookupTest.java | 85 ++++++++++++++++++++
.../src/test/resources/log4j-marker-lookup.yaml | 39 +++++++++
src/changes/changes.xml | 3 +
src/site/xdoc/manual/lookups.xml | 58 +++++++++++++
8 files changed, 302 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/26a8e2aa/log4j-api/src/main/java/org/apache/logging/log4j/MarkerManager.java
----------------------------------------------------------------------
diff --git
a/log4j-api/src/main/java/org/apache/logging/log4j/MarkerManager.java
b/log4j-api/src/main/java/org/apache/logging/log4j/MarkerManager.java
index a2c876d..a807644 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/MarkerManager.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/MarkerManager.java
@@ -41,6 +41,17 @@ public final class MarkerManager {
}
/**
+ * Tests existence of the given marker.
+ * @param key the marker name
+ * @return true if the marker exists.
+ * @since 2.4
+ */
+ public static boolean exists(String key) {
+ return MARKERS.containsKey(key);
+ }
+
+
+ /**
* Retrieves a Marker or create a Marker that has no parent.
* @param name The name of the Marker.
* @return The Marker with the specified name.
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/26a8e2aa/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java
----------------------------------------------------------------------
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java
index 3dda892..de0a466 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java
@@ -85,6 +85,7 @@ public class Interpolator extends AbstractLookup {
lookups.put("sys", new SystemPropertiesLookup());
lookups.put("env", new EnvironmentLookup());
lookups.put("main", MainMapLookup.MAIN_SINGLETON);
+ lookups.put("marker", new MarkerLookup());
lookups.put("java", new JavaLookup());
// JNDI
try {
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/26a8e2aa/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MarkerLookup.java
----------------------------------------------------------------------
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MarkerLookup.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MarkerLookup.java
new file mode 100644
index 0000000..320db49
--- /dev/null
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MarkerLookup.java
@@ -0,0 +1,46 @@
+/*
+ * 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.lookup;
+
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.MarkerManager;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+
+/**
+ * Looks-up markers.
+ *
+ * @since 2.4
+ */
+@Plugin(name = "marker", category = StrLookup.CATEGORY)
+public class MarkerLookup extends AbstractLookup {
+
+ static final String MARKER = "marker";
+
+ @Override
+ public String lookup(final LogEvent event, final String key) {
+ final Marker marker = event == null ? null : event.getMarker();
+ return marker == null ? null : marker.getName();
+ }
+
+ @Override
+ public String lookup(final String key) {
+ return MarkerManager.exists(key) ? key : null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/26a8e2aa/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MarkerLookupConfigTest.java
----------------------------------------------------------------------
diff --git
a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MarkerLookupConfigTest.java
b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MarkerLookupConfigTest.java
new file mode 100644
index 0000000..e29423b
--- /dev/null
+++
b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MarkerLookupConfigTest.java
@@ -0,0 +1,59 @@
+package org.apache.logging.log4j.core.lookup;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.MarkerManager;
+import org.apache.logging.log4j.junit.InitialLoggerContext;
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+/**
+ * Tests {@link MarkerLookup} with a configuration file.
+ *
+ * @since 2.4
+ */
+public class MarkerLookupConfigTest {
+
+ @ClassRule
+ public static InitialLoggerContext context = new
InitialLoggerContext("log4j-marker-lookup.yaml");
+ public static final Marker PAYLOAD = MarkerManager.getMarker("PAYLOAD");
+ private static final String PAYLOAD_LOG = "Message in payload.log";
+
+ public static final Marker PERFORMANCE =
MarkerManager.getMarker("PERFORMANCE");
+
+ private static final String PERFORMANCE_LOG = "Message in performance.log";
+ public static final Marker SQL = MarkerManager.getMarker("SQL");
+ private static final String SQL_LOG = "Message in sql.log";
+
+ @Test
+ public void test() throws IOException {
+ final Logger logger = LogManager.getLogger();
+ logger.info(SQL, SQL_LOG);
+ logger.info(PAYLOAD, PAYLOAD_LOG);
+ logger.info(PERFORMANCE, PERFORMANCE_LOG);
+ {
+ final String log = FileUtils.readFileToString(new
File("target/logs/sql.log"));
+ Assert.assertTrue(log.contains(SQL_LOG));
+ Assert.assertFalse(log.contains(PAYLOAD_LOG));
+ Assert.assertFalse(log.contains(PERFORMANCE_LOG));
+ }
+ {
+ final String log = FileUtils.readFileToString(new
File("target/logs/payload.log"));
+ Assert.assertFalse(log.contains(SQL_LOG));
+ Assert.assertTrue(log.contains(PAYLOAD_LOG));
+ Assert.assertFalse(log.contains(PERFORMANCE_LOG));
+ }
+ {
+ final String log = FileUtils.readFileToString(new
File("target/logs/performance.log"));
+ Assert.assertFalse(log.contains(SQL_LOG));
+ Assert.assertFalse(log.contains(PAYLOAD_LOG));
+ Assert.assertTrue(log.contains(PERFORMANCE_LOG));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/26a8e2aa/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MarkerLookupTest.java
----------------------------------------------------------------------
diff --git
a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MarkerLookupTest.java
b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MarkerLookupTest.java
new file mode 100644
index 0000000..a33ed3d
--- /dev/null
+++
b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MarkerLookupTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.lookup;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.MarkerManager;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.impl.Log4jLogEvent;
+import org.apache.logging.log4j.message.SimpleMessage;
+import org.junit.Test;
+
+/**
+ * Tests {@link MarkerLookup}.
+ *
+ * @since 2.4
+ */
+public class MarkerLookupTest {
+
+ private static final String ABSENT_MARKER_NAME = "NONE";
+ private final String markerName = "MarkerLookupTest";
+ private final StrLookup strLookup = new MarkerLookup();
+
+ @Test
+ public void testLookupEventExistant() {
+ final Marker marker = MarkerManager.getMarker(markerName);
+ final LogEvent event = new Log4jLogEvent(this.getClass().getName(),
marker,
+ "org.apache.logging.log4j.core.Logger", Level.INFO, new
SimpleMessage("Hello, world!"), null);
+ final String value = strLookup.lookup(event, marker.getName());
+ assertEquals(markerName, value);
+ }
+
+ @Test
+ public void testLookupEventNonExistant() {
+ final LogEvent event = new Log4jLogEvent(this.getClass().getName(),
null,
+ "org.apache.logging.log4j.core.Logger", Level.INFO, new
SimpleMessage("Hello, world!"), null);
+ final String value = strLookup.lookup(event, ABSENT_MARKER_NAME);
+ assertNull(value);
+ }
+
+ @Test
+ public void testLookupEventNonExistantKey() {
+ final Marker marker = MarkerManager.getMarker(markerName);
+ final LogEvent event = new Log4jLogEvent(this.getClass().getName(),
marker,
+ "org.apache.logging.log4j.core.Logger", Level.INFO, new
SimpleMessage("Hello, world!"), null);
+ final String value = strLookup.lookup(event, ABSENT_MARKER_NAME);
+ assertEquals(markerName, value);
+ }
+
+ @Test
+ public void testLookupEventNullNonExistant() {
+ final String value = strLookup.lookup(null, ABSENT_MARKER_NAME);
+ assertNull(value);
+ }
+
+ @Test
+ public void testLookupExistant() {
+ final String value =
strLookup.lookup(MarkerManager.getMarker(markerName).getName());
+ assertEquals(markerName, value);
+ }
+
+ @Test
+ public void testLookupNonExistant() {
+ final String value = strLookup.lookup(ABSENT_MARKER_NAME);
+ assertNull(value);
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/26a8e2aa/log4j-core/src/test/resources/log4j-marker-lookup.yaml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-marker-lookup.yaml
b/log4j-core/src/test/resources/log4j-marker-lookup.yaml
new file mode 100644
index 0000000..9880e2e
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-marker-lookup.yaml
@@ -0,0 +1,39 @@
+Configuration:
+ status: debug
+
+ Appenders:
+ Console:
+ RandomAccessFile:
+ - name: SQL_APPENDER
+ fileName: target/logs/sql.log
+ append: false
+ PatternLayout:
+ Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n"
+ - name: PAYLOAD_APPENDER
+ fileName: target/logs/payload.log
+ append: false
+ PatternLayout:
+ Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n"
+ - name: PERFORMANCE_APPENDER
+ fileName: target/logs/performance.log
+ append: false
+ PatternLayout:
+ Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n"
+
+ Routing:
+ name: ROUTING_APPENDER
+ Routes:
+ pattern: "$${marker:}"
+ Route:
+ - key: PERFORMANCE
+ ref: PERFORMANCE_APPENDER
+ - key: PAYLOAD
+ ref: PAYLOAD_APPENDER
+ - key: SQL
+ ref: SQL_APPENDER
+
+ Loggers:
+ Root:
+ level: trace
+ AppenderRef:
+ - ref: ROUTING_APPENDER
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/26a8e2aa/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index a51769f..25a0f19 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -24,6 +24,9 @@
</properties>
<body>
<release version="2.4" date="2015-MM-DD" description="GA Release 2.4">
+ <action issue="LOG4J2-1015" dev="ggregory" type="add">
+ Add a way to route messages based on the %marker in Layout for
RoutingAppender.
+ </action>
<action issue="LOG4J2-1022" dev="rgoers" type="update">
Allow a list of keys to be specified in the MDC pattern converter.
</action>
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/26a8e2aa/src/site/xdoc/manual/lookups.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/lookups.xml b/src/site/xdoc/manual/lookups.xml
index e209e2a..6d8c6a0 100644
--- a/src/site/xdoc/manual/lookups.xml
+++ b/src/site/xdoc/manual/lookups.xml
@@ -304,6 +304,64 @@ public static void main(String args[]) {
</Routes>
</Routing>]]></pre>
</subsection>
+ <subsection name="Marker Lookup">
+ <p>
+ The marker lookup allows you to use markers in interesting
configurations like a routing appender.
+ Consider the following YAML configuration and code that logs to
different files based on markers:
+ </p>
+ <pre class="prettyprint linenums"><![CDATA[
+Configuration:
+ status: debug
+
+ Appenders:
+ Console:
+ RandomAccessFile:
+ - name: SQL_APPENDER
+ fileName: logs/sql.log
+ PatternLayout:
+ Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n"
+ - name: PAYLOAD_APPENDER
+ fileName: logs/payload.log
+ PatternLayout:
+ Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n"
+ - name: PERFORMANCE_APPENDER
+ fileName: logs/performance.log
+ PatternLayout:
+ Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n"
+
+ Routing:
+ name: ROUTING_APPENDER
+ Routes:
+ pattern: "$${marker:}"
+ Route:
+ - key: PERFORMANCE
+ ref: PERFORMANCE_APPENDER
+ - key: PAYLOAD
+ ref: PAYLOAD_APPENDER
+ - key: SQL
+ ref: SQL_APPENDER
+
+ Loggers:
+ Root:
+ level: trace
+ AppenderRef:
+ - ref: ROUTING_APPENDER]]></pre>
+ <pre class="prettyprint linenums"><![CDATA[
+public static final Marker SQL = MarkerFactory.getMarker("SQL");
+public static final Marker PAYLOAD = MarkerFactory.getMarker("PAYLOAD");
+public static final Marker PERFORMANCE =
MarkerFactory.getMarker("PERFORMANCE");
+
+final Logger logger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+
+logger.info(SQL, "Message in Sql.log");
+logger.info(PAYLOAD, "Message in Payload.log");
+logger.info(PERFORMANCE, "Message in Performance.log");]]></pre>
+ <p>
+ Note the key part of the configuration is <code>pattern:
"$${marker:}"</code>. This will produce three log files,
+ each with a log event for a specific marker. Log4j will route the
log event with the <code>SQL</code> marker to
+ <code>sql.log</code>, the log event with the <code>PAYLOAD</code>
marker to <code>payload.log</code>, and so on.
+ </p>
+ </subsection>
<a name="StructuredDataLookup"/>
<subsection name="Structured Data Lookup">
<p>