All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.split.client.jmx.JmxMonitor Maven / Gradle / Ivy

package io.split.client.jmx;

import java.lang.management.ManagementFactory;
import java.net.URL;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;

/**
 * A JMX monitor singleton.
 *
 * @author patricioe
 */
public class JmxMonitor {

    private final Logger log = LoggerFactory.getLogger(getClass());

    private MBeanServer mbs;
    private static JmxMonitor monitorInstance;

    private JmxMonitor() {
        mbs = ManagementFactory.getPlatformMBeanServer();
    }

    public static JmxMonitor getInstance() {
        if (monitorInstance == null) {
            monitorInstance = new JmxMonitor();
        }
        return monitorInstance;
    }


    public void registerMonitor(String name, String monitorType, Object monitoringInterface)
            throws MalformedObjectNameException, InstanceAlreadyExistsException,
            MBeanRegistrationException, NotCompliantMBeanException {

        String monitorName = generateMonitorName(name, monitorType);
        log.info("Registering JMX {}", monitorName);

        ObjectName oName = new ObjectName(monitorName);

        // Check if the monitor is already registered
        if (mbs.isRegistered(oName)) {
            log.info("Monitor already registered: {}", oName);
            return;
        }

        mbs.registerMBean(monitoringInterface, oName);
    }

    public void unregisterMonitor(String name, String monitorType)
            throws MalformedObjectNameException, InstanceAlreadyExistsException,
            MBeanRegistrationException, NotCompliantMBeanException {

        String monitorName = generateMonitorName(name, monitorType);
        log.info("Unregistering JMX {}", monitorName);

        ObjectName oName = new ObjectName(monitorName);

        // Check if the monitor is already registered
        if (!mbs.isRegistered(oName)) {
            log.info("Monitor is not registered: {}", oName);
            return;
        }

        try {
            mbs.unregisterMBean(oName);
        } catch (InstanceNotFoundException e) {
            log.warn("Failed to unregister monitor: {}" + oName.toString(), e);
        }
    }

    private String generateMonitorName(String className, String monitorType) {
        StringBuilder sb = new StringBuilder();
        sb.append(className);
        //sb.append(":ServiceType=");
        sb.append(":");
        // append the classloader name so we have unique names in web apps.
        sb.append(getUniqueClassloaderIdentifier());
        if (null != monitorType && monitorType.length() > 0) {
            sb.append("Type=" + monitorType);
        }
        return sb.toString();
    }

    /**
     * Generates a unique, but still nice and predictable name representing this classloader so that
     * even apps operating under a web server such as tomcat with multiple classloaders would bee able
     * to register each with its own unique mbean.
     */
    private String getUniqueClassloaderIdentifier() {
        String contextPath = getContextPath();
        if (contextPath != null) {
            return contextPath;
        }
        return "split";
    }

    /**
     * Tries to guess a context path for the running application.
     * If this is a web application running under a tomcat server this will work.
     * If unsuccessful, returns null.
     *
     * @return A string representing the current context path or null if it cannot be determined.
     */
    private String getContextPath() {
        ClassLoader loader = getClass().getClassLoader();
        if (loader == null)

            return null;
        URL url = loader.getResource("/");
        if (url != null) {
            String[] elements = url.toString().split("/");
            for (int i = elements.length - 1; i > 0; --i) {
                // URLs look like this: file:/.../ImageServer/WEB-INF/classes/
                // And we want that part that's just before WEB-INF
                if ("WEB-INF".equals(elements[i])) {
                    return elements[i - 1];
                }
            }
        }
        return null;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy