如何将log4j1与JMX相关的记录器代码迁移到log4j2?

时间:2018-12-10 10:28:04

标签: log4j log4j2 jmx mbeans

对于当前正在使用log4j1的Web应用程序,我具有以下Mbean注册侦听器类。

 package myApp.MyComp.jmx;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.log4j.Logger;

/**
 * MBeanRegistrationListener registers MBeans to configure all loggers of the webapp.
 * 
 */
public class MBeanRegistrationListener implements ServletContextListener {

  /** The Constant LOG. */
  private static final Logger LOG = Logger.getLogger(MBeanRegistrationListener.class);

  /** The m beans. */
  private final List<MBeanSupport> mBeans = new ArrayList<MBeanSupport>();

  /* (non-Javadoc)
   * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
   */
  @SuppressWarnings("unused")
  @Override
  public void contextDestroyed(final ServletContextEvent sce) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Unregistering MBeans.");
    }
    for (final MBeanSupport mB : mBeans) {
      mB.unregisterMBeans();
    }
  }

  /* (non-Javadoc)
   * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
   */
  @Override
  public void contextInitialized(final ServletContextEvent sce) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Registering my app MBeans.");
    }
    final String webappName = sce.getServletContext().getContextPath();

    mBeans.add(new LoggerManager(webappName));
    mBeans.add(new MyApp(webappName));
    mBeans.add(new Status(webappName));

    for (final MBeanSupport mB : mBeans) {
      mB.registerMBeans();
    }
  }
}

我还有以下LogLogManager类,它为记录器层次结构创建JMX包装器。

package myApp.MyComp.jmx;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;

import javax.management.JMException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.jmx.HierarchyDynamicMBean;
import org.apache.log4j.spi.LoggerRepository;

/**
 * The Class LoggerManager creates JMX wrappers for the logger hierarchy.
 */
@SuppressWarnings({"PMD.MoreThanOneLogger"})
public class LoggerManager extends MBeanSupport implements LoggerManagerMXBean {

  /** The Constant LOG4J_PATH. */
  private static final String LOG4J_PATH = "logger";

  /** The Constant LOG4J_DOMAIN. */
  public static final String LOG4J_DOMAIN = "log4j";

  /** The Constant LOG. */
  private static final Logger LOG = Logger.getLogger(LoggerManager.class);

  /** The webapp. */
  private final String webapp;

  /** The hierarchy dynamic m bean. */
  private HierarchyDynamicMBean hierarchyDynamicMBean;

  /** The Constant LOG4J_QUERYNAME. */
  public static final String LOG4J_QUERYNAME = LOG4J_DOMAIN + ":*";

  /**
   * Instantiates a new logger manager.
   * 
   * @param webappName
   *          the webapp name
   */
  public LoggerManager(final String webappName) {
    super(createObjectName(webappName));
    this.webapp = webappName;
  }

  /**
   * Creates the object name.
   * 
   * @param webapp
   *          the webapp
   * @return the object name
   */
  private static ObjectName createObjectName(final String webapp) {
    final Hashtable<String, String> nameParameters = new Hashtable<String, String>();
    nameParameters.put("portal", webapp);
    nameParameters.put("type", "logging");
    nameParameters.put("name", "loggerManager");

    ObjectName objectName = null;
    try {
      objectName = new ObjectName("mycomp.myapp.jmx", nameParameters);
    }
    catch (final MalformedObjectNameException e) {
    }
    catch (final NullPointerException e) {
    }
    return objectName;
  }

  /**
   * Creates the root logger object name.
   * 
   * @param webapp
   *          the webapp
   * @return the object name
   */
  private static ObjectName createRootLoggerObjectName(final String webapp) {
    final Hashtable<String, String> nameParameters = new Hashtable<String, String>();
    nameParameters.put("portal", webapp);
    nameParameters.put("type", "logging");
    nameParameters.put("name", "rootLogger");

    ObjectName objectName = null;
    try {
      objectName = new ObjectName("mycomp.myapp.jmx", nameParameters);
    }
    catch (final MalformedObjectNameException e) {
    }
    catch (final NullPointerException e) {
    }
    return objectName;
  }

  /*
   * (non-Javadoc)
   * @see mycomp.myapp.jmx.LoggerManagerMXBean#getActiveLoggerNames()
   */
  @Override
  public String[] getActiveLoggerNames() {
    @SuppressWarnings("unchecked")
    final Enumeration<Logger> currentLoggers = LogManager.getCurrentLoggers();
    final List<String> loggerNames = new ArrayList<String>();
    while (currentLoggers.hasMoreElements()) {
      final Logger logger = currentLoggers.nextElement();
      loggerNames.add(logger.getName());
    }
    Collections.sort(loggerNames);
    return loggerNames.toArray(new String[0]);
  }

  /*
   * (non-Javadoc)
   * @see mycomp.myapp.jmx.LoggerManagerMXBean#getLogLevel(java.lang.String)
   */
  @Override
  public String getLogLevel(final String loggerName) {
    final Logger logger = Logger.getLogger(loggerName);
    final Level curLevel = logger.getLevel();
    return curLevel.toString();
  }

