2c48bab91a
JmxMBeanServer is a concrete implementation of a MBeanServer. We want to use it directly because we need to bypass calls to JmxMBeanServer.registerMBean and JmxMBeanServer.unregisterMBean. They take ObjectName as parameter, copy it using ObjectName.getInstance(ObjectName) and pass it to registerMBean and unregisterMBean of JmxMBeanServer.getMBeanServerInterceptor(). We want to avoid this copy and pass the ObjectName argument directly to JmxMBeanServer.getMBeanServerInterceptor(). To do that this patch: 1. changes all MBeanServer variables to JmxMBeanServer 2. creates JmxMBeanServer in APIBuilder making sure accessing interceptors is allowed 3. makes sure that JmxMBeanServer.getMBeanServerInterceptor().registerMBean is called wherever JmxMBeanServer.registerMBean was called 4. makes sure that JmxMBeanServer.getMBeanServerInterceptor().unregisterMBean is called whenever JmxMBeanServer.unregisterMBean was called Next patch will use different ObjectName implementation that will use less memory and this patch is crucial because without it every ObjectName is transformed with ObjectName.getInstance which turns the object into a regular ObjectName. Signed-off-by: Piotr Jastrzebski <piotr@scylladb.com>
93 lines
3.1 KiB
Java
93 lines
3.1 KiB
Java
package com.scylladb.jmx.metrics;
|
|
|
|
import static java.util.Arrays.asList;
|
|
|
|
import java.util.Collection;
|
|
import java.util.function.Predicate;
|
|
import java.util.function.Supplier;
|
|
|
|
import javax.management.InstanceNotFoundException;
|
|
import javax.management.MBeanRegistrationException;
|
|
import javax.management.MBeanServer;
|
|
import javax.management.MalformedObjectNameException;
|
|
import javax.management.ObjectName;
|
|
|
|
import org.apache.cassandra.metrics.Metrics;
|
|
import org.apache.cassandra.metrics.MetricsRegistry;
|
|
|
|
import com.scylladb.jmx.api.APIClient;
|
|
import com.sun.jmx.mbeanserver.JmxMBeanServer;
|
|
|
|
/**
|
|
* Base type for MBeans containing {@link Metrics}.
|
|
*
|
|
* @author calle
|
|
*
|
|
*/
|
|
public abstract class MetricsMBean extends APIMBean {
|
|
private final Collection<Metrics> metrics;
|
|
|
|
public MetricsMBean(APIClient client, Metrics... metrics) {
|
|
this(null, client, metrics);
|
|
}
|
|
|
|
public MetricsMBean(String mbeanName, APIClient client, Metrics... metrics) {
|
|
this(mbeanName, client, asList(metrics));
|
|
}
|
|
|
|
public MetricsMBean(String mbeanName, APIClient client, Collection<Metrics> metrics) {
|
|
super(mbeanName, client);
|
|
this.metrics = metrics;
|
|
}
|
|
|
|
protected Predicate<ObjectName> getTypePredicate() {
|
|
String domain = name.getDomain();
|
|
String type = name.getKeyProperty("type");
|
|
return n -> {
|
|
return domain.equals(n.getDomain()) && type.equals(n.getKeyProperty("type"));
|
|
};
|
|
}
|
|
|
|
private void register(MetricsRegistry registry, JmxMBeanServer server) throws MalformedObjectNameException {
|
|
// Check if we're the first/last of our type bound/removed.
|
|
boolean empty = queryNames(server, getTypePredicate()).isEmpty();
|
|
for (Metrics m : metrics) {
|
|
if (empty) {
|
|
m.registerGlobals(registry);
|
|
}
|
|
m.register(registry);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception {
|
|
// Get name etc.
|
|
name = super.preRegister(server, name);
|
|
// Register all metrics in server
|
|
register(new MetricsRegistry(client, (JmxMBeanServer) server), (JmxMBeanServer) server);
|
|
return name;
|
|
}
|
|
|
|
@Override
|
|
public void postDeregister() {
|
|
// We're officially unbound. Remove all metrics we added.
|
|
try {
|
|
register(new MetricsRegistry(client, server) {
|
|
// Unbind instead of bind. Yes.
|
|
@Override
|
|
public void register(Supplier<MetricMBean> s, ObjectName... objectNames) {
|
|
for (ObjectName name : objectNames) {
|
|
try {
|
|
server.getMBeanServerInterceptor().unregisterMBean(name);
|
|
} catch (MBeanRegistrationException | InstanceNotFoundException e) {
|
|
}
|
|
}
|
|
}
|
|
}, server);
|
|
} catch (MalformedObjectNameException e) {
|
|
// TODO : log?
|
|
}
|
|
super.postDeregister();
|
|
}
|
|
}
|