logging-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rgo...@apache.org
Subject svn commit: r1469973 [1/2] - in /logging/log4j/log4j2/trunk: api/src/main/java/org/apache/logging/log4j/simple/ api/src/main/java/org/apache/logging/log4j/status/ core/ core/src/main/java/org/apache/logging/log4j/core/ core/src/main/java/org/apache/log...
Date Fri, 19 Apr 2013 17:59:12 GMT
Author: rgoers
Date: Fri Apr 19 17:59:11 2013
New Revision: 1469973

URL: http://svn.apache.org/r1469973
Log:
LOG4J2-207 - Add JMX support. Also add missing license headers.

Added:
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/AppenderAdmin.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/AppenderAdminMBean.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/Assert.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/Client.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ClientEditConfigPanel.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ClientGUI.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ClientGUIJConsolePlugin.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ContextSelectorAdmin.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ContextSelectorAdminMBean.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerConfigAdmin.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerConfigAdminMBean.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerContextAdmin.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerContextAdminMBean.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/StatusLoggerAdmin.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/StatusLoggerAdminMBean.java
    logging/log4j/log4j2/trunk/core/src/main/resources/META-INF/services/
    logging/log4j/log4j2/trunk/core/src/main/resources/META-INF/services/com.sun.tools.jconsole.JConsolePlugin
    logging/log4j/log4j2/trunk/src/site/resources/images/jmx-jconsole-editconfig.png   (with props)
    logging/log4j/log4j2/trunk/src/site/resources/images/jmx-jconsole-mbeans.png   (with props)
    logging/log4j/log4j2/trunk/src/site/resources/images/jmx-jconsole-statuslogger.png   (with props)
    logging/log4j/log4j2/trunk/src/site/resources/images/jmx-standalone-editconfig.png   (with props)
    logging/log4j/log4j2/trunk/src/site/resources/images/jmx-standalone-statuslogger.png   (with props)
Removed:
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/Log4jManager.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/Log4jManagerMBean.java
Modified:
    logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/simple/SimpleLogger.java
    logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/status/StatusData.java
    logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java
    logging/log4j/log4j2/trunk/core/pom.xml
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/helpers/SecretKeyProvider.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java
    logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/async/perftest/IPerfTestRunner.java
    logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/async/perftest/MTPerfTest.java
    logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/async/perftest/PerfTest.java
    logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/async/perftest/PerfTestDriver.java
    logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/async/perftest/PerfTestResultFormatter.java
    logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/async/perftest/RunLog4j1.java
    logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/async/perftest/RunLog4j2.java
    logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/async/perftest/RunLogback.java
    logging/log4j/log4j2/trunk/src/changes/changes.xml
    logging/log4j/log4j2/trunk/src/site/xdoc/manual/jmx.xml

Modified: logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/simple/SimpleLogger.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/simple/SimpleLogger.java?rev=1469973&r1=1469972&r2=1469973&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/simple/SimpleLogger.java (original)
+++ logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/simple/SimpleLogger.java Fri Apr 19 17:59:11 2013
@@ -89,6 +89,10 @@ public class SimpleLogger extends Abstra
     public void setStream(final PrintStream stream) {
         this.stream = stream;
     }