  /*
   * (non-Javadoc)
   * @see mycomp.myapp.jmx.LoggerManagerMXBean#registerLoggerMBeans()
   */
  @Override
  public void registerLoggerMBeans() {
    // Create and Register the top level Log4J MBean for the webapp
    try {
      ObjectName mbo;
      mbo = createRootLoggerObjectName(webapp);
      final MBeanServer server = findMBeanServer();

      if (!server.isRegistered(mbo)) {
        hierarchyDynamicMBean = new Log4jHierarchyDynamicMBean();
        server.registerMBean(hierarchyDynamicMBean, mbo);
        // Add the root logger to the Hierarchy MBean
        hierarchyDynamicMBean.addLoggerMBean(Logger.getRootLogger().getName());
      }

      // Get each logger from the Log4J Repository and add it to
      // the Hierarchy MBean if it's not already registered.
      final LoggerRepository r = LogManager.getLoggerRepository();

      @SuppressWarnings("unchecked")
      final java.util.Enumeration<Logger> loggers = r.getCurrentLoggers();

      int count = 1;
      while (loggers.hasMoreElements()) {
        final String name = loggers.nextElement().getName();
        if (LOG.isDebugEnabled()) {
          LOG.debug("Registering " + name);
        }
        try {
          final Hashtable<String, String> loggerNameParameters = new Hashtable<String, String>();
          loggerNameParameters.put(LOG4J_PATH, name);
          final ObjectName objectName = new ObjectName(LOG4J_DOMAIN, loggerNameParameters);
          if (!server.isRegistered(objectName)) {
            hierarchyDynamicMBean.addLoggerMBean(name);
            count++;
          }
        }
        catch (final Exception e) {
          LOG.debug("couldn't register log4j mbean " + name);
        }
      }
      if (LOG.isInfoEnabled()) {
        LOG.info("[contextInitialized]: " + count + " log4j MBeans registered.");
      }
    }
    catch (final JMException e) {
      LOG.error("[unregisterMBeans]: ", e);
    }
  }


  @Override
  public void registerMBeans() {

    super.registerMBeans();
    registerLoggerMBeans();
  }

  /*
   * (non-Javadoc)
   * @see mycomp.myapp.jmx.LoggerManagerMXBean#setLogLevel(java.lang.String, java.lang.String)
   */
  @Override
  public void setLogLevel(final String loggerName, final String logLevel) {
    final Logger logger = Logger.getLogger(loggerName);
    final Level curLevel = logger.getLevel();
    final Level newLevel = Level.toLevel(logLevel, curLevel);
    logger.setLevel(newLevel);
  }

  /*
   * (non-Javadoc)
   * @see mycomp.myapp.jmx.LoggerManagerMXBean#unregisterLoggerMBeans()
   */
  @Override
  public void unregisterLoggerMBeans() {
    try {

      final MBeanServer server = findMBeanServer();
      ObjectName mbo;
      mbo = createRootLoggerObjectName(webapp);
      // unregister the root logger mbean
      server.unregisterMBean(mbo);

      final ObjectName qmbo = new ObjectName(LoggerManager.LOG4J_QUERYNAME);
      final Set<ObjectName> names = server.queryNames(qmbo, null);
      if (LOG.isInfoEnabled()) {
        LOG.info("[unregisterMBeans]: Found " + names.size() + " log4j logger MBeans to unregister.");
      }
      for (final ObjectName name : names) {
        server.unregisterMBean(name);
      }
    }
    catch (final Exception e) {
      LOG.error("[unregisterMBeans]: ", e);
    }
  }

  /*
   * (non-Javadoc)
   * @see mycomp.myapp.jmx.MBeanSupport#unregisterMBeans()
   */
  @Override
  public void unregisterMBeans() {
    super.registerMBeans();
    unregisterLoggerMBeans();
    super.unregisterMBeans();
  }
}

我正在将项目从log4j1迁移到log4j2。我该如何迁移与jmx相关的代码以使用log4j2?

还使用了HierarchyDynamicMBean

public class Log4jHierarchyDynamicMBean extends HierarchyDynamicMBean {

  *//** The loggers to turn off. *//*
  private final List<Logger> loggersToTurnOff = Arrays.asList(
      new Logger[] { Logger.getLogger(LoggerDynamicMBean.class)
          , Logger.getLogger(HierarchyDynamicMBean.class)
          , Logger.getLogger(AppenderDynamicMBean.class) });


   * (non-Javadoc)
   * @see org.apache.log4j.jmx.HierarchyDynamicMBean#postRegister(java.lang.Boolean)

  *//**
   * Post register.
   *
   * @param registrationDone the registration done
   *//*
  @Override
  public void postRegister(final java.lang.Boolean registrationDone) {
    final Map<Logger, Level> levels = new HashMap<Logger, Level>(loggersToTurnOff.size());
    for (final Logger logger : loggersToTurnOff)
    {
      levels.put(logger, logger.getLevel());
      logger.setLevel(Level.OFF);
    }
    super.postRegister(registrationDone);
    for (final Logger logger : loggersToTurnOff)
    {
      levels.put(logger, logger.getLevel());
      logger.setLevel(levels.get(logger));
    }
  }

}

0 个答案:

没有答案