You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by gg...@apache.org on 2014/08/20 05:19:09 UTC
svn commit: r1619026 - in /logging/log4j/log4j2/trunk:
log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/
log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/ src/changes/
src/site/xdoc/manual/
Author: ggregory
Date: Wed Aug 20 03:19:09 2014
New Revision: 1619026
URL: http://svn.apache.org/r1619026
Log:
[LOG4J2-771] Add lookup for application main arguments.
[LOG4J2-787] Add lookup for JVM arguments.
Added:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java (with props)
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java (with props)
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsMapLookup.java (with props)
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MapLookup.java
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MapLookupTest.java
logging/log4j/log4j2/trunk/src/changes/changes.xml
logging/log4j/log4j2/trunk/src/site/xdoc/manual/configuration.xml.vm
logging/log4j/log4j2/trunk/src/site/xdoc/manual/lookups.xml
Modified: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java?rev=1619026&r1=1619025&r2=1619026&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java Wed Aug 20 03:19:09 2014
@@ -27,7 +27,7 @@ import org.apache.logging.log4j.core.uti
import org.apache.logging.log4j.status.StatusLogger;
/**
- * Proxies all the other StrLookups.
+ * Proxies all the other {@link StrLookup}s.
*/
public class Interpolator implements StrLookup {
@@ -72,6 +72,8 @@ public class Interpolator implements Str
// TODO: this ought to use the PluginManager
lookups.put("sys", new SystemPropertiesLookup());
lookups.put("env", new EnvironmentLookup());
+ lookups.put("main", MapLookup.MAIN_SINGLETON);
+ // JNDI
try {
// [LOG4J2-703] We might be on Android
lookups.put("jndi",
@@ -82,6 +84,17 @@ public class Interpolator implements Str
"JNDI lookup class is not available because this JRE does not support JNDI. JNDI string lookups will not be available, continuing configuration.",
e);
}
+ // JMX input args
+ try {
+ // We might be on Android
+ lookups.put("jmx-input",
+ Loader.newCheckedInstanceOf("org.apache.logging.log4j.core.lookup.JmxRuntimeInputArgumentsLookup", StrLookup.class));
+ } catch (Throwable e) {
+ // java.lang.VerifyError: org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup
+ LOGGER.warn(
+ "JMX runtime input lookup class is not available because this JRE does not support JMX. JMX lookups will not be available, continuing configuration.",
+ e);
+ }
lookups.put("date", new DateLookup());
lookups.put("ctx", new ContextMapLookup());
if (Loader.isClassAvailable("javax.servlet.ServletContext")) {
Added: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java?rev=1619026&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java (added)
+++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java Wed Aug 20 03:19:09 2014
@@ -0,0 +1,29 @@
+package org.apache.logging.log4j.core.lookup;
+
+import java.lang.management.ManagementFactory;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+
+/**
+ * Maps JVM input arguments (but not main arguments) using JMX to acquire JVM arguments.
+ *
+ * @see java.lang.management.RuntimeMXBean#getInputArguments()
+ * @since 2.1
+ */
+@Plugin(name = "jmx-input", category = "Lookup")
+public class JmxRuntimeInputArgumentsLookup extends MapLookup {
+
+ static {
+ List<String> argsList = ManagementFactory.getRuntimeMXBean().getInputArguments();
+ JMX_SINGLETON = new JmxRuntimeInputArgumentsLookup(MapLookup.toMap(argsList));
+ }
+
+ public static final JmxRuntimeInputArgumentsLookup JMX_SINGLETON;
+
+ public JmxRuntimeInputArgumentsLookup(Map<String, String> map) {
+ super(map);
+ }
+
+}
Propchange: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MapLookup.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MapLookup.java?rev=1619026&r1=1619025&r2=1619026&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MapLookup.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MapLookup.java Wed Aug 20 03:19:09 2014
@@ -16,6 +16,8 @@
*/
package org.apache.logging.log4j.core.lookup;
+import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.core.LogEvent;
@@ -23,25 +25,82 @@ import org.apache.logging.log4j.core.con
import org.apache.logging.log4j.message.MapMessage;
/**
- * The basis for a lookup based on a Map.
+ * A map-based lookup.
*/
@Plugin(name = "map", category = "Lookup")
public class MapLookup implements StrLookup {
-
+
/**
- * Map keys are variable names and value.
+ * A singleton used by a main method to save its arguments.
*/
- private final Map<String, String> map;
+ static final MapLookup MAIN_SINGLETON = new MapLookup(newMap(0));
+
+ static Map<String, String> initMap(final String[] srcArgs, final Map<String, String> destMap) {
+ for (int i = 0; i < srcArgs.length; i++) {
+ final int next = i + 1;
+ final String value = srcArgs[i];
+ destMap.put(Integer.toString(i), value);
+ destMap.put(value, next < srcArgs.length ? srcArgs[next] : null);
+ }
+ return destMap;
+ }
+
+ private static HashMap<String, String> newMap(final int initialCapacity) {
+ return new HashMap<String, String>(initialCapacity);
+ }
/**
- * Creates a new instance backed by a Map. Used by the default lookup.
- *
- * @param map the map of keys to values, may be null
+ * An application's {@code public static main(String[])} method calls this method to make its main arguments
+ * available for lookup with the prefix {@code main}.
+ * <p>
+ * The map provides two kinds of access: First by index, starting at {@code "0"}, {@code "1"} and so on. For
+ * example, the command line {@code --file path/file.txt -x 2} can be accessed from a configuration file with:
+ * </p>
+ * <ul>
+ * <li>{@code "main:0"} = {@code "--file"}</li>
+ * <li>{@code "main:1"} = {@code "path/file.txt"}</li>
+ * <li>{@code "main:2"} = {@code "-x"}</li>
+ * <li>{@code "main:3"} = {@code "2"}</li>
+ * </ul>
+ * <p>
+ * Second using the argument at position n as the key to access the value at n+1.
+ * </p>
+ * <ul>
+ * <li>{@code "main:--file"} = {@code "path/file.txt"}</li>
+ * <li>{@code "main:-x"} = {@code "2"}</li>
+ * </ul>
+ *
+ * @param args
+ * An application's {@code public static main(String[])} arguments.
+ * @since 2.1
*/
- public MapLookup(final Map<String, String> map) {
- this.map = map;
+ public static void setMainArguments(final String[] args) {
+ if (args == null) {
+ return;
+ }
+ initMap(args, MAIN_SINGLETON.map);
+ }
+
+ static Map<String, String> toMap(final List<String> args) {
+ if (args == null) {
+ return null;
+ }
+ final int size = args.size();
+ return initMap(args.toArray(new String[size]), newMap(size));
}
+ static Map<String, String> toMap(final String[] args) {
+ if (args == null) {
+ return null;
+ }
+ return initMap(args, newMap(args.length));
+ }
+
+ /**
+ * Map keys are variable names and value.
+ */
+ private final Map<String, String> map;
+
/**
* Constructor when used directly as a plugin.
*/
@@ -50,21 +109,13 @@ public class MapLookup implements StrLoo
}
/**
- * Looks up a String key to a String value using the map.
- * <p>
- * If the map is null, then null is returned.
- * The map result object is converted to a string using toString().
- * </p>
+ * Creates a new instance backed by a Map. Used by the default lookup.
*
- * @param key the key to be looked up, may be null
- * @return the matching value, null if no match
+ * @param map
+ * the map of keys to values, may be null
*/
- @Override
- public String lookup(final String key) {
- if (map == null) {
- return null;
- }
- return map.get(key);
+ public MapLookup(final Map<String, String> map) {
+ this.map = map;
}
@Override
@@ -83,4 +134,23 @@ public class MapLookup implements StrLoo
}
return null;
}
+
+ /**
+ * Looks up a String key to a String value using the map.
+ * <p>
+ * If the map is null, then null is returned. The map result object is converted to a string using toString().
+ * </p>
+ *
+ * @param key
+ * the key to be looked up, may be null
+ * @return the matching value, null if no match
+ */
+ @Override
+ public String lookup(final String key) {
+ if (map == null) {
+ return null;
+ }
+ return map.get(key);
+ }
+
}
Added: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java?rev=1619026&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java (added)
+++ logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java Wed Aug 20 03:19:09 2014
@@ -0,0 +1,57 @@
+/*
+ * 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 org.junit.Test;
+
+/**
+ * Tests {@link JmxRuntimeInputArgumentsLookup} from the command line, not a JUnit test.
+ *
+ * From an IDE or CLI: --file foo.txt
+ *
+ * @since 2.1
+ */
+public class MainInputArgumentsJmxLookupTest {
+
+ public static void main(String[] args) {
+ new MainInputArgumentsJmxLookupTest().callFromMain();
+ }
+
+ @Test
+ public void testMap() {
+ JmxRuntimeInputArgumentsLookup lookup = JmxRuntimeInputArgumentsLookup.JMX_SINGLETON;
+ assertEquals(null, lookup.lookup(null));
+ assertEquals(null, lookup.lookup("X"));
+ assertEquals(null, lookup.lookup("foo.txt"));
+ }
+
+ public void callFromMain() {
+ JmxRuntimeInputArgumentsLookup lookup = JmxRuntimeInputArgumentsLookup.JMX_SINGLETON;
+ assertEquals(null, lookup.lookup(null));
+ assertEquals(null, lookup.lookup("X"));
+ // Eclipse adds -Dfile.encoding=Cp1252
+ // assertEquals("--file", lookup.lookup("0"));
+ // assertEquals("foo.txt", lookup.lookup("1"));
+ //
+ // JMX does not include the main arguments.
+ // assertEquals("foo.txt", lookup.lookup("--file"));
+ // assertEquals(null, lookup.lookup("foo.txt"));
+ }
+
+}
Propchange: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsMapLookup.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsMapLookup.java?rev=1619026&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsMapLookup.java (added)
+++ logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsMapLookup.java Wed Aug 20 03:19:09 2014
@@ -0,0 +1,41 @@
+package org.apache.logging.log4j.core.lookup;
+
+import java.util.Map;
+
+/**
+ * Work in progress, saved for future experimentation.
+ *
+ * TODO The goal is to use the Sun debugger API to find the main arg values on the stack.
+ */
+public class MainInputArgumentsMapLookup extends MapLookup {
+
+ public static final MainInputArgumentsMapLookup SINGLETON_STACK;
+
+ static {
+ Map<Thread, StackTraceElement[]> allStackTraces = Thread.getAllStackTraces();
+ String[] args = null;
+ for (Map.Entry<Thread, StackTraceElement[]> entry : allStackTraces.entrySet()) {
+ StackTraceElement[] stackTraceElements = entry.getValue();
+ Thread thread = entry.getKey();
+ // Can't use the thread name to look for "main" since anyone can set it.
+ // Can't use thread ID since it can be any positive value, and is likely vender dependent. Oracle seems to
+ // use 1.
+ // We are left to look for "main" at the top of the stack
+ if (stackTraceElements != null) {
+ final int frame0 = stackTraceElements.length - 1;
+ if ("main".equals(stackTraceElements[frame0].getMethodName())) {
+ // We could further validate the main is a public static void method that takes a String[], if not,
+ // look at the other threads.
+ //
+ // How do we get the main args from the stack with the debug API?
+ // Must we be started in debug mode? Seems like it.
+ }
+ }
+ }
+ SINGLETON_STACK = new MainInputArgumentsMapLookup(MapLookup.toMap(args));
+ }
+
+ public MainInputArgumentsMapLookup(Map<String, String> map) {
+ super(map);
+ }
+}
Propchange: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsMapLookup.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsMapLookup.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MapLookupTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MapLookupTest.java?rev=1619026&r1=1619025&r2=1619026&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MapLookupTest.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MapLookupTest.java Wed Aug 20 03:19:09 2014
@@ -49,4 +49,19 @@ public class MapLookupTest {
assertEquals(null, lookup.lookup(null));
assertEquals(null, lookup.lookup("X"));
}
+
+ @Test
+ public void testMainMap() {
+ MapLookup.setMainArguments(new String[] {
+ "--file",
+ "foo.txt" });
+ MapLookup lookup = MapLookup.MAIN_SINGLETON;
+ assertEquals(null, lookup.lookup(null));
+ assertEquals(null, lookup.lookup("X"));
+ assertEquals("--file", lookup.lookup("0"));
+ assertEquals("foo.txt", lookup.lookup("1"));
+ assertEquals("foo.txt", lookup.lookup("--file"));
+ assertEquals(null, lookup.lookup("foo.txt"));
+ }
+
}
Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/changes/changes.xml?rev=1619026&r1=1619025&r2=1619026&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/changes/changes.xml (original)
+++ logging/log4j/log4j2/trunk/src/changes/changes.xml Wed Aug 20 03:19:09 2014
@@ -21,10 +21,16 @@
<title>Changes</title>
</properties>
<body>
- <release version="2.?.?" date="2014-??-??" description="Bug fixes and enhancements">
+ <release version="2.?.?" date="2014-??-??" description="Bug fixes and enhancements">
<action issue="LOG4J2-783" dev="rpopma" type="fix" due-to="Minglei Lee">
PatternLayout should use platform character encoding by default, not UTF-8.
</action>
+ <action issue="LOG4J2-771" dev="ggregory" type="add">
+ Add lookup for application main arguments.
+ </action>
+ <action issue="LOG4J2-787" dev="ggregory" type="add">
+ Add lookup for JVM arguments.
+ </action>
</release>
<release version="2.0.2" date="2014-08-16" description="Bug fixes and enhancements">
<action issue="LOG4J2-775" dev="ggregory" type="update">
Modified: logging/log4j/log4j2/trunk/src/site/xdoc/manual/configuration.xml.vm
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/site/xdoc/manual/configuration.xml.vm?rev=1619026&r1=1619025&r2=1619026&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/site/xdoc/manual/configuration.xml.vm (original)
+++ logging/log4j/log4j2/trunk/src/site/xdoc/manual/configuration.xml.vm Wed Aug 20 03:19:09 2014
@@ -869,6 +869,14 @@ public class Bar {
<td>System environment variables</td>
</tr>
<tr>
+ <td>jmx-input</td>
+ <td>A JVM input argument accessed through JMX, but not a main argument; see <a href="http://docs.oracle.com/javase/8/docs/api/java/lang/management/RuntimeMXBean.html#getInputArguments--">RuntimeMXBean.html#getInputArguments()</a></td>
+ </tr>
+ <tr>
+ <td>main</td>
+ <td>A value set with <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/MapLookup.html#setMainArguments%28java.lang.String[]%29">MapLookup.setMainArguments(String[])</a></td>
+ </tr>
+ <tr>
<td>map</td>
<td>A value from a MapMessage</td>
</tr>
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=1619026&r1=1619025&r2=1619026&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/site/xdoc/manual/lookups.xml (original)
+++ logging/log4j/log4j2/trunk/src/site/xdoc/manual/lookups.xml Wed Aug 20 03:19:09 2014
@@ -98,11 +98,12 @@
<subsection name="MapLookup">
<a name="MapLookup"/>
<p>
- The MapLookup serves two purposes.
+ The MapLookup serves several purposes.
</p>
<ol>
<li>Provide the base for Properties declared in the configuration file.</li>
<li>Retrieve values from MapMessages in LogEvents.</li>
+ <li>Retrieve values set with <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/MapLookup.html#setMainArguments%28java.lang.String[]%29">MapLookup.setMainArguments(String[])</a></li>
</ol>
<p>
The first item simply means that the MapLookup is used to substitute properties that are defined
Re: svn commit: r1619026 - in /logging/log4j/log4j2/trunk: log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/ log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/ src/changes/ src/site/xdoc/manual/
Posted by Ralph Goers <ra...@dslextreme.com>.
Why is the lookup that returns JVM arguments named jmx-input? That just seems strange.
Ralph
On Aug 19, 2014, at 8:19 PM, ggregory@apache.org wrote:
> Author: ggregory
> Date: Wed Aug 20 03:19:09 2014
> New Revision: 1619026
>
> URL: http://svn.apache.org/r1619026
> Log:
> [LOG4J2-771] Add lookup for application main arguments.
> [LOG4J2-787] Add lookup for JVM arguments.
>
> Added:
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java (with props)
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java (with props)
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsMapLookup.java (with props)
> Modified:
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MapLookup.java
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MapLookupTest.java
> logging/log4j/log4j2/trunk/src/changes/changes.xml
> logging/log4j/log4j2/trunk/src/site/xdoc/manual/configuration.xml.vm
> logging/log4j/log4j2/trunk/src/site/xdoc/manual/lookups.xml
>
> Modified: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java
> URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java?rev=1619026&r1=1619025&r2=1619026&view=diff
> ==============================================================================
> --- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java (original)
> +++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java Wed Aug 20 03:19:09 2014
> @@ -27,7 +27,7 @@ import org.apache.logging.log4j.core.uti
> import org.apache.logging.log4j.status.StatusLogger;
>
> /**
> - * Proxies all the other StrLookups.
> + * Proxies all the other {@link StrLookup}s.
> */
> public class Interpolator implements StrLookup {
>
> @@ -72,6 +72,8 @@ public class Interpolator implements Str
> // TODO: this ought to use the PluginManager
> lookups.put("sys", new SystemPropertiesLookup());
> lookups.put("env", new EnvironmentLookup());
> + lookups.put("main", MapLookup.MAIN_SINGLETON);
> + // JNDI
> try {
> // [LOG4J2-703] We might be on Android
> lookups.put("jndi",
> @@ -82,6 +84,17 @@ public class Interpolator implements Str
> "JNDI lookup class is not available because this JRE does not support JNDI. JNDI string lookups will not be available, continuing configuration.",
> e);
> }
> + // JMX input args
> + try {
> + // We might be on Android
> + lookups.put("jmx-input",
> + Loader.newCheckedInstanceOf("org.apache.logging.log4j.core.lookup.JmxRuntimeInputArgumentsLookup", StrLookup.class));
> + } catch (Throwable e) {
> + // java.lang.VerifyError: org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup
> + LOGGER.warn(
> + "JMX runtime input lookup class is not available because this JRE does not support JMX. JMX lookups will not be available, continuing configuration.",
> + e);
> + }
> lookups.put("date", new DateLookup());
> lookups.put("ctx", new ContextMapLookup());
> if (Loader.isClassAvailable("javax.servlet.ServletContext")) {
>
> Added: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java
> URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java?rev=1619026&view=auto
> ==============================================================================
> --- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java (added)
> +++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java Wed Aug 20 03:19:09 2014
> @@ -0,0 +1,29 @@
> +package org.apache.logging.log4j.core.lookup;
> +
> +import java.lang.management.ManagementFactory;
> +import java.util.List;
> +import java.util.Map;
> +
> +import org.apache.logging.log4j.core.config.plugins.Plugin;
> +
> +/**
> + * Maps JVM input arguments (but not main arguments) using JMX to acquire JVM arguments.
> + *
> + * @see java.lang.management.RuntimeMXBean#getInputArguments()
> + * @since 2.1
> + */
> +@Plugin(name = "jmx-input", category = "Lookup")
> +public class JmxRuntimeInputArgumentsLookup extends MapLookup {
> +
> + static {
> + List<String> argsList = ManagementFactory.getRuntimeMXBean().getInputArguments();
> + JMX_SINGLETON = new JmxRuntimeInputArgumentsLookup(MapLookup.toMap(argsList));
> + }
> +
> + public static final JmxRuntimeInputArgumentsLookup JMX_SINGLETON;
> +
> + public JmxRuntimeInputArgumentsLookup(Map<String, String> map) {
> + super(map);
> + }
> +
> +}
>
> Propchange: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java
> ------------------------------------------------------------------------------
> svn:eol-style = native
>
> Propchange: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java
> ------------------------------------------------------------------------------
> svn:keywords = Id
>
> Modified: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MapLookup.java
> URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MapLookup.java?rev=1619026&r1=1619025&r2=1619026&view=diff
> ==============================================================================
> --- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MapLookup.java (original)
> +++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MapLookup.java Wed Aug 20 03:19:09 2014
> @@ -16,6 +16,8 @@
> */
> package org.apache.logging.log4j.core.lookup;
>
> +import java.util.HashMap;
> +import java.util.List;
> import java.util.Map;
>
> import org.apache.logging.log4j.core.LogEvent;
> @@ -23,25 +25,82 @@ import org.apache.logging.log4j.core.con
> import org.apache.logging.log4j.message.MapMessage;
>
> /**
> - * The basis for a lookup based on a Map.
> + * A map-based lookup.
> */
> @Plugin(name = "map", category = "Lookup")
> public class MapLookup implements StrLookup {
> -
> +
> /**
> - * Map keys are variable names and value.
> + * A singleton used by a main method to save its arguments.
> */
> - private final Map<String, String> map;
> + static final MapLookup MAIN_SINGLETON = new MapLookup(newMap(0));
> +
> + static Map<String, String> initMap(final String[] srcArgs, final Map<String, String> destMap) {
> + for (int i = 0; i < srcArgs.length; i++) {
> + final int next = i + 1;
> + final String value = srcArgs[i];
> + destMap.put(Integer.toString(i), value);
> + destMap.put(value, next < srcArgs.length ? srcArgs[next] : null);
> + }
> + return destMap;
> + }
> +
> + private static HashMap<String, String> newMap(final int initialCapacity) {
> + return new HashMap<String, String>(initialCapacity);
> + }
>
> /**
> - * Creates a new instance backed by a Map. Used by the default lookup.
> - *
> - * @param map the map of keys to values, may be null
> + * An application's {@code public static main(String[])} method calls this method to make its main arguments
> + * available for lookup with the prefix {@code main}.
> + * <p>
> + * The map provides two kinds of access: First by index, starting at {@code "0"}, {@code "1"} and so on. For
> + * example, the command line {@code --file path/file.txt -x 2} can be accessed from a configuration file with:
> + * </p>
> + * <ul>
> + * <li>{@code "main:0"} = {@code "--file"}</li>
> + * <li>{@code "main:1"} = {@code "path/file.txt"}</li>
> + * <li>{@code "main:2"} = {@code "-x"}</li>
> + * <li>{@code "main:3"} = {@code "2"}</li>
> + * </ul>
> + * <p>
> + * Second using the argument at position n as the key to access the value at n+1.
> + * </p>
> + * <ul>
> + * <li>{@code "main:--file"} = {@code "path/file.txt"}</li>
> + * <li>{@code "main:-x"} = {@code "2"}</li>
> + * </ul>
> + *
> + * @param args
> + * An application's {@code public static main(String[])} arguments.
> + * @since 2.1
> */
> - public MapLookup(final Map<String, String> map) {
> - this.map = map;
> + public static void setMainArguments(final String[] args) {
> + if (args == null) {
> + return;
> + }
> + initMap(args, MAIN_SINGLETON.map);
> + }
> +
> + static Map<String, String> toMap(final List<String> args) {
> + if (args == null) {
> + return null;
> + }
> + final int size = args.size();
> + return initMap(args.toArray(new String[size]), newMap(size));
> }
>
> + static Map<String, String> toMap(final String[] args) {
> + if (args == null) {
> + return null;
> + }
> + return initMap(args, newMap(args.length));
> + }
> +
> + /**
> + * Map keys are variable names and value.
> + */
> + private final Map<String, String> map;
> +
> /**
> * Constructor when used directly as a plugin.
> */
> @@ -50,21 +109,13 @@ public class MapLookup implements StrLoo
> }
>
> /**
> - * Looks up a String key to a String value using the map.
> - * <p>
> - * If the map is null, then null is returned.
> - * The map result object is converted to a string using toString().
> - * </p>
> + * Creates a new instance backed by a Map. Used by the default lookup.
> *
> - * @param key the key to be looked up, may be null
> - * @return the matching value, null if no match
> + * @param map
> + * the map of keys to values, may be null
> */
> - @Override
> - public String lookup(final String key) {
> - if (map == null) {
> - return null;
> - }
> - return map.get(key);
> + public MapLookup(final Map<String, String> map) {
> + this.map = map;
> }
>
> @Override
> @@ -83,4 +134,23 @@ public class MapLookup implements StrLoo
> }
> return null;
> }
> +
> + /**
> + * Looks up a String key to a String value using the map.
> + * <p>
> + * If the map is null, then null is returned. The map result object is converted to a string using toString().
> + * </p>
> + *
> + * @param key
> + * the key to be looked up, may be null
> + * @return the matching value, null if no match
> + */
> + @Override
> + public String lookup(final String key) {
> + if (map == null) {
> + return null;
> + }
> + return map.get(key);
> + }
> +
> }
>
> Added: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java
> URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java?rev=1619026&view=auto
> ==============================================================================
> --- logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java (added)
> +++ logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java Wed Aug 20 03:19:09 2014
> @@ -0,0 +1,57 @@
> +/*
> + * 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 org.junit.Test;
> +
> +/**
> + * Tests {@link JmxRuntimeInputArgumentsLookup} from the command line, not a JUnit test.
> + *
> + * From an IDE or CLI: --file foo.txt
> + *
> + * @since 2.1
> + */
> +public class MainInputArgumentsJmxLookupTest {
> +
> + public static void main(String[] args) {
> + new MainInputArgumentsJmxLookupTest().callFromMain();
> + }
> +
> + @Test
> + public void testMap() {
> + JmxRuntimeInputArgumentsLookup lookup = JmxRuntimeInputArgumentsLookup.JMX_SINGLETON;
> + assertEquals(null, lookup.lookup(null));
> + assertEquals(null, lookup.lookup("X"));
> + assertEquals(null, lookup.lookup("foo.txt"));
> + }
> +
> + public void callFromMain() {
> + JmxRuntimeInputArgumentsLookup lookup = JmxRuntimeInputArgumentsLookup.JMX_SINGLETON;
> + assertEquals(null, lookup.lookup(null));
> + assertEquals(null, lookup.lookup("X"));
> + // Eclipse adds -Dfile.encoding=Cp1252
> + // assertEquals("--file", lookup.lookup("0"));
> + // assertEquals("foo.txt", lookup.lookup("1"));
> + //
> + // JMX does not include the main arguments.
> + // assertEquals("foo.txt", lookup.lookup("--file"));
> + // assertEquals(null, lookup.lookup("foo.txt"));
> + }
> +
> +}
>
> Propchange: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java
> ------------------------------------------------------------------------------
> svn:eol-style = native
>
> Propchange: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java
> ------------------------------------------------------------------------------
> svn:keywords = Id
>
> Added: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsMapLookup.java
> URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsMapLookup.java?rev=1619026&view=auto
> ==============================================================================
> --- logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsMapLookup.java (added)
> +++ logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsMapLookup.java Wed Aug 20 03:19:09 2014
> @@ -0,0 +1,41 @@
> +package org.apache.logging.log4j.core.lookup;
> +
> +import java.util.Map;
> +
> +/**
> + * Work in progress, saved for future experimentation.
> + *
> + * TODO The goal is to use the Sun debugger API to find the main arg values on the stack.
> + */
> +public class MainInputArgumentsMapLookup extends MapLookup {
> +
> + public static final MainInputArgumentsMapLookup SINGLETON_STACK;
> +
> + static {
> + Map<Thread, StackTraceElement[]> allStackTraces = Thread.getAllStackTraces();
> + String[] args = null;
> + for (Map.Entry<Thread, StackTraceElement[]> entry : allStackTraces.entrySet()) {
> + StackTraceElement[] stackTraceElements = entry.getValue();
> + Thread thread = entry.getKey();
> + // Can't use the thread name to look for "main" since anyone can set it.
> + // Can't use thread ID since it can be any positive value, and is likely vender dependent. Oracle seems to
> + // use 1.
> + // We are left to look for "main" at the top of the stack
> + if (stackTraceElements != null) {
> + final int frame0 = stackTraceElements.length - 1;
> + if ("main".equals(stackTraceElements[frame0].getMethodName())) {
> + // We could further validate the main is a public static void method that takes a String[], if not,
> + // look at the other threads.
> + //
> + // How do we get the main args from the stack with the debug API?
> + // Must we be started in debug mode? Seems like it.
> + }
> + }
> + }
> + SINGLETON_STACK = new MainInputArgumentsMapLookup(MapLookup.toMap(args));
> + }
> +
> + public MainInputArgumentsMapLookup(Map<String, String> map) {
> + super(map);
> + }
> +}
>
> Propchange: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsMapLookup.java
> ------------------------------------------------------------------------------
> svn:eol-style = native
>
> Propchange: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsMapLookup.java
> ------------------------------------------------------------------------------
> svn:keywords = Id
>
> Modified: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MapLookupTest.java
> URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MapLookupTest.java?rev=1619026&r1=1619025&r2=1619026&view=diff
> ==============================================================================
> --- logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MapLookupTest.java (original)
> +++ logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MapLookupTest.java Wed Aug 20 03:19:09 2014
> @@ -49,4 +49,19 @@ public class MapLookupTest {
> assertEquals(null, lookup.lookup(null));
> assertEquals(null, lookup.lookup("X"));
> }
> +
> + @Test
> + public void testMainMap() {
> + MapLookup.setMainArguments(new String[] {
> + "--file",
> + "foo.txt" });
> + MapLookup lookup = MapLookup.MAIN_SINGLETON;
> + assertEquals(null, lookup.lookup(null));
> + assertEquals(null, lookup.lookup("X"));
> + assertEquals("--file", lookup.lookup("0"));
> + assertEquals("foo.txt", lookup.lookup("1"));
> + assertEquals("foo.txt", lookup.lookup("--file"));
> + assertEquals(null, lookup.lookup("foo.txt"));
> + }
> +
> }
>
> Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml
> URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/changes/changes.xml?rev=1619026&r1=1619025&r2=1619026&view=diff
> ==============================================================================
> --- logging/log4j/log4j2/trunk/src/changes/changes.xml (original)
> +++ logging/log4j/log4j2/trunk/src/changes/changes.xml Wed Aug 20 03:19:09 2014
> @@ -21,10 +21,16 @@
> <title>Changes</title>
> </properties>
> <body>
> - <release version="2.?.?" date="2014-??-??" description="Bug fixes and enhancements">
> + <release version="2.?.?" date="2014-??-??" description="Bug fixes and enhancements">
> <action issue="LOG4J2-783" dev="rpopma" type="fix" due-to="Minglei Lee">
> PatternLayout should use platform character encoding by default, not UTF-8.
> </action>
> + <action issue="LOG4J2-771" dev="ggregory" type="add">
> + Add lookup for application main arguments.
> + </action>
> + <action issue="LOG4J2-787" dev="ggregory" type="add">
> + Add lookup for JVM arguments.
> + </action>
> </release>
> <release version="2.0.2" date="2014-08-16" description="Bug fixes and enhancements">
> <action issue="LOG4J2-775" dev="ggregory" type="update">
>
> Modified: logging/log4j/log4j2/trunk/src/site/xdoc/manual/configuration.xml.vm
> URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/site/xdoc/manual/configuration.xml.vm?rev=1619026&r1=1619025&r2=1619026&view=diff
> ==============================================================================
> --- logging/log4j/log4j2/trunk/src/site/xdoc/manual/configuration.xml.vm (original)
> +++ logging/log4j/log4j2/trunk/src/site/xdoc/manual/configuration.xml.vm Wed Aug 20 03:19:09 2014
> @@ -869,6 +869,14 @@ public class Bar {
> <td>System environment variables</td>
> </tr>
> <tr>
> + <td>jmx-input</td>
> + <td>A JVM input argument accessed through JMX, but not a main argument; see <a href="http://docs.oracle.com/javase/8/docs/api/java/lang/management/RuntimeMXBean.html#getInputArguments--">RuntimeMXBean.html#getInputArguments()</a></td>
> + </tr>
> + <tr>
> + <td>main</td>
> + <td>A value set with <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/MapLookup.html#setMainArguments%28java.lang.String[]%29">MapLookup.setMainArguments(String[])</a></td>
> + </tr>
> + <tr>
> <td>map</td>
> <td>A value from a MapMessage</td>
> </tr>
>
> 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=1619026&r1=1619025&r2=1619026&view=diff
> ==============================================================================
> --- logging/log4j/log4j2/trunk/src/site/xdoc/manual/lookups.xml (original)
> +++ logging/log4j/log4j2/trunk/src/site/xdoc/manual/lookups.xml Wed Aug 20 03:19:09 2014
> @@ -98,11 +98,12 @@
> <subsection name="MapLookup">
> <a name="MapLookup"/>
> <p>
> - The MapLookup serves two purposes.
> + The MapLookup serves several purposes.
> </p>
> <ol>
> <li>Provide the base for Properties declared in the configuration file.</li>
> <li>Retrieve values from MapMessages in LogEvents.</li>
> + <li>Retrieve values set with <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/MapLookup.html#setMainArguments%28java.lang.String[]%29">MapLookup.setMainArguments(String[])</a></li>
> </ol>
> <p>
> The first item simply means that the MapLookup is used to substitute properties that are defined
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org