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>

Reply via email to