Index: src/main/java/org/apache/log4j/jmx/AbstractModelMBean.java
===================================================================
--- src/main/java/org/apache/log4j/jmx/AbstractModelMBean.java (revision 0)
+++ src/main/java/org/apache/log4j/jmx/AbstractModelMBean.java (revision 0)
@@ -0,0 +1,168 @@
+package org.apache.log4j.jmx;
+
+import javax.management.Descriptor;
+import javax.management.MBeanException;
+import javax.management.MBeanParameterInfo;
+import javax.management.RuntimeOperationsException;
+import javax.management.modelmbean.DescriptorSupport;
+import javax.management.modelmbean.ModelMBeanAttributeInfo;
+import javax.management.modelmbean.ModelMBeanConstructorInfo;
+import javax.management.modelmbean.ModelMBeanInfo;
+import javax.management.modelmbean.ModelMBeanInfoSupport;
+import javax.management.modelmbean.ModelMBeanNotificationInfo;
+import javax.management.modelmbean.ModelMBeanOperationInfo;
+import javax.management.modelmbean.RequiredModelMBean;
+
+/**
+ * Base class for Model MBeans.
+ * To provide a Mode MBean simply extend this class and override getModelMbeanInfo using
+ * createModelMBeanInfo.
+ * For registering attributes, methods, constructors, ... there exist createModelMBean*-methods.
+ * @author Stefan Fleiter
+ */
+public abstract class AbstractModelMBean extends RequiredModelMBean {
+
+ private final Object delegate;
+
+ /**
+ * Constructor to use an own instance of a Delegate to represent per JMX.
+ * @param delegate Instance of LoggerManager to represent as MBean
+ * @throws MBeanException user Exception of MBean
+ * @throws RuntimeOperationsException Runtime Exceptions in the MBeanServer
+ */
+ public AbstractModelMBean(Object delegate) throws MBeanException, RuntimeOperationsException {
+ this.delegate = delegate;
+ setModelMBeanInfo(getModelMBeanInfo());
+ try {
+ setManagedResource(delegate, "ObjectReference");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Object getDelegate() {
+ return delegate;
+ }
+
+ protected abstract ModelMBeanInfo getModelMBeanInfo() throws RuntimeOperationsException, MBeanException;
+
+ /**
+ * Creates the ModelMBeanNotificationInfos for this ModelMBean, extracted for easy extendability.
+ * @return Array of ModelMBeanNotificationInfo describing the methods available per JMX
+ */
+ protected ModelMBeanNotificationInfo[] createModelMBeanNotificationInfos() {
+ return new ModelMBeanNotificationInfo[] {};
+ }
+
+ /**
+ * Creates the ModelMBeanConstructorInfos for this ModelMBean, extracted for easy extendability.
+ * @return Array of ModelMBeanConstructorInfo describing the methods available per JMX
+ */
+ protected ModelMBeanConstructorInfo[] createModelMBeanConstructorInfos() {
+ return new ModelMBeanConstructorInfo[] {};
+ }
+
+ /**
+ * Creates the ModelMBeanOperationInfos for this ModelMBean, extracted for easy extendability.
+ * @return Array of ModelMBeanOperationInfo describing the methods available per JMX
+ */
+ protected ModelMBeanOperationInfo[] createModelMBeanOperationInfos() {
+ return new ModelMBeanOperationInfo[] {};
+ }
+
+ /**
+ * Creates the ModelMBeanAttributeInfos for this ModelMBean, extracted for easy extendability.
+ * @return Array of ModelMBeanAttributeInfo describing the methods available per JMX
+ */
+ protected ModelMBeanAttributeInfo[] createModelMBeanAttributeInfos() {
+ return new ModelMBeanAttributeInfo[] {};
+ }
+
+ /**
+ * Creates the ModelMBeanInfo for this ModelMBean.
+ * @param displayName Name for this mbean to display in manager applications
+ * @param description Description what this MBean does
+ * @param clazz Class implementing the functionality and this MBean delegates to
+ * @param mbeanName Name of
+ * @return Array of ModelMBeanConstructorInfo describing the methods available per JMX
+ */
+ protected ModelMBeanInfo createModelMBeanInfo(String displayName, String description,
+ Class clazz, String mbeanName) {
+ ModelMBeanInfo result;
+ Descriptor managerDescriptor = new DescriptorSupport(new String[] {
+ "name=" + mbeanName,
+ "descriptorType=mbean",
+ "displayName=" + displayName,
+ "type=" + clazz.getName(),
+ });
+
+ result = new ModelMBeanInfoSupport(
+ clazz.getName(),
+ description,
+ createModelMBeanAttributeInfos(),
+ createModelMBeanConstructorInfos(),
+ createModelMBeanOperationInfos(),
+ createModelMBeanNotificationInfos(),
+ managerDescriptor
+ );
+ return result;
+ }
+
+ /**
+ * Helper Method for registering operations.
+ * @param name Name of operation
+ * @param description describes what the operation does
+ * @param parameters parameters of the operation
+ * @param returnType class which is returned by the to be registered method
+ * @param operationInfo INFO if non-modifying and ACTION if modifying status
+ * @return ModelMBeanOperationInfo for the described method
+ */
+ protected ModelMBeanOperationInfo createOperationInfo(String name, String description,
+ MBeanParameterInfo[] parameters, Class returnType, int operationInfo) {
+ return new ModelMBeanOperationInfo(
+ name,
+ description,
+ parameters,
+ returnType.getName(),
+ operationInfo,
+ new DescriptorSupport(new String[] {
+ "name=" + name,
+ "displayName=" + description,
+ "descriptorType=operation",
+ "class=" + getDelegate().getClass().getName(),
+ "role=operation",
+ })
+ );
+ }
+
+ /**
+ * Helper Method for registering attributes.
+ * @param name Name of attribute
+ * @param description describes what the attribute is for
+ * @param type type of attribute (return value of get and parameter of set Operation)
+ * @param readable true, if attribute can be read
+ * @param writable true, if attribute can be set
+ * @param is true if the attribute has an "is" getter, false otherwise
+ * @param getMethod name of getter Method
+ * @param setMethod name of setter Method
+ * @return ModelMBeanAttributeInfo for the described method
+ */
+ protected ModelMBeanAttributeInfo createAttributeInfo(String name, String description,
+ Class type, boolean readable, boolean writable, boolean is, String getMethod,
+ String setMethod) {
+ return new ModelMBeanAttributeInfo(
+ name,
+ type.getName(),
+ description,
+ readable, writable, is,
+ new DescriptorSupport(new String[] {
+ "name=" + name,
+ "descriptorType=attribute",
+ "displayName=" + description,
+ "getMethod=" + getMethod,
+ "setMethod=" + setMethod,
+ })
+ );
+ }
+
+}
Index: src/main/java/org/apache/log4j/jmx/RollbackableLoggerManager.java
===================================================================
--- src/main/java/org/apache/log4j/jmx/RollbackableLoggerManager.java (revision 0)
+++ src/main/java/org/apache/log4j/jmx/RollbackableLoggerManager.java (revision 0)
@@ -0,0 +1,135 @@
+package org.apache.log4j.jmx;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Stack;
+import java.util.Map.Entry;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+
+/**
+ * LoggerManager implementation with additional rollback support to be able to undo the changes
+ * done by this class.
+ * @see LoggerManager
+ * @author Stefan Fleiter
+ */
+public class RollbackableLoggerManager extends LoggerManager {
+
+ /**
+ * Thread safety guaranteed by locking on this (instance of LoggerManager) on every access.
+ * Invariant guarded is that savedLoggerConfiguration and loggerConfigurationUndoStack
+ * contain consistent information.
+ */
+ private final Map initialLoggerConfigurations = new HashMap();
+
+ /**
+ * Thread safety guaranteed by locking on this (instance of LoggerManager) on every access.
+ * Invariant guarded is that savedLoggerConfiguration and loggerConfigurationUndoStack
+ * contain consistent information.
+ */
+ private final Stack loggerConfigurationUndoStack = new Stack();
+
+ /**
+ * Holder for a Logger and a Level combination.
+ * This object ist immutable.
+ * @author Stefan Fleiter
+ */
+ class LoggerConfiguration {
+ private final Logger logger;
+ private final Level formerLevel;
+
+ /**
+ * Constructor
+ * @param logger a logger
+ * @param formerLevel level of the logger
+ */
+ LoggerConfiguration(Logger logger, Level formerLevel) {
+ super();
+ this.logger = logger;
+ this.formerLevel = formerLevel;
+ }
+
+ public Logger getLogger() {
+ return logger;
+ }
+ public Level getFormerLevel() {
+ return formerLevel;
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ * Saves all needed data for supporting rollback.
+ */
+ protected boolean doSetLogLogLevel(Logger logger, String level) {
+ Level originalLevel = logger.getLevel();
+ boolean modified = super.doSetLogLogLevel(logger, level);
+ if (modified) {
+ synchronized (this) {
+ if (!initialLoggerConfigurations.containsKey(logger)) {
+ initialLoggerConfigurations.put(logger, originalLevel);
+ }
+ loggerConfigurationUndoStack.push(new LoggerConfiguration(logger, originalLevel));
+ }
+ }
+ return modified;
+ }
+
+ /**
+ * Returns count of modifications to logging which can be undone.
+ * This count decreases after calls to the rollback methods.
+ * @return count of modifications which can be undone
+ */
+ public int getLogConfigurationModificationCount() {
+ synchronized (this) {
+ return loggerConfigurationUndoStack.size();
+ }
+ }
+
+ /**
+ * Rolls back all modifications which where done to the log configuration by this instance.
+ */
+ public void rollbackLogConfiguration() {
+ synchronized (this) {
+ for (Iterator it = initialLoggerConfigurations.entrySet().iterator(); it.hasNext(); ) {
+ Map.Entry entry = (Entry) it.next();
+ Logger logger = (Logger) entry.getKey();
+ Level initialLevel = (Level) entry.getValue();
+ logger.setLevel(initialLevel);
+ }
+ destroy();
+ }
+ }
+
+ /**
+ * Rolls back last modification which was done to the log configuration by this instance.
+ * @return true, wenn undo durchgeführt wurde, false wenn es keine Modifikationen
+ * zum undo mehr gab
+ */
+ public void rollbackLastLogConfigurationModification() {
+ synchronized (this) {
+ if (!loggerConfigurationUndoStack.empty()) {
+ LoggerConfiguration loggerState = (LoggerConfiguration) loggerConfigurationUndoStack.pop();
+ Logger logger = loggerState.getLogger();
+ Level originalLevel = loggerState.getFormerLevel();
+ logger.setLevel(originalLevel);
+ }
+ }
+ }
+
+ /**
+ * Shutdown hook which clears all references, but does not call resetLogConfiguration
+ * @see #resetLogConfiguration()
+ */
+ public void destroy() {
+ super.destroy();
+ synchronized (this) {
+ initialLoggerConfigurations.clear();
+ loggerConfigurationUndoStack.clear();
+ }
+ }
+
+}
Index: src/main/java/org/apache/log4j/jmx/LoggerManager.java
===================================================================
--- src/main/java/org/apache/log4j/jmx/LoggerManager.java (revision 0)
+++ src/main/java/org/apache/log4j/jmx/LoggerManager.java (revision 0)
@@ -0,0 +1,183 @@
+package org.apache.log4j.jmx;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.spi.LoggerRepository;
+
+/**
+ * Helper for reading and modifying the logger configuration of a running log4j instance.
+ * This class is thread safe.
+ * @author Stefan Fleiter
+ */
+public class LoggerManager {
+
+ /**
+ * Returns a Level instance matching the given string representation.
+ * @param levelName Name of the level of INHERITED to inherit level from the next ancestor.
+ * @return Level matching levelName, null for INHERITED
+ * @throws IllegalArgumentException levelName does not represent a known level
+ */
+ Level getLevelByName(String levelName) throws IllegalArgumentException {
+ Level level = Level.toLevel(levelName, null);
+ if (null == level && null != levelName) {
+ String lowerLevelName = levelName.toLowerCase();
+ if (!"inherit".equals(lowerLevelName) &&
+ !"inherited".equals(lowerLevelName) &&
+ !"null".equals(lowerLevelName)) {
+ throw new IllegalArgumentException('"' + levelName + "\" is not a valid level");
+ }
+ }
+ return level;
+ }
+
+ /**
+ * Returns the string representation of the given Level.
+ * @param level Level instance
+ * @return Name of level or null if level is null
+ */
+ String getLogLevelString(Level level) {
+ return null == level ? null : level.toString();
+ }
+
+
+ /**
+ * Returns the explicit set level of a specified logger.
+ * @param loggerName Name of the logger
+ * @return Level of the logger
+ */
+ public String getLogLevel(String loggerName) {
+ return getLogLevelString(LogManager.getLogger(loggerName).getLevel());
+ }
+
+ /**
+ * Returns the effective level (the level set on this logger or if not set explicitly the
+ * level of the next ancestor) of the specified logger.
+ * @param loggerName Name of logger either existing or to be created
+ * @return Effective level of the logger
+ */
+ public String getEffectiveLogLevel(String loggerName) {
+ return getLogLevelString(LogManager.getLogger(loggerName).getEffectiveLevel());
+ }
+
+ /**
+ * Compares two levels and returns whether they are equal.
+ * @param first first level
+ * @param second second level
+ * @return true if levels are equal
+ */
+ boolean levelEquals(Level first, Level second) {
+ if (null == first) {
+ return null == second;
+ } else {
+ return first.equals(second);
+ }
+ }
+
+ /**
+ * Sets the level of the specified logger.
+ * @param loggerName Name of logger either existing or to be created
+ * @param level New level
+ * @throws IllegalArgumentException levelName does not represent a known level
+ */
+ public void setLogLevel(String loggerName, String level) throws IllegalArgumentException {
+ Logger logger = LogManager.getLogger(loggerName);
+ doSetLogLogLevel(logger, level);
+ }
+
+ /**
+ * Returns the level of the root logger.
+ * @return Level of the logger
+ */
+ public String getRootLogLevel() {
+ return getLogLevelString(LogManager.getRootLogger().getLevel());
+ }
+
+ /**
+ * Sets the level of the specified logger.
+ * @param level New level
+ * @throws IllegalArgumentException levelName does not represent a known level
+ */
+ public void setRootLogLevel(String level) throws IllegalArgumentException {
+ Logger logger = LogManager.getRootLogger();
+ doSetLogLogLevel(logger, level);
+ }
+
+ /**
+ * Sets the level of the specified logger.
+ * Can be overriden to do something additional when modifying loggers.
+ * @param logger Log4j Logger Instance
+ * @param level New level as string
+ * @return true, if level has changed, false if level is same as before
+ */
+ protected boolean doSetLogLogLevel(Logger logger, String level) {
+ Level originalLevel = logger.getLevel();
+ Level newLevel = getLevelByName(level);
+ boolean modified = false;
+ if (!levelEquals(newLevel, originalLevel)) {
+ modified = true;
+ logger.setLevel(newLevel);
+ }
+ return modified;
+ }
+
+ /**
+ * Shutdown hook.
+ */
+ public void destroy() {
+ // nothing to do
+ }
+
+ /**
+ * Returns a map of all explicitly configured loggers with the level as value.
+ * @return map of logger names and level names
+ */
+ public Map getLogConfiguration() {
+ Map result = new HashMap();
+ List loggers = getConfiguredLoggersInternal();
+ for (Iterator it = loggers.iterator(); it.hasNext(); ) {
+ Logger logger = (Logger) it.next();
+ result.put(logger.getName(), logger.getEffectiveLevel().toString());
+ }
+ return result;
+ }
+
+ /**
+ * @return all explicitly configured loggers
+ */
+ List getConfiguredLoggersInternal() {
+ List result = new ArrayList();
+ LoggerRepository r = LogManager.getLoggerRepository();
+ Enumeration loggers = r.getCurrentLoggers();
+ while (loggers.hasMoreElements()) {
+ Logger logger = (Logger) loggers.nextElement();
+ if (null != logger.getLevel()) {
+ result.add(logger);
+ }
+ }
+ result.add(LogManager.getRootLogger());
+ return result;
+ }
+
+ /**
+ * Returns the names of all loggers with an explicit set level
+ * (Logger{@link #getLogLevel(String)} is not null).
+ * @return array of names of all explicitly configured loggers
+ */
+ public String[] getConfiguredLoggers() {
+ List configuredLoggers = getConfiguredLoggersInternal();
+ String[] result = new String[configuredLoggers.size()];
+ for (int i = 0; i < configuredLoggers.size(); i++) {
+ result[i] = ((Logger) configuredLoggers.get(i)).getName();
+ }
+ return result;
+ }
+
+}
Index: src/main/java/org/apache/log4j/jmx/RollbackableLoggerManagerModelMBean.java
===================================================================
--- src/main/java/org/apache/log4j/jmx/RollbackableLoggerManagerModelMBean.java (revision 0)
+++ src/main/java/org/apache/log4j/jmx/RollbackableLoggerManagerModelMBean.java (revision 0)
@@ -0,0 +1,113 @@
+package org.apache.log4j.jmx;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.management.MBeanException;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.RuntimeOperationsException;
+import javax.management.modelmbean.ModelMBeanAttributeInfo;
+import javax.management.modelmbean.ModelMBeanOperationInfo;
+
+/**
+ * Model MBean which makes the methods of RollbackableLoggerManager
+ * available per JMX.
+ * @author Stefan Fleiter
+ * @see RollbackableLoggerManager
+ */
+public class RollbackableLoggerManagerModelMBean extends LoggerManagerModelMBean {
+
+ /**
+ * Constructor.
+ * @throws MBeanException user Exception of MBean
+ * @throws RuntimeOperationsException Runtime Exceptions in the MBeanServer
+ */
+ public RollbackableLoggerManagerModelMBean() throws MBeanException, RuntimeOperationsException {
+ this(new RollbackableLoggerManager());
+ }
+
+ /**
+ * Constructor to use an own instance of LoggerManager to represent per JMX.
+ * @param loggerManager Instance of RollbackableLoggerManager to represent as MBean
+ * @throws MBeanException user Exception of MBean
+ * @throws RuntimeOperationsException Runtime Exceptions in the MBeanServer
+ */
+ public RollbackableLoggerManagerModelMBean(RollbackableLoggerManager loggerManager) throws MBeanException, RuntimeOperationsException {
+ super(loggerManager);
+ }
+
+ /**
+ * Method to create a single list of the content of two arrays.
+ * @param arrayA first Array
+ * @param arrayB second array
+ * @return List with content of both input arrays
+ */
+ private List arraysToList(Object[] arrayA, Object[] arrayB) {
+ List result = new ArrayList(arrayA.length + arrayB.length);
+ for (int i = 0; i < arrayA.length; i++) {
+ result.add(arrayA[i]);
+ }
+ for (int i = 0; i < arrayB.length; i++) {
+ result.add(arrayB[i]);
+ }
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected ModelMBeanOperationInfo[] createModelMBeanOperationInfos() {
+ ModelMBeanOperationInfo[] modelMBeanOperationInfos = super.createModelMBeanOperationInfos();
+
+ ModelMBeanOperationInfo[] additionalOperations = new ModelMBeanOperationInfo[] {
+ createOperationInfo(
+ "rollbackLogConfiguration",
+ "Resets all loggers to its' states before calling actions in this MBean",
+ new MBeanParameterInfo[0],
+ void.class,
+ MBeanOperationInfo.ACTION
+ ),
+ createOperationInfo(
+ "rollbackLastLogConfigurationModification",
+ "Resets last modification to log configuration",
+ new MBeanParameterInfo[0],
+ void.class,
+ MBeanOperationInfo.ACTION
+ ),
+ createOperationInfo(
+ "getLogConfigurationModificationCount",
+ "Modification count auf log configuration, equals number of possible undo steps",
+ new MBeanParameterInfo[0],
+ int.class,
+ MBeanOperationInfo.INFO
+ ),
+ };
+
+ List result = arraysToList(modelMBeanOperationInfos, additionalOperations);
+ return (ModelMBeanOperationInfo[]) result.toArray(new ModelMBeanOperationInfo[result.size()]);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected ModelMBeanAttributeInfo[] createModelMBeanAttributeInfos() {
+ ModelMBeanAttributeInfo[] modelMBeanAttributeInfos = super.createModelMBeanAttributeInfos();
+
+ ModelMBeanAttributeInfo[] additionalAttributes = new ModelMBeanAttributeInfo[] {
+ createAttributeInfo(
+ "logConfigurationModificationCount",
+ "Modification count auf log configuration, equals number of possible undo steps",
+ int.class,
+ true,
+ false,
+ false,
+ "getLogConfigurationModificationCount",
+ null
+ ),
+ };
+ List result = arraysToList(modelMBeanAttributeInfos, additionalAttributes);
+ return (ModelMBeanAttributeInfo[]) result.toArray(new ModelMBeanAttributeInfo[result.size()]);
+ }
+
+}
Index: src/main/java/org/apache/log4j/jmx/LoggerManagerModelMBean.java
===================================================================
--- src/main/java/org/apache/log4j/jmx/LoggerManagerModelMBean.java (revision 0)
+++ src/main/java/org/apache/log4j/jmx/LoggerManagerModelMBean.java (revision 0)
@@ -0,0 +1,210 @@
+package org.apache.log4j.jmx;
+
+import java.util.Map;
+
+import javax.management.MBeanException;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.RuntimeOperationsException;
+import javax.management.modelmbean.ModelMBeanAttributeInfo;
+import javax.management.modelmbean.ModelMBeanInfo;
+import javax.management.modelmbean.ModelMBeanOperationInfo;
+
+/**
+ * Model MBean which makes the methods of LoggerManager
available per JMX.
+ * @author Stefan Fleiter
+ * @see LoggerManager
+ */
+public class LoggerManagerModelMBean extends AbstractModelMBean {
+
+ /**
+ * Constructor.
+ * @throws MBeanException user Exception of MBean
+ * @throws RuntimeOperationsException Runtime Exceptions in the MBeanServer
+ */
+ public LoggerManagerModelMBean() throws MBeanException, RuntimeOperationsException {
+ this(new LoggerManager());
+ }
+
+ /**
+ * Constructor to use an own instance of LoggerManager to represent per JMX.
+ * @param loggerManager Instance of LoggerManager to represent as MBean
+ * @throws MBeanException user Exception of MBean
+ * @throws RuntimeOperationsException Runtime Exceptions in the MBeanServer
+ */
+ public LoggerManagerModelMBean(LoggerManager loggerManager) throws MBeanException, RuntimeOperationsException {
+ super(loggerManager);
+ setModelMBeanInfo(getModelMBeanInfo());
+ try {
+ setManagedResource(loggerManager, "ObjectReference");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected ModelMBeanOperationInfo[] createModelMBeanOperationInfos() {
+ ModelMBeanOperationInfo getLogConfiguration = createOperationInfo(
+ "getLogConfiguration",
+ "Return the levels of all explicitly configured loggers",
+ new MBeanParameterInfo[0],
+ Map.class,
+ ModelMBeanOperationInfo.INFO
+ );
+ ModelMBeanOperationInfo getConfiguredLoggers = createOperationInfo(
+ "getConfiguredLoggers",
+ "Return the names of the explicitly configured loggers",
+ new MBeanParameterInfo[0],
+ String[].class,
+ ModelMBeanOperationInfo.INFO
+ );
+
+
+ ModelMBeanOperationInfo getRootLogLevel = createOperationInfo(
+ "getRootLogLevel",
+ "Return the level of the root logger",
+ new MBeanParameterInfo[0],
+ String.class,
+ MBeanOperationInfo.INFO
+ );
+ ModelMBeanOperationInfo setRootLogLevel = createOperationInfo(
+ "setRootLogLevel",
+ "Set the level of the root logger",
+ new MBeanParameterInfo[] {
+ new MBeanParameterInfo(
+ "level",
+ String.class.getName(),
+ "New level of root logger (INHERITED to inherit level from next ancestor)"
+ ),
+
+ },
+ void.class,
+ ModelMBeanOperationInfo.ACTION
+ );
+
+ ModelMBeanOperationInfo getLogLevel = createOperationInfo(
+ "getLogLevel",
+ "Return the level explicitly set at the specified logger, null if this logger INHERITS its level",
+ new MBeanParameterInfo[] {
+ new MBeanParameterInfo(
+ "logger",
+ String.class.getName(),
+ "Name of logger to query level"
+ ),
+ },
+ String.class,
+ MBeanOperationInfo.INFO
+ );
+ ModelMBeanOperationInfo getEffectiveLogLevel = createOperationInfo(
+ "getEffectiveLogLevel",
+ "Return the effective level of the specified logger " +
+ "(the explicitly specified level or the level of the next ancestor)",
+ new MBeanParameterInfo[] {
+ new MBeanParameterInfo(
+ "logger",
+ String.class.getName(),
+ "Name of logger to query level"
+ ),
+ },
+ String.class,
+ MBeanOperationInfo.INFO
+ );
+ ModelMBeanOperationInfo setLogLevel = createOperationInfo(
+ "setLogLevel",
+ "Set the level of the specified logger",
+ new MBeanParameterInfo[] {
+ new MBeanParameterInfo(
+ "logger",
+ String.class.getName(),
+ "name of logger to modify level"
+
+ ),
+ new MBeanParameterInfo(
+ "level",
+ String.class.getName(),
+ "new level of specified logger (INHERITED to inherit level from next ancestor)"
+ ),
+ },
+ void.class,
+ MBeanOperationInfo.ACTION
+ );
+
+ return new ModelMBeanOperationInfo[] {
+ getLogConfiguration, getConfiguredLoggers,
+ getRootLogLevel, setRootLogLevel,
+ getLogLevel, getEffectiveLogLevel, setLogLevel,
+ };
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected ModelMBeanAttributeInfo[] createModelMBeanAttributeInfos() {
+ ModelMBeanAttributeInfo rootLoggerAttribute = createAttributeInfo(
+ "rootLogger",
+ "Level of root logger",
+ String.class,
+ true,
+ true,
+ false,
+ "getRootLogLevel",
+ "setRootLogLevel"
+ );
+
+ ModelMBeanAttributeInfo configuredLoggersAttribute = createAttributeInfo(
+ "configuredLoggers",
+ "Names of all loggers with explicitly set log levels",
+ String[].class,
+ true,
+ false,
+ false,
+ "getConfiguredLoggers",
+ null
+ );
+
+ ModelMBeanAttributeInfo logConfigurationAttribute = createAttributeInfo(
+ "logConfiguration",
+ "Name of all explicitly configured loggers with their log level",
+ Map.class,
+ true,
+ false,
+ false,
+ "getLogConfiguration",
+ null
+ );
+
+ return new ModelMBeanAttributeInfo[] {
+ rootLoggerAttribute,
+ configuredLoggersAttribute,
+ logConfigurationAttribute,
+ };
+ }
+
+ /**
+ * Constructs the ModelMBeanInfo for this Model MBean.
+ * @return ModelMBeanInfo instance
+ * @throws MBeanException user Exception of MBean
+ * @throws RuntimeOperationsException Runtime Exceptions in the MBeanServer
+ */
+ protected ModelMBeanInfo getModelMBeanInfo() throws RuntimeOperationsException, MBeanException {
+ Class clazz = getDelegate().getClass();
+ String displayName = "Log4jManager";
+ String description = "Model MBean for Manager Logger Configuration of Log4j";
+ String mbeanName = "log4j:manager";
+ return createModelMBeanInfo(displayName, description, clazz, mbeanName);
+ }
+
+ /**
+ * Calls LoggerManager#destroy()
.
+ * @see LoggerManager#destroy()
+ * {@inheritDoc}}
+ */
+ public void postDeregister() {
+ ((LoggerManager) getDelegate()).destroy();
+ super.postDeregister();
+ }
+
+
+}