+    
+    public Level getLevel() {
+        return level;
+    }
 
     public void setLevel(final Level level) {
         if (level != null) {

Modified: logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/status/StatusData.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/status/StatusData.java?rev=1469973&r1=1469972&r2=1469973&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/status/StatusData.java (original)
+++ logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/status/StatusData.java Fri Apr 19 17:59:11 2013
@@ -21,22 +21,20 @@ import org.apache.logging.log4j.message.
 
 import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
+import java.io.Serializable;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 
 /**
  * The Status data.
  */
-public class StatusData {
+public class StatusData implements Serializable {
+    private static final long serialVersionUID = -4341916115118014017L;
 
     private final long timestamp;
-
     private final StackTraceElement caller;
-
     private final Level level;
-
     private final Message msg;
-
     private final Throwable throwable;
 
     /**

Modified: logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java?rev=1469973&r1=1469972&r2=1469973&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java (original)
+++ logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java Fri Apr 19 17:59:11 2013
@@ -73,6 +73,10 @@ public final class StatusLogger extends 
     public static StatusLogger getLogger() {
         return STATUS_LOGGER;
     }
+    
+    public Level getLevel() {
+        return logger.getLevel();
+    }
 
     public void setLevel(final Level level) {
         logger.setLevel(level);

Modified: logging/log4j/log4j2/trunk/core/pom.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/pom.xml?rev=1469973&r1=1469972&r2=1469973&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/pom.xml (original)
+++ logging/log4j/log4j2/trunk/core/pom.xml Fri Apr 19 17:59:11 2013
@@ -342,6 +342,53 @@
         </plugins>
       </build>
     </profile>
+		<profile>
+			<id>default-profile</id>
+			<activation>
+				<activeByDefault>true</activeByDefault>
+				<file>
+					<exists>${java.home}/../lib/jconsole.jar</exists>
+				</file>
+			</activation>
+			<properties>
+				<toolsjar>${java.home}/../lib/jconsole.jar</toolsjar>
+			</properties>
+
+			<dependencies>
+				<dependency>
+					<groupId>com.sun</groupId>
+					<artifactId>tools</artifactId>
+					<version>1.6.0</version>
+					<scope>system</scope>
+					<systemPath>${toolsjar}</systemPath>
+				</dependency>
+				<dependency>
+					<groupId>com.sun</groupId>
+					<artifactId>jconsole</artifactId>
+					<version>1.6.0</version>
+					<scope>system</scope>
+					<systemPath>${java.home}/../lib/jconsole.jar</systemPath>
+				</dependency>
+			</dependencies>
+		</profile>
+		<profile>
+			<id>mac-profile</id>
+			<activation>
+				<activeByDefault>false</activeByDefault>
+				<file>
+					<exists>${java.home}/../Classes/jconsole.jar</exists>
+				</file>
+			</activation>
+			<dependencies>
+				<dependency>
+					<groupId>com.sun</groupId>
+					<artifactId>jconsole</artifactId>
+					<version>1.6.0</version>
+					<scope>system</scope>
+					<systemPath>${java.home}/../Classes/jconsole.jar</systemPath>
+				</dependency>
+			</dependencies>
+		</profile>
   </profiles>
 </project>
 

Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java?rev=1469973&r1=1469972&r2=1469973&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java (original)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java Fri Apr 19 17:59:11 2013
@@ -16,12 +16,15 @@
  */
 package org.apache.logging.log4j.core;
 
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 import java.io.File;
 import java.net.URI;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
@@ -32,32 +35,34 @@ import org.apache.logging.log4j.core.con
 import org.apache.logging.log4j.core.config.NullConfiguration;
 import org.apache.logging.log4j.core.config.Reconfigurable;
 import org.apache.logging.log4j.core.helpers.NetUtils;
+import org.apache.logging.log4j.core.jmx.Assert;
 import org.apache.logging.log4j.message.MessageFactory;
 import org.apache.logging.log4j.spi.AbstractLogger;
 import org.apache.logging.log4j.status.StatusLogger;
 
 /**
- * The LoggerContext is the anchor for the logging system. It maintains a list of all the loggers requested by
- * applications and a reference to the Configuration. The Configuration will contain the configured loggers, appenders,
- * filters, etc and will be atomically updated whenever a reconfigure occurs.
+ * The LoggerContext is the anchor for the logging system. It maintains a list
+ * of all the loggers requested by applications and a reference to the
+ * Configuration. The Configuration will contain the configured loggers,
+ * appenders, filters, etc and will be atomically updated whenever a reconfigure
+ * occurs.
  */
 public class LoggerContext implements org.apache.logging.log4j.spi.LoggerContext, ConfigurationListener, LifeCycle {
 
+    public static final String PROPERTY_CONFIG = "config";
     private static final StatusLogger LOGGER = StatusLogger.getLogger();
 
     private final ConcurrentMap<String, Logger> loggers = new ConcurrentHashMap<String, Logger>();
+    private final CopyOnWriteArrayList<PropertyChangeListener> propertyChangeListeners = new CopyOnWriteArrayList<PropertyChangeListener>();
 
     /**
-     * The Configuration is volatile to guarantee that initialization of the Configuration has completed before
-     * the reference is updated.
+     * The Configuration is volatile to guarantee that initialization of the
+     * Configuration has completed before the reference is updated.
      */
     private volatile Configuration config = new DefaultConfiguration();
-
     private Object externalContext;
-
     private final String name;
-
-    private final URI configLocation;
+    private URI configLocation;
 
     private ShutdownThread shutdownThread = null;
 
@@ -111,8 +116,9 @@ public class LoggerContext implements or
     }
 
     /**
-     * Constructor taking a name external context and a configuration location String. The location
-     * must be resolvable to a File.
+     * Constructor taking a name external context and a configuration location
+     * String. The location must be resolvable to a File.
+     * 
      * @param name The configuration location.
      * @param externalContext The external context.
      * @param configLocn The configuration location.
@@ -216,8 +222,9 @@ public class LoggerContext implements or
     /**
      * Obtain a Logger from the Context.
      * @param name The name of the Logger to return.
-     * @param messageFactory The message factory is used only when creating a logger, subsequent use does not change
-     *                       the logger but will log a warning if mismatched.
+     * @param messageFactory The message factory is used only when creating a
+     *            logger, subsequent use does not change the logger but will log
+     *            a warning if mismatched.
      * @return The Logger.
      */
     public Logger getLogger(final String name, final MessageFactory messageFactory) {
@@ -242,7 +249,9 @@ public class LoggerContext implements or
     }
 
     /**
-     * Returns the current Configuration. The Configuration will be replaced when a reconfigure occurs.
+     * Returns the current Configuration. The Configuration will be replaced
+     * when a reconfigure occurs.
+     * 
      * @return The Configuration.
      */
     public Configuration getConfiguration() {
@@ -288,22 +297,43 @@ public class LoggerContext implements or
             prev.removeListener(this);
             prev.stop();
         }
+
+        // notify listeners
+        PropertyChangeEvent evt = new PropertyChangeEvent(this, PROPERTY_CONFIG, prev, config);
+        for (PropertyChangeListener listener : propertyChangeListeners) {
+            listener.propertyChange(evt);
+        }
         return prev;
     }
 
+    public void addPropertyChangeListener(PropertyChangeListener listener) {
+        propertyChangeListeners.add(Assert.isNotNull(listener, "listener"));
+    }
+
+    public void removePropertyChangeListener(PropertyChangeListener listener) {
+        propertyChangeListeners.remove(listener);
+    }
+
+    public synchronized URI getConfigLocation() {
+        return configLocation;
+    }
+
+    public synchronized void setConfigLocation(URI configLocation) {
+        this.configLocation = configLocation;
+        reconfigure();
+    }
+
     /**
-     *  Reconfigure the context.
+     * Reconfigure the context.
      */
     public synchronized void reconfigure() {
         LOGGER.debug("Reconfiguration started for context " + name);
         final Configuration instance = ConfigurationFactory.getInstance().getConfiguration(name, configLocation);
         setConfiguration(instance);
-        /*instance.start();
-        Configuration old = setConfiguration(instance);
-        updateLoggers();
-        if (old != null) {
-            old.stop();
-        } */
+        /*
+         * instance.start(); Configuration old = setConfiguration(instance);
+         * updateLoggers(); if (old != null) { old.stop(); }
+         */
         LOGGER.debug("Reconfiguration completed");
     }
 
@@ -325,7 +355,9 @@ public class LoggerContext implements or
     }
 
     /**
-     * Cause a reconfiguration to take place when the underlying configuration file changes.
+     * Cause a reconfiguration to take place when the underlying configuration
+     * file changes.
+     * 
      * @param reconfigurable The Configuration that can be reconfigured.
      */
     public synchronized void onChange(final Reconfigurable reconfigurable) {

Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/helpers/SecretKeyProvider.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/helpers/SecretKeyProvider.java?rev=1469973&r1=1469972&r2=1469973&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/helpers/SecretKeyProvider.java (original)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/helpers/SecretKeyProvider.java Fri Apr 19 17:59:11 2013
@@ -1,3 +1,19 @@
+/*
+ * 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.helpers;
 
 import javax.crypto.SecretKey;

Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java?rev=1469973&r1=1469972&r2=1469973&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java (original)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java Fri Apr 19 17:59:11 2013
@@ -16,17 +16,18 @@
  */
 package org.apache.logging.log4j.core.impl;
 
+import java.net.URI;
+
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.helpers.Constants;
 import org.apache.logging.log4j.core.helpers.Loader;
+import org.apache.logging.log4j.core.jmx.Server;
 import org.apache.logging.log4j.core.selector.ClassLoaderContextSelector;
 import org.apache.logging.log4j.core.selector.ContextSelector;
-import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.spi.LoggerContextFactory;
+import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.util.PropertiesUtil;
 
-import java.net.URI;
-
 /**
  * Factory to locate a ContextSelector and then load a LoggerContext.
  */
@@ -43,17 +44,22 @@ public class Log4jContextFactory impleme
         final String sel = PropertiesUtil.getProperties().getStringProperty(Constants.LOG4J_CONTEXT_SELECTOR);
         if (sel != null) {
             try {
-                final Class clazz = Loader.loadClass(sel);
+                final Class<?> clazz = Loader.loadClass(sel);
                 if (clazz != null && ContextSelector.class.isAssignableFrom(clazz)) {
                     selector = (ContextSelector) clazz.newInstance();
-                    return;
                 }
             } catch (final Exception ex) {
                 LOGGER.error("Unable to create context " + sel, ex);
             }
-
         }
-        selector = new ClassLoaderContextSelector();
+        if (selector == null) {
+            selector = new ClassLoaderContextSelector();
+        }
+        try {
+            Server.registerMBeans(selector);
+        } catch (Exception ex) {
+            LOGGER.error("Could not start JMX", ex);
+        }
     }
 
     /**
@@ -80,7 +86,6 @@ public class Log4jContextFactory impleme
         return ctx;
     }
 
-
     /**
      * Load the LoggerContext using the ContextSelector.
      * @param fqcn The fully qualified class name of the caller.
@@ -91,7 +96,7 @@ public class Log4jContextFactory impleme
      * @return The LoggerContext.
      */
     public LoggerContext getContext(final String fqcn, final ClassLoader loader, final boolean currentContext,
-                                    URI configLocation) {
+            URI configLocation) {
         final LoggerContext ctx = selector.getContext(fqcn, loader, currentContext, configLocation);
         if (ctx.getStatus() == LoggerContext.Status.INITIALIZED) {
             ctx.start();

Added: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/AppenderAdmin.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/AppenderAdmin.java?rev=1469973&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/AppenderAdmin.java (added)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/AppenderAdmin.java Fri Apr 19 17:59:11 2013
@@ -0,0 +1,77 @@
+/*
+ * 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.jmx;
+
+import javax.management.ObjectName;
+
+import org.apache.logging.log4j.core.Appender;
+
+/**
+ * Implementation of the {@code AppenderAdminMBean} interface.
+ */
+public class AppenderAdmin implements AppenderAdminMBean {
+
+    private final String contextName;
+    private final Appender<?> appender;
+    private final ObjectName objectName;
+
+    /**
+     * Constructs a new {@code AppenderAdmin} with the specified contextName
+     * and appender.
+     * 
+     * @param contextName used in the {@code ObjectName} for this mbean
+     * @param appender the instrumented object
+     */
+    public AppenderAdmin(String contextName, Appender<?> appender) {
+        // super(executor); // no notifications for now
+        this.contextName = Assert.isNotNull(contextName, "contextName");
+        this.appender = Assert.isNotNull(appender, "appender");
+        try {
+            String ctxName = Server.escape(this.contextName);
+            String configName = Server.escape(appender.getName());
+            String name = String.format(PATTERN, ctxName, configName);
+            objectName = new ObjectName(name);
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    /** @see AppenderAdminMBean#PATTERN */
+    public ObjectName getObjectName() {
+        return objectName;
+    }
+
+    @Override
+    public String getName() {
+        return appender.getName();
+    }
+    
+    @Override
+    public String getLayout() {
+        return String.valueOf(appender.getLayout());
+    }
+
+    @Override
+    public boolean isExceptionSuppressed() {
+        return appender.isExceptionSuppressed();
+    }
+    
+    @Override
+    public String getErrorHandler() {
+        return String.valueOf(appender.getHandler());
+    }
+}

Added: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/AppenderAdminMBean.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/AppenderAdminMBean.java?rev=1469973&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/AppenderAdminMBean.java (added)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/AppenderAdminMBean.java Fri Apr 19 17:59:11 2013
@@ -0,0 +1,59 @@
+/*
+ * 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.jmx;
+
+/**
+ * The MBean interface for monitoring and managing an {@code Appender}.
+ */
+public interface AppenderAdminMBean {
+    /** ObjectName pattern for AppenderAdmin MBeans. */
+    String PATTERN = "org.apache.logging.log4j2:type=LoggerContext,ctx=%s,sub=Appender,name=%s";
+
+    /**
+     * Returns the name of the instrumented {@code Appender}.
+     * 
+     * @return the name of the Appender
+     */
+    String getName();
+
+    /**
+     * Returns the result of calling {@code toString} on the {@code Layout}
+     * object of the instrumented {@code Appender}.
+     * 
+     * @return the {@code Layout} of the instrumented {@code Appender} as a
+     *         string
+     */
+    String getLayout();
+
+    /**
+     * Returns how exceptions thrown on the instrumented {@code Appender} are
+     * handled.
+     * 
+     * @return {@code true} if any exceptions thrown by the Appender will be
+     *         logged or {@code false} if such exceptions are re-thrown.
+     */
+    boolean isExceptionSuppressed();
+
+    /**
+     * Returns the result of calling {@code toString} on the error handler of
+     * this appender, or {@code "null"} if no error handler was set.
+     * 
+     * @return result of calling {@code toString} on the error handler of this
+     *         appender, or {@code "null"}
+     */
+    String getErrorHandler();
+}

Added: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/Assert.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/Assert.java?rev=1469973&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/Assert.java (added)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/Assert.java Fri Apr 19 17:59:11 2013
@@ -0,0 +1,58 @@
+/*
+ * 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.jmx;
+
+/**
+ * Utility class providing common validation logic.
+ */
+public class Assert {
+    private Assert() {
+    }
+
+    /**
+     * Throws a {@code NullPointerException} if the specified parameter is
+     * {@code null}, otherwise returns the specified parameter.
+     * <p>
+     * Usage:
+     * 
+     * <pre>
+     * // earlier you would write this:
+     * public SomeConstructor(Object param) {
+     *     if (param == null) {
+     *         throw new NullPointerException(name + &quot; is null&quot;);
+     *     }
+     *     this.field = param;
+     * }
+     * 
+     * // now you can do the same in one line:
+     * public SomeConstructor(Object param) {
+     *     this.field = Assert.isNotNull(param);
+     * }
+     * </pre>
+     * 
+     * @param checkMe the parameter to check
+     * @param name name of the parameter to use in the error message if
+     *            {@code null}
+     * @return the specified parameter
+     */
+    public static <T> T isNotNull(T checkMe, String name) {
+        if (checkMe == null) {
+            throw new NullPointerException(name + " is null");
+        }
+        return checkMe;
+    }
+}

Added: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/Client.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/Client.java?rev=1469973&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/Client.java (added)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/Client.java Fri Apr 19 17:59:11 2013
@@ -0,0 +1,149 @@
+/*
+ * 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.jmx;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.management.JMX;
+import javax.management.MBeanServerConnection;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+
+/**
+ * This class allows client-side code to perform operations on remote
+ * (server-side) MBeans via proxies.
+ */
+public class Client {
+    private JMXConnector connector;
+    private MBeanServerConnection connection;
+    private StatusLoggerAdminMBean statusLoggerAdmin;
+    private ContextSelectorAdminMBean contextSelectorAdmin;
+    private List<LoggerContextAdminMBean> contextAdminList;
+
+    /**
+     * Constructs a new {@code Client} object and creates proxies for all known
+     * remote MBeans.
+     * 
+     * @param connector used to create the MBean server connection through which
+     *            to communicate with the remote mbeans
+     * @throws MalformedObjectNameException if a problem occurred identifying
+     *             one of the remote mbeans
+     * @throws IOException if the connection failed
+     */
+    public Client(JMXConnector connector) throws MalformedObjectNameException,
+            IOException {
+        this.connector = Assert.isNotNull(connector, "JMXConnector");
+        this.connector.connect();
+        this.connection = connector.getMBeanServerConnection();
+        init();
+    }
+
+    /**
+     * Constructs a new {@code Client} object and creates proxies for all known
+     * remote MBeans.
+     * 
+     * @param mBeanServerConnection the MBean server connection through which to
+     *            communicate with the remote mbeans
+     * @throws MalformedObjectNameException if a problem occurred identifying
+     *             one of the remote mbeans
+     * @throws IOException if the connection failed
+     */
+    public Client(MBeanServerConnection mBeanServerConnection)
+            throws MalformedObjectNameException, IOException {
+        this.connection = mBeanServerConnection;
+        init();
+    }
+
+    private void init() throws MalformedObjectNameException, IOException {
+        statusLoggerAdmin = JMX.newMBeanProxy(connection, //
+                new ObjectName(StatusLoggerAdminMBean.NAME), //
+                StatusLoggerAdminMBean.class, true);
+
+        contextSelectorAdmin = JMX.newMBeanProxy(connection, //
+                new ObjectName(ContextSelectorAdminMBean.NAME), //
+                ContextSelectorAdminMBean.class, false);
+
+        contextAdminList = new ArrayList<LoggerContextAdminMBean>();
+        String pattern = String.format(LoggerContextAdminMBean.PATTERN, "*");
+        ObjectName search = new ObjectName(pattern);
+        Set<ObjectName> found = connection.queryNames(search, null);
+        for (ObjectName contextName : found) {
+            LoggerContextAdminMBean ctx = JMX.newMBeanProxy(connection, //
+                    contextName, //
+                    LoggerContextAdminMBean.class, false);
+            contextAdminList.add(ctx);
+
+            // TODO Appenders, LoggerConfigs
+        }
+    }
+
+    /**
+     * Returns a proxy that allows operations to be performed on the remote
+     * {@code ContextSelectorAdminMBean}.
+     * 
+     * @return a proxy to the remote {@code ContextSelectorAdminMBean}
+     */
+    public ContextSelectorAdminMBean getContextSelectorAdmin() {
+        return contextSelectorAdmin;
+    }
+
+    /**
+     * Returns a list of proxies that allow operations to be performed on the
+     * remote {@code LoggerContextAdminMBean}s.
+     * 
+     * @return a list of proxies to the remote {@code LoggerContextAdminMBean}s
+     */
+    public List<LoggerContextAdminMBean> getLoggerContextAdmins() {
+        return new ArrayList<LoggerContextAdminMBean>(contextAdminList);
+    }
+
+    /**
+     * Closes the client connection to its server. Any ongoing or new requests
+     * to the MBeanServerConnection will fail.
+     */
+    public void close() {
+        try {
+            connector.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Returns the MBean server connection through which to communicate with the
+     * remote mbeans.
+     * 
+     * @return the MBean server connection
+     */
+    public MBeanServerConnection getConnection() {
+        return connection;
+    }
+
+    /**
+     * Returns a proxy that allows operations to be performed on the remote
+     * {@code StatusLoggerAdminMBean}.
+     * 
+     * @return a proxy to the remote {@code StatusLoggerAdminMBean}
+     */
+    public StatusLoggerAdminMBean getStatusLoggerAdmin() {
+        return statusLoggerAdmin;
+    }
+}

Added: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ClientEditConfigPanel.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ClientEditConfigPanel.java?rev=1469973&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ClientEditConfigPanel.java (added)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ClientEditConfigPanel.java Fri Apr 19 17:59:11 2013
@@ -0,0 +1,149 @@
+/*
+ * 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.jmx;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import javax.swing.AbstractAction;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+
+/**
+ * Panel for editing Log4J configurations.
+ */
+public class ClientEditConfigPanel extends JPanel {
+    private static final long serialVersionUID = -7544651740950723394L;
+    private static final int LOCATION_TEXT_COLS = 50;
+    private static final int CONFIG_TEXT_COLS = 60;
+    private static final int CONFIG_TEXT_ROWS = 20;
+    private static final int BUFFER_SIZE = 2048;
+    
+    private JTextField locationTextField;
+    private JLabel locationLabel;
+    private JButton buttonSendLocation;
+    private JButton buttonSendConfigText;
+    private JTextArea configTextArea;
+    private LoggerContextAdminMBean contextAdmin;
+
+    private AbstractAction actionReconfigureFromLocation = new AbstractAction(
+            "Reconfigure from Location") {
+        private static final long serialVersionUID = 6995219797596745774L;
+
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            try {
+                contextAdmin.setConfigLocationURI(locationTextField.getText());
+                populateWidgets();
+                showConfirmation();
+            } catch (Exception ex) {
+                populateWidgets();
+                handle("Could not reconfigure from location", ex);
+            }
+        }
+    };
+    private AbstractAction actionReconfigureFromText = new AbstractAction(
+            "Reconfigure with XML Below") {
+        private static final long serialVersionUID = -2846103707134292312L;
+
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            String encoding = System.getProperty("file.encoding");
+            try {
+                contextAdmin.setConfigText(configTextArea.getText(), encoding);
+                populateWidgets();
+                showConfirmation();
+            } catch (Exception ex) {
+                populateWidgets();
+                handle("Could not reconfigure from XML", ex);
+            }
+        }
+    };
+
+    private void handle(String msg, Exception ex) {
+        StringWriter sr = new StringWriter(BUFFER_SIZE);
+        PrintWriter pw = new PrintWriter(sr);
+        pw.println("Please check the StatusLogger tab for details");
+        pw.println();
+        ex.printStackTrace(pw);
+        JOptionPane.showMessageDialog(this, sr.toString(), msg,
+                JOptionPane.ERROR_MESSAGE);
+    }
+
+    private void showConfirmation() {
+        JOptionPane.showMessageDialog(this, "Reconfiguration complete.",
+                "Reconfiguration complete", JOptionPane.INFORMATION_MESSAGE);
+    }
+
+    public ClientEditConfigPanel(LoggerContextAdminMBean contextAdmin) {
+        this.contextAdmin = contextAdmin;
+        createWidgets();
+        populateWidgets();
+    }
+
+    private void populateWidgets() {
+        try {
+            configTextArea.setText(contextAdmin.getConfigText());
+        } catch (Exception ex) {
+            StringWriter sw = new StringWriter(2048);
+            ex.printStackTrace(new PrintWriter(sw));
+            configTextArea.setText(sw.toString());
+        }
+        String uri = contextAdmin.getConfigLocationURI();
+        locationTextField.setText(uri);
+    }
+
+    private void createWidgets() {
+        configTextArea = new JTextArea(CONFIG_TEXT_ROWS, CONFIG_TEXT_COLS);
+        // configTextArea.setEditable(false);
+        configTextArea.setBackground(Color.white);
+        configTextArea.setForeground(Color.black);
+        configTextArea.setFont(new Font("Monospaced", Font.PLAIN,
+                configTextArea.getFont().getSize()));
+        JScrollPane scrollConfig = new JScrollPane(configTextArea);
+
+        locationTextField = new JTextField(LOCATION_TEXT_COLS);
+        locationLabel = new JLabel("Location: ");
+        locationLabel.setLabelFor(locationTextField);
+        buttonSendLocation = new JButton(actionReconfigureFromLocation);
+        buttonSendConfigText = new JButton(actionReconfigureFromText);
+
+        JPanel north = new JPanel();
+        north.setLayout(new BoxLayout(north, BoxLayout.LINE_AXIS));
+        north.add(locationLabel);
+        north.add(locationTextField);
+        north.add(buttonSendLocation);
+        north.add(Box.createRigidArea(new Dimension(20, 0)));
+        north.add(buttonSendConfigText);
+
+        this.setLayout(new BorderLayout());
+        this.add(north, BorderLayout.NORTH);
+        this.add(scrollConfig, BorderLayout.CENTER);
+    }
+}
\ No newline at end of file

Added: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ClientGUI.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ClientGUI.java?rev=1469973&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ClientGUI.java (added)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ClientGUI.java Fri Apr 19 17:59:11 2013
@@ -0,0 +1,201 @@
+/*
+ * 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.jmx;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Font;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MalformedObjectNameException;
+import javax.management.Notification;
+import javax.management.NotificationFilterSupport;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UIManager.LookAndFeelInfo;
+
+/**
+ * GUI that connects to a Java process via JMX and allows the user to view and
+ * modify the log4j2 configuration, as well as monitor status logs.
+ * 
+ * @see http 
+ *      ://docs.oracle.com/javase/6/docs/technotes/guides/management/jconsole
+ *      .html
+ */
+public class ClientGUI extends JPanel implements NotificationListener {
+    private static final long serialVersionUID = -253621277232291174L;
+    private Client client;
+    private JTextArea statusLogTextArea;
+    private JTabbedPane tabbedPane;
+
+    public ClientGUI(Client client) throws InstanceNotFoundException,
+            MalformedObjectNameException, IOException {
+        this.client = Assert.isNotNull(client, "client");
+        createWidgets();
+        populateWidgets();
+        registerListeners();
+    }
+
+    private void createWidgets() {
+        statusLogTextArea = new JTextArea();
+        statusLogTextArea.setEditable(false);
+        statusLogTextArea.setBackground(this.getBackground());
+        statusLogTextArea.setForeground(Color.black);
+        statusLogTextArea.setFont(new Font("Monospaced", Font.PLAIN,
+                statusLogTextArea.getFont().getSize()));
+        JScrollPane scrollStatusLog = new JScrollPane(statusLogTextArea);
+
+        tabbedPane = new JTabbedPane();
+        tabbedPane.addTab("StatusLogger", scrollStatusLog);
+
+        this.setLayout(new BorderLayout());
+        this.add(tabbedPane, BorderLayout.CENTER);
+    }
+
+    private void populateWidgets() {
+
+        StatusLoggerAdminMBean statusAdmin = client.getStatusLoggerAdmin();
+        String[] messages = statusAdmin.getStatusDataHistory();
+        for (String message : messages) {
+            statusLogTextArea.append(message + "\n");
+        }
+
+        for (LoggerContextAdminMBean ctx : client.getLoggerContextAdmins()) {
+            ClientEditConfigPanel editor = new ClientEditConfigPanel(ctx);
+            tabbedPane.addTab("LoggerContext: " + ctx.getName(), editor);
+        }
+    }
+
+    private void registerListeners() throws InstanceNotFoundException,
+            MalformedObjectNameException, IOException {
+        NotificationFilterSupport filter = new NotificationFilterSupport();
+        filter.enableType(StatusLoggerAdminMBean.NOTIF_TYPE_MESSAGE);
+        ObjectName objName = new ObjectName(StatusLoggerAdminMBean.NAME);
+        client.getConnection().addNotificationListener(objName, this, filter,
+                null);
+    }
+
+    @Override
+    public void handleNotification(Notification notif, Object paramObject) {
+        if (StatusLoggerAdminMBean.NOTIF_TYPE_MESSAGE.equals(notif.getType())) {
+            statusLogTextArea.append(notif.getMessage() + "\n");
+        }
+    }
+
+    /**
+     * Connects to the specified location and shows this panel in a window.
+     * <p>
+     * Useful links:
+     * http://www.componative.com/content/controller/developer/insights
+     * /jconsole3/
+     * 
+     * @param args
+     *            must have at least one parameter, which specifies the location
+     *            to connect to. Must be of the form {@code host:port} or
+     *            {@code service:jmx:rmi:///jndi/rmi://<host>:<port>/jmxrmi} or
+     *            {@code service:jmx:rmi://<host>:<port>/jndi/rmi://<host>:<port>/jmxrmi}
+     */
+    public static void main(String[] args) throws Exception {
+        if (args.length < 1) {
+            usage();
+            return;
+        }
+        String serviceUrl = args[0];
+        if (!serviceUrl.startsWith("service:jmx")) {
+            serviceUrl = "service:jmx:rmi:///jndi/rmi://" + args[0] + "/jmxrmi";
+        }
+        JMXServiceURL url = new JMXServiceURL(serviceUrl);
+        Map<String, String> paramMap = new HashMap<String, String>();
+        for (Object objKey : System.getProperties().keySet()) {
+            String key = (String) objKey;
+            paramMap.put(key, System.getProperties().getProperty(key));
+        }
+        JMXConnector connector = JMXConnectorFactory.connect(url, paramMap);
+        final Client client = new Client(connector);
+        final String title = "Log4J2 JMX Client - " + url;
+
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                installLookAndFeel();
+                try {
+                    ClientGUI gui = new ClientGUI(client);
+                    JFrame frame = new JFrame(title);
+                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+                    frame.getContentPane().add(gui, BorderLayout.CENTER);
+                    frame.pack();
+                    frame.setVisible(true);
+                } catch (Exception ex) {
+                    // if console is visible, print error so that
+                    // the stack trace remains visible after error dialog is
+                    // closed
+                    ex.printStackTrace();
+
+                    // show error in dialog: there may not be a console window
+                    // visible
+                    StringWriter sr = new StringWriter();
+                    ex.printStackTrace(new PrintWriter(sr));
+                    JOptionPane.showMessageDialog(null, sr.toString(), "Error",
+                            JOptionPane.ERROR_MESSAGE);
+                }
+            }
+        });
+    }
+
+    private static void usage() {
+        String me = ClientGUI.class.getName();
+        System.err.println("Usage: java " + me + " <host>:<port>");
+        System.err.println("   or: java " + me
+                + " service:jmx:rmi:///jndi/rmi://<host>:<port>/jmxrmi");
+        String longAdr = " service:jmx:rmi://<host>:<port>/jndi/rmi://<host>:<port>/jmxrmi";
+        System.err.println("   or: java " + me + longAdr);
+    }
+
+    private static void installLookAndFeel() {
+        try {
+            for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
+                if ("Nimbus".equals(info.getName())) {
+                    UIManager.setLookAndFeel(info.getClassName());
+                    return;
+                }
+            }
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+        try {
+            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

Added: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ClientGUIJConsolePlugin.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ClientGUIJConsolePlugin.java?rev=1469973&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ClientGUIJConsolePlugin.java (added)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ClientGUIJConsolePlugin.java Fri Apr 19 17:59:11 2013
@@ -0,0 +1,49 @@
+/*
+ * 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.jmx;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.JPanel;
+import javax.swing.SwingWorker;
+
+import com.sun.tools.jconsole.JConsolePlugin;
+
+/**
+ * Adapts the {@code ClientGUI} to the {@code JConsolePlugin} API.
+ */
+public class ClientGUIJConsolePlugin extends JConsolePlugin {
+
+    @Override
+    public Map<String, JPanel> getTabs() {
+        try {
+            Client client = new Client(getContext().getMBeanServerConnection());
+            ClientGUI gui = new ClientGUI(client);
+            Map<String, JPanel> result = new HashMap<String, JPanel>();
+            result.put("Log4j2", gui);
+            return result;
+        } catch (Throwable ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
+
+    @Override
+    public SwingWorker<?, ?> newSwingWorker() {
+        return null;
+    }
+}
\ No newline at end of file

Added: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ContextSelectorAdmin.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ContextSelectorAdmin.java?rev=1469973&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ContextSelectorAdmin.java (added)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ContextSelectorAdmin.java Fri Apr 19 17:59:11 2013
@@ -0,0 +1,55 @@
+/*
+ * 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.jmx;
+
+import javax.management.ObjectName;
+
+import org.apache.logging.log4j.core.selector.ContextSelector;
+
+/**
+ * Implementation of the {@code ContextSelectorAdminMBean} interface.
+ */
+public class ContextSelectorAdmin implements ContextSelectorAdminMBean {
+
+    private final ObjectName objectName;
+    private final ContextSelector selector;
+
+    /**
+     * Constructs a new {@code ContextSelectorAdmin}.
+     * 
+     * @param selector the instrumented object
+     */
+    public ContextSelectorAdmin(ContextSelector selector) {
+        super();
+        this.selector = Assert.isNotNull(selector, "ContextSelector");
+        try {
+            objectName = new ObjectName(NAME);
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    /** @see ContextSelectorAdminMBean#NAME */
+    public ObjectName getObjectName() {
+        return objectName;
+    }
+
+    @Override
+    public String getImplementationClassName() {
+        return selector.getClass().getName();
+    }
+}

Added: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ContextSelectorAdminMBean.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ContextSelectorAdminMBean.java?rev=1469973&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ContextSelectorAdminMBean.java (added)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/ContextSelectorAdminMBean.java Fri Apr 19 17:59:11 2013
@@ -0,0 +1,33 @@
+/*
+ * 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.jmx;
+
+/**
+ * The MBean interface for monitoring and managing the {@code ContextSelector}.
+ */
+public interface ContextSelectorAdminMBean {
+    /** Object name of this MBean. */
+    String NAME = "org.apache.logging.log4j2:type=ContextSelector";
+
+    /**
+     * Returns the name of the class implementing the {@code ContextSelector}
+     * interface.
+     * 
+     * @return the name of the {@code ContextSelector} implementation class.
+     */
+    String getImplementationClassName();
+}

Added: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerConfigAdmin.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerConfigAdmin.java?rev=1469973&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerConfigAdmin.java (added)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerConfigAdmin.java Fri Apr 19 17:59:11 2013
@@ -0,0 +1,106 @@
+/*
+ * 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.jmx;
+
+import java.util.List;
+
+import javax.management.ObjectName;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.config.AppenderRef;
+import org.apache.logging.log4j.core.config.LoggerConfig;
+
+/**
+ * Implementation of the {@code LoggerConfigAdminMBean} interface.
+ */
+public class LoggerConfigAdmin implements LoggerConfigAdminMBean {
+
+    private final String contextName;
+    private final LoggerConfig loggerConfig;
+    private final ObjectName objectName;
+
+    /**
+     * Constructs a new {@code LoggerConfigAdmin} with the specified contextName
+     * and logger config.
+     * 
+     * @param contextName used in the {@code ObjectName} for this mbean
+     * @param loggerConfig the instrumented object
+     */
+    public LoggerConfigAdmin(String contextName, LoggerConfig loggerConfig) {
+        // super(executor); // no notifications for now
+        this.contextName = Assert.isNotNull(contextName, "contextName");
+        this.loggerConfig = Assert.isNotNull(loggerConfig, "loggerConfig");
+        try {
+            String ctxName = Server.escape(this.contextName);
+            String configName = Server.escape(loggerConfig.getName());
+            String name = String.format(PATTERN, ctxName, configName);
+            objectName = new ObjectName(name);
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    /** @see LoggerConfigAdminMBean#PATTERN */
+    public ObjectName getObjectName() {
+        return objectName;
+    }
+
+    @Override
+    public String getName() {
+        return loggerConfig.getName();
+    }
+
+    @Override
+    public String getLevel() {
+        return loggerConfig.getLevel().name();
+    }
+
+    @Override
+    public void setLevel(String level) {
+        loggerConfig.setLevel(Level.valueOf(level));
+    }
+
+    @Override
+    public boolean isAdditive() {
+        return loggerConfig.isAdditive();
+    }
+
+    @Override
+    public void setAdditive(boolean additive) {
+        loggerConfig.setAdditive(additive);
+    }
+
+    @Override
+    public boolean isIncludeLocation() {
+        return loggerConfig.isIncludeLocation();
+    }
+
+    @Override
+    public String getFilter() {
+        return String.valueOf(loggerConfig.getFilter());
+    }
+
+    @Override
+    public String[] getAppenderRefs() {
+        List<AppenderRef> refs = loggerConfig.getAppenderRefs();
+        String[] result = new String[refs.size()];
+        for (int i = 0; i < result.length; i++) {
+            result[i] = refs.get(i).getRef();
+        }
+        return result;
+    }
+}

Added: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerConfigAdminMBean.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerConfigAdminMBean.java?rev=1469973&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerConfigAdminMBean.java (added)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerConfigAdminMBean.java Fri Apr 19 17:59:11 2013
@@ -0,0 +1,91 @@
+/*
+ * 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.jmx;
+
+/**
+ * The MBean interface for monitoring and managing a {@code LoggerConfig}.
+ */
+public interface LoggerConfigAdminMBean {
+    /** ObjectName pattern for LoggerConfigAdmin MBeans. */
+    String PATTERN = "org.apache.logging.log4j2:type=LoggerContext,ctx=%s,sub=LoggerConfig,name=%s";
+
+    /**
+     * Returns the name of the instrumented {@code LoggerConfig}.
+     * 
+     * @return the name of the LoggerConfig
+     */
+    String getName();
+
+    /**
+     * Returns the {@code LoggerConfig} level as a String.
+     * 
+     * @return the {@code LoggerConfig} level.
+     */
+    String getLevel();
+
+    /**
+     * Sets the {@code LoggerConfig} level to the specified value.
+     * 
+     * @param level the new {@code LoggerConfig} level.
+     * @throws IllegalArgumentException if the specified level is not one of
+     *             "OFF", "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE",
+     *             "ALL"
+     */
+    void setLevel(String level);
+
+    /**
+     * Returns whether the instrumented {@code LoggerConfig} is additive.
+     * 
+     * @return {@code true} if the LoggerConfig is additive, {@code false}
+     *         otherwise
+     */
+    boolean isAdditive();
+
+    /**
+     * Sets whether the instrumented {@code LoggerConfig} should be additive.
+     * 
+     * @param additive {@code true} if the instrumented LoggerConfig should be
+     *            additive, {@code false} otherwise
+     */
+    void setAdditive(boolean additive);
+
+    /**
+     * Returns whether the instrumented {@code LoggerConfig} is configured to
+     * include location.
+     * 
+     * @return whether location should be passed downstream
+     */
+    boolean isIncludeLocation();
+
+    /**
+     * Returns a string description of all filters configured for the
+     * instrumented {@code LoggerConfig}.
+     * 
+     * @return a string description of all configured filters for this
+     *         LoggerConfig
+     */
+    String getFilter();
+
+    /**
+     * Returns a String array with the appender refs configured for the
+     * instrumented {@code LoggerConfig}.
+     * 
+     * @return the appender refs for the instrumented {@code LoggerConfig}.
+     */
+    String[] getAppenderRefs();
+
+}

Added: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerContextAdmin.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerContextAdmin.java?rev=1469973&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerContextAdmin.java (added)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerContextAdmin.java Fri Apr 19 17:59:11 2013
@@ -0,0 +1,236 @@
+/*
+ * 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.jmx;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Map;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.management.MBeanNotificationInfo;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.ObjectName;
+
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.ConfigurationFactory;
+import org.apache.logging.log4j.core.config.ConfigurationFactory.ConfigurationSource;
+import org.apache.logging.log4j.status.StatusLogger;
+
+/**
+ * Implementation of the {@code LoggerContextAdminMBean} interface.
+ */
+public class LoggerContextAdmin extends NotificationBroadcasterSupport
+        implements LoggerContextAdminMBean, PropertyChangeListener {
+    private static final int PAGE = 4 * 1024;
+    private static final int TEXT_BUFFER = 64 * 1024;
+    private static final int BUFFER_SIZE = 2048;
+    private static final StatusLogger LOGGER = StatusLogger.getLogger();
+
+    private final AtomicLong sequenceNo = new AtomicLong();
+    private final ObjectName objectName;
+    private final LoggerContext loggerContext;
+    private String customConfigText;
+
+    /**
+     * Constructs a new {@code LoggerContextAdmin} with the {@code Executor} to
+     * be used for sending {@code Notification}s asynchronously to listeners.
+     * 
+     * @param executor
+     */
+    public LoggerContextAdmin(LoggerContext loggerContext, Executor executor) {
+        super(executor, createNotificationInfo());
+        this.loggerContext = Assert.isNotNull(loggerContext, "loggerContext");
+        try {
+            String ctxName = Server.escape(loggerContext.getName());
+            String name = String.format(PATTERN, ctxName);
+            objectName = new ObjectName(name);
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
+        }
+        loggerContext.addPropertyChangeListener(this);
+    }
+
+    private static MBeanNotificationInfo createNotificationInfo() {
+        String[] notifTypes = new String[] { NOTIF_TYPE_RECONFIGURED };
+        String name = Notification.class.getName();
+        String description = "Configuration reconfigured";
+        return new MBeanNotificationInfo(notifTypes, name, description);
+    }
+
+    @Override
+    public String getStatus() {
+        return loggerContext.getStatus().toString();
+    }
+
+    @Override
+    public String getName() {
+        return loggerContext.getName();
+    }
+
+    private Configuration getConfig() {
+        return loggerContext.getConfiguration();
+    }
+
+    @Override
+    public String getConfigLocationURI() {
+        if (loggerContext.getConfigLocation() != null) {
+            return String.valueOf(loggerContext.getConfigLocation());
+        }
+        if (getConfigName() != null) {
+            return String.valueOf(new File(getConfigName()).toURI());
+        }
+        return "";
+    }
+
+    @Override
+    public void setConfigLocationURI(String configLocation)
+            throws URISyntaxException, IOException {
+        LOGGER.debug("---------");
+        LOGGER.debug("Remote request to reconfigure using location "
+                + configLocation);
+        URI uri = new URI(configLocation);
+
+        // validate the location first: invalid location will result in
+        // default configuration being configured, try to avoid that...
+        uri.toURL().openStream().close();
+
+        loggerContext.setConfigLocation(uri);
+        LOGGER.debug("Completed remote request to reconfigure.");
+    }
+
+    @Override
+    public void propertyChange(PropertyChangeEvent evt) {
+        if (!LoggerContext.PROPERTY_CONFIG.equals(evt.getPropertyName())) {
+            return;
+        }
+        // erase custom text if new configuration was read from a location
+        if (loggerContext.getConfiguration().getName() != null) {
+            customConfigText = null;
+        }
+        Notification notif = new Notification(NOTIF_TYPE_RECONFIGURED,
+                getObjectName(), nextSeqNo(), now(), null);
+        sendNotification(notif);
+    }
+
+    @Override
+    public String getConfigText() throws IOException {
+        if (customConfigText != null) {
+            return customConfigText;
+        }
+        try {
+            return readContents(new URI(getConfigLocationURI()));
+        } catch (Exception ex) {
+            StringWriter sw = new StringWriter(BUFFER_SIZE);
+            ex.printStackTrace(new PrintWriter(sw));
+            return sw.toString();
+        }
+    }
+
+    @Override
+    public void setConfigText(String configText, String charsetName) {
+        String old = customConfigText;
+        customConfigText = Assert.isNotNull(configText, "configText");
+        LOGGER.debug("---------");
+        LOGGER.debug("Remote request to reconfigure from config text.");
+
+        try {
+            InputStream in = new ByteArrayInputStream(
+                    configText.getBytes(charsetName));
+            ConfigurationSource source = new ConfigurationSource(in);
+            Configuration updated = ConfigurationFactory.getInstance()
+                    .getConfiguration(source);
+            loggerContext.setConfiguration(updated);
+            LOGGER.debug("Completed remote request to reconfigure from config text.");
+        } catch (Exception ex) {
+            customConfigText = old;
+            String msg = "Could not reconfigure from config text";
+            LOGGER.error(msg, ex);
+            throw new IllegalArgumentException(msg, ex);
+        }
+    }
+
+    private String readContents(URI uri) throws IOException {
+        InputStream in = null;
+        try {
+            in = uri.toURL().openStream();
+            Reader reader = new InputStreamReader(in);
+            StringBuilder result = new StringBuilder(TEXT_BUFFER);
+            char[] buff = new char[PAGE];
+            int count = -1;
+            while ((count = reader.read(buff)) >= 0) {
+                result.append(buff, 0, count);
+            }
+            return result.toString();
+        } finally {
+            try {
+                in.close();
+            } catch (Exception ignored) {
+            }
+        }
+    }
+
+    @Override
+    public String getConfigName() {
+        return getConfig().getName();
+    }
+
+    @Override
+    public String getConfigClassName() {
+        return getConfig().getClass().getName();
+    }
+
+    @Override
+    public String getConfigFilter() {
+        return String.valueOf(getConfig().getFilter());
+    }
+
+    @Override
+    public String getConfigMonitorClassName() {
+        return getConfig().getConfigurationMonitor().getClass().getName();
+    }
+
+    @Override
+    public Map<String, String> getConfigProperties() {
+        return getConfig().getProperties();
+    }
+
+    /** @see LoggerContextAdminMBean#PATTERN */
+    public ObjectName getObjectName() {
+        return objectName;
+    }
+
+    private long nextSeqNo() {
+        return sequenceNo.getAndIncrement();
+    }
+
+    private long now() {
+        return System.currentTimeMillis();
+    }
+}
\ No newline at end of file

Added: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerContextAdminMBean.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerContextAdminMBean.java?rev=1469973&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerContextAdminMBean.java (added)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/jmx/LoggerContextAdminMBean.java Fri Apr 19 17:59:11 2013
@@ -0,0 +1,133 @@
+/*
+ * 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.jmx;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Map;
+
+/**
+ * The MBean interface for monitoring and managing a {@code LoggerContext}.
+ */
+public interface LoggerContextAdminMBean {
+    /** ObjectName pattern for LoggerContextAdmin MBeans. */
+    String PATTERN = "org.apache.logging.log4j2:type=LoggerContext,ctx=%s";
+
+    /**
+     * Notification that the {@code Configuration} of the instrumented
+     * {@code LoggerContext} has been reconfigured. Notifications of this type
+     * do not carry a message or user data.
+     */
+    String NOTIF_TYPE_RECONFIGURED = "com.apache.logging.log4j.core.jmx.config.reconfigured";
+
+    /**
+     * Returns the status of the instrumented {@code LoggerContext}.
+     * 
+     * @return the LoggerContext status.
+     */
+    String getStatus();
+
+    /**
+     * Returns the name of the instrumented {@code LoggerContext}.
+     * 
+     * @return the name of the instrumented {@code LoggerContext}.
+     */
+    String getName();
+
+    /**
+     * Returns the configuration location URI as a String.
+     * 
+     * @return the configuration location
+     */
+    String getConfigLocationURI();
+
+    /**
+     * Sets the configuration location to the specified URI. This will cause the
+     * instrumented {@code LoggerContext} to reconfigure.
+     * 
+     * @param configLocationURI location of the configuration file in
+     *            {@link URI} format.
+     * @throws URISyntaxException if the format of the specified
+     *             configLocationURI is incorrect
+     * @throws IOException if an error occurred reading the specified location
+     */
+    void setConfigLocationURI(String configLocation) throws URISyntaxException,
+            IOException;
+
+    /**
+     * Returns the configuration text, which may be the contents of the
+     * configuration file or the text that was last set with a call to
+     * {@code setConfigText}.
+     * 
+     * @return the configuration text
+     */
+    String getConfigText() throws IOException;
+
+    /**
+     * Sets the configuration text. This does not replace the contents of the
+     * configuration file, but <em>does</em> cause the instrumented
+     * {@code LoggerContext} to be reconfigured with the specified text.
+     * 
+     * @param configText the configuration text in XML or JSON format
+     * @param charsetName name of the {@code Charset} used to convert the
+     *            specified configText to bytes
+     * @throws IllegalArgumentException if a problem occurs configuring from the
+     *             specified text
+     */
+    void setConfigText(String configText, String charsetName);
+
+    /**
+     * Returns the name of the Configuration of the instrumented LoggerContext.
+     * 
+     * @return the Configuration name
+     */
+    String getConfigName();
+
+    /**
+     * Returns the class name of the {@code Configuration} of the instrumented
+     * LoggerContext.
+     * 
+     * @return the class name of the {@code Configuration}.
+     */
+    String getConfigClassName();
+
+    /**
+     * Returns a string description of all Filters configured in the
+     * {@code Configuration} of the instrumented LoggerContext.
+     * 
+     * @return a string description of all Filters configured
+     */
+    String getConfigFilter();
+
+    /**
+     * Returns the class name of the object that is monitoring the configuration
+     * file for modifications.
+     * 
+     * @return the class name of the object that is monitoring the configuration
+     *         file for modifications
+     */
+    String getConfigMonitorClassName();
+
+    /**
+     * Returns a map with configured properties.
+     * 
+     * @return a map with configured properties.
+     */
+    Map<String, String> getConfigProperties();
+
+}



Mime
View raw message