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 2013/07/18 21:47:20 UTC
svn commit: r1504620 - in /logging/log4j/log4j2/trunk:
core/src/main/java/org/apache/logging/log4j/core/lookup/
core/src/test/java/org/apache/logging/log4j/core/appender/routing/
core/src/test/java/org/apache/logging/log4j/core/lookup/ core/src/test/re...
Author: rgoers
Date: Thu Jul 18 19:47:20 2013
New Revision: 1504620
URL: http://svn.apache.org/r1504620
Log:
LOG4J2-313 - Add JNDILookup
Added:
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java
logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithJndiTest.java
logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLookupTest.java
logging/log4j/log4j2/trunk/core/src/test/resources/log4j-routing-by-jndi.xml
Modified:
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java
logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/lookup/InterpolatorTest.java
logging/log4j/log4j2/trunk/src/changes/changes.xml
logging/log4j/log4j2/trunk/src/site/site.xml
logging/log4j/log4j2/trunk/src/site/xdoc/manual/lookups.xml
Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java?rev=1504620&r1=1504619&r2=1504620&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java (original)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java Thu Jul 18 19:47:20 2013
@@ -63,6 +63,7 @@ public class Interpolator implements Str
this.defaultLookup = new MapLookup(new HashMap<String, String>());
lookups.put("sys", new SystemPropertiesLookup());
lookups.put("env", new EnvironmentLookup());
+ lookups.put("jndi", new JndiLookup());
}
/**
Added: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java?rev=1504620&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java (added)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java Thu Jul 18 19:47:20 2013
@@ -0,0 +1,78 @@
+/*
+ * 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 javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+
+/**
+ * Looks up keys from JNDI resources.
+ */
+@Plugin(name = "jndi", category = "Lookup")
+public class JndiLookup implements StrLookup {
+
+ /** JNDI resourcce path prefix used in a J2EE container */
+ static final String CONTAINER_JNDI_RESOURCE_PATH_PREFIX = "java:comp/env/";
+
+ /**
+ * Get the value of the JNDI resource.
+ * @param key the JNDI resource name to be looked up, may be null
+ * @return The value of the JNDI resource.
+ */
+ @Override
+ public String lookup(final String key) {
+ return lookup(null, key);
+ }
+
+ /**
+ * Get the value of the JNDI resource.
+ * @param event The current LogEvent (is ignored by this StrLookup).
+ * @param key the JNDI resource name to be looked up, may be null
+ * @return The value of the JNDI resource.
+ */
+ @Override
+ public String lookup(final LogEvent event, final String key) {
+ if (key == null) {
+ return null;
+ }
+
+ try {
+ InitialContext ctx = new InitialContext();
+ return (String) ctx.lookup(convertJndiName(key));
+ } catch (NamingException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Convert the given JNDI name to the actual JNDI name to use.
+ * Default implementation applies the "java:comp/env/" prefix
+ * unless other scheme like "java:" is given.
+ * @param jndiName The name of the resource.
+ * @return The fully qualified name to look up.
+ */
+ private String convertJndiName(String jndiName) {
+ if (!jndiName.startsWith(CONTAINER_JNDI_RESOURCE_PATH_PREFIX) && jndiName.indexOf(':') == -1) {
+ jndiName = CONTAINER_JNDI_RESOURCE_PATH_PREFIX + jndiName;
+ }
+
+ return jndiName;
+ }
+}
Added: logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithJndiTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithJndiTest.java?rev=1504620&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithJndiTest.java (added)
+++ logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithJndiTest.java Thu Jul 18 19:47:20 2013
@@ -0,0 +1,122 @@
+/*
+ * 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.appender.routing;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.util.Map;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.apache.logging.log4j.EventLogger;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.XMLConfigurationFactory;
+import org.apache.logging.log4j.message.StructuredDataMessage;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.test.appender.ListAppender;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockejb.jndi.MockContextFactory;
+
+/**
+ * RoutingAppenderWithJndiTest
+ */
+public class RoutingAppenderWithJndiTest {
+
+ private static final String CONFIG = "log4j-routing-by-jndi.xml";
+ private static Configuration config;
+ private static ListAppender<LogEvent> listAppender1;
+ private static ListAppender<LogEvent> listAppender2;
+ private static LoggerContext ctx;
+
+ @BeforeClass
+ @SuppressWarnings("unchecked")
+ public static void setupClass() {
+ System.setProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY, CONFIG);
+ ctx = (LoggerContext) LogManager.getContext(false);
+ config = ctx.getConfiguration();
+ for (final Map.Entry<String, Appender<?>> entry : config.getAppenders().entrySet()) {
+ if (entry.getKey().equals("List1")) {
+ listAppender1 = (ListAppender<LogEvent>) entry.getValue();
+ }
+ if (entry.getKey().equals("List2")) {
+ listAppender2 = (ListAppender<LogEvent>) entry.getValue();
+ }
+ }
+ }
+
+ @Before
+ public void before() throws NamingException {
+ MockContextFactory.setAsInitial();
+ }
+
+ @After
+ public void after() {
+ MockContextFactory.revertSetAsInitial();
+ }
+
+ @AfterClass
+ public static void cleanupClass() {
+ System.clearProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
+ ctx.reconfigure();
+ StatusLogger.getLogger().reset();
+ }
+
+ @Test
+ public void routingTest() throws NamingException {
+ // default route when there's no jndi resource
+ StructuredDataMessage msg = new StructuredDataMessage("Test", "This is a message from unknown context", "Context");
+ EventLogger.logEvent(msg);
+ File defaultLogFile = new File("target/routingbyjndi/routingbyjnditest-default.log");
+ assertTrue("The default log file was not created", defaultLogFile.exists());
+
+ // now set jndi resource to Application1
+ Context context = new InitialContext();
+ context.bind("java:comp/env/logging/context-name", "Application1");
+
+ msg = new StructuredDataMessage("Test", "This is a message from Application1", "Context");
+ EventLogger.logEvent(msg);
+ assertNotNull("No events generated", listAppender1.getEvents());
+ assertTrue("Incorrect number of events. Expected 1, got " + listAppender1.getEvents().size(), listAppender1.getEvents().size() == 1);
+
+ // now set jndi resource to Application2
+ context.rebind("java:comp/env/logging/context-name", "Application2");
+
+ msg = new StructuredDataMessage("Test", "This is a message from Application2", "Context");
+ EventLogger.logEvent(msg);
+ assertNotNull("No events generated", listAppender2.getEvents());
+ assertTrue("Incorrect number of events. Expected 1, got " + listAppender2.getEvents().size(), listAppender2.getEvents().size() == 1);
+ assertTrue("Incorrect number of events. Expected 1, got " + listAppender1.getEvents().size(), listAppender1.getEvents().size() == 1);
+
+ msg = new StructuredDataMessage("Test", "This is another message from Application2", "Context");
+ EventLogger.logEvent(msg);
+ assertNotNull("No events generated", listAppender2.getEvents());
+ assertTrue("Incorrect number of events. Expected 2, got " + listAppender2.getEvents().size(), listAppender2.getEvents().size() == 2);
+ assertTrue("Incorrect number of events. Expected 1, got " + listAppender1.getEvents().size(), listAppender1.getEvents().size() == 1);
+ }
+}
Modified: logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/lookup/InterpolatorTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/lookup/InterpolatorTest.java?rev=1504620&r1=1504619&r2=1504620&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/lookup/InterpolatorTest.java (original)
+++ logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/lookup/InterpolatorTest.java Thu Jul 18 19:47:20 2013
@@ -16,16 +16,22 @@
*/
package org.apache.logging.log4j.core.lookup;
-import org.apache.logging.log4j.ThreadContext;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import java.util.HashMap;
import java.util.Map;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.apache.logging.log4j.ThreadContext;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockejb.jndi.MockContextFactory;
/**
*
@@ -35,18 +41,25 @@ public class InterpolatorTest {
private static final String TESTKEY = "TestKey";
private static final String TESTVAL = "TestValue";
+ private static final String TEST_CONTEXT_RESOURCE_NAME = "logging/context-name";
+ private static final String TEST_CONTEXT_NAME = "app-1";
@BeforeClass
- public static void before() {
+ public static void before() throws NamingException {
System.setProperty(TESTKEY, TESTVAL);
+
+ MockContextFactory.setAsInitial();
+ Context context = new InitialContext();
+ context.bind(JndiLookup.CONTAINER_JNDI_RESOURCE_PATH_PREFIX + TEST_CONTEXT_RESOURCE_NAME, TEST_CONTEXT_NAME);
}
@AfterClass
public static void after() {
+ MockContextFactory.revertSetAsInitial();
+
System.clearProperty(TESTKEY);
}
-
@Test
public void testLookup() {
final Map<String, String> map = new HashMap<String, String>();
@@ -64,5 +77,18 @@ public class InterpolatorTest {
ThreadContext.clear();
value = lookup.lookup("ctx:" + TESTKEY);
assertEquals(TESTVAL, value);
+ value = lookup.lookup("jndi:" + TEST_CONTEXT_RESOURCE_NAME);
+ assertEquals(TEST_CONTEXT_NAME, value);
+ }
+
+ @Test
+ public void testLookupWithDefaultInterpolator() {
+ final StrLookup lookup = new Interpolator();
+ String value = lookup.lookup("sys:" + TESTKEY);
+ assertEquals(TESTVAL, value);
+ value = lookup.lookup("env:PATH");
+ assertNotNull(value);
+ value = lookup.lookup("jndi:" + TEST_CONTEXT_RESOURCE_NAME);
+ assertEquals(TEST_CONTEXT_NAME, value);
}
}
Added: logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLookupTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLookupTest.java?rev=1504620&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLookupTest.java (added)
+++ logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLookupTest.java Thu Jul 18 19:47:20 2013
@@ -0,0 +1,64 @@
+/*
+ * 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 javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockejb.jndi.MockContextFactory;
+
+/**
+ * JndiLookupTest
+ */
+public class JndiLookupTest {
+
+ private static final String TEST_CONTEXT_RESOURCE_NAME = "logging/context-name";
+ private static final String TEST_CONTEXT_NAME = "app-1";
+
+ @Before
+ public void before() throws NamingException {
+ MockContextFactory.setAsInitial();
+ Context context = new InitialContext();
+ context.bind(JndiLookup.CONTAINER_JNDI_RESOURCE_PATH_PREFIX + TEST_CONTEXT_RESOURCE_NAME, TEST_CONTEXT_NAME);
+ }
+
+ @After
+ public void after() {
+ MockContextFactory.revertSetAsInitial();
+ }
+
+ @Test
+ public void testLookup() {
+ final StrLookup lookup = new JndiLookup();
+
+ String contextName = lookup.lookup(TEST_CONTEXT_RESOURCE_NAME);
+ assertEquals(TEST_CONTEXT_NAME, contextName);
+
+ contextName = lookup.lookup(JndiLookup.CONTAINER_JNDI_RESOURCE_PATH_PREFIX + TEST_CONTEXT_RESOURCE_NAME);
+ assertEquals(TEST_CONTEXT_NAME, contextName);
+
+ String nonExistingResource = lookup.lookup("logging/non-existing-resource");
+ assertNull(nonExistingResource);
+ }
+}
Added: logging/log4j/log4j2/trunk/core/src/test/resources/log4j-routing-by-jndi.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/resources/log4j-routing-by-jndi.xml?rev=1504620&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/test/resources/log4j-routing-by-jndi.xml (added)
+++ logging/log4j/log4j2/trunk/core/src/test/resources/log4j-routing-by-jndi.xml Thu Jul 18 19:47:20 2013
@@ -0,0 +1,60 @@
+<?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="debug" name="RoutingByJndiTest" packages="org.apache.logging.log4j.test">
+
+ <ThresholdFilter level="debug"/>
+
+ <appenders>
+ <Console name="STDOUT">
+ <PatternLayout pattern="%m%n"/>
+ </Console>
+ <List name="List1">
+ <ThresholdFilter level="debug"/>
+ </List>
+ <List name="List2">
+ <ThresholdFilter level="debug"/>
+ </List>
+ <Routing name="Routing">
+ <Routes pattern="$${jndi:logging/context-name}">
+ <!-- Default route -->
+ <Route>
+ <File name="DefaultApplicationLogFile" fileName="target/routingbyjndi/routingbyjnditest-default.log" append="false">
+ <PatternLayout>
+ <pattern>%d %p %C{1.} [%t] %m%n</pattern>
+ </PatternLayout>
+ </File>
+ </Route>
+ <Route ref="List1" key="Application1"/>
+ <Route ref="List2" key="Application2"/>
+ </Routes>
+ </Routing>
+ </appenders>
+
+ <loggers>
+ <logger name="EventLogger" level="info" additivity="false">
+ <appender-ref ref="Routing"/>
+ <appender-ref ref="STDOUT"/>
+ </logger>
+
+ <root level="error">
+ <appender-ref ref="STDOUT"/>
+ </root>
+ </loggers>
+
+</configuration>
\ No newline at end of file
Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/changes/changes.xml?rev=1504620&r1=1504619&r2=1504620&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/changes/changes.xml (original)
+++ logging/log4j/log4j2/trunk/src/changes/changes.xml Thu Jul 18 19:47:20 2013
@@ -21,6 +21,9 @@
</properties>
<body>
<release version="2.0-beta9" date="soon, very soon" description="Bug fixes and enhancements">
+ <action issue="LOG4J2-313" dev="rgoers" type="add" due-to="Woonsan Ko">
+ Add JNDILookup plugin.
+ </action>
<action issue="LOG4J2-299" dev="rgoers" type="fix">
Add getThrowable method to ThrowableProxy.
</action>
Modified: logging/log4j/log4j2/trunk/src/site/site.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/site/site.xml?rev=1504620&r1=1504619&r2=1504620&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/site/site.xml (original)
+++ logging/log4j/log4j2/trunk/src/site/site.xml Thu Jul 18 19:47:20 2013
@@ -76,6 +76,7 @@
<item name="ContextMap" href="/manual/lookups.html#ContextMapLookup"/>
<item name="Date" href="/manual/lookups.html#DateLookcup"/>
<item name="Environment" href="/manual/lookups.html#EnvironmentLookup"/>
+ <item name="JNDI" href="/manual/lookups.html#JNDILookup"/>
<item name="Map" href="/manual/lookups.html#MapLookup"/>
<item name="StructuredData" href="/manual/lookups.html#StructuredDataLookup"/>
<item name="SystemProperties" href="/manual/lookups.html#SystemPropertiesLookup"/>
Modified: logging/log4j/log4j2/trunk/src/site/xdoc/manual/lookups.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/site/xdoc/manual/lookups.xml?rev=1504620&r1=1504619&r2=1504620&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/site/xdoc/manual/lookups.xml (original)
+++ logging/log4j/log4j2/trunk/src/site/xdoc/manual/lookups.xml Thu Jul 18 19:47:20 2013
@@ -80,6 +80,19 @@
</PatternLayout>
</File>]]></pre>
</subsection>
+ <a name="JNDILookup"/>
+ <subsection name="JNDILookup">
+ <p>
+ The JNDILookup allows variables to be retrieved via JNDI. By default the key will be prefixed with
+ java:comp/env/, however if the key contains a ":" no prefix will be added.
+ </p>
+ <pre class="prettyprint linenums"><![CDATA[
+<File name="Application" fileName="application.log">
+ <PatternLayout>
+ <pattern>%d %p %c{1.} [%t] $${jndi:logging/context-name} %m%n</pattern>
+ </PatternLayout>
+</File>]]></pre>
+ </subsection>
<a name="MapLookup"/>
<subsection name="MapLookup">
<p>