Permalink
Browse files

Issue #45 First crack at registering Monitor objects with the JMX reg…

…istry. Still needs some cleanup.
  • Loading branch information...
1 parent 43c5196 commit 0ffc20edc6908372870a74b5d5907c47f8edb7a6 @gorzell committed May 9, 2012
@@ -20,9 +20,11 @@
package com.netflix.servo.examples;
import com.netflix.servo.DefaultMonitorRegistry;
+import com.netflix.servo.MonitorContext;
import com.netflix.servo.annotations.DataSourceType;
import com.netflix.servo.annotations.Monitor;
import com.netflix.servo.annotations.MonitorTags;
+import com.netflix.servo.monitor.Counter;
import com.netflix.servo.tag.InjectableTag;
import com.netflix.servo.tag.SortedTagList;
import com.netflix.servo.tag.Tag;
@@ -71,16 +73,22 @@ public static void main(String[] args) throws InterruptedException {
tags.add(InjectableTag.HOSTNAME);
tags.add(InjectableTag.IP);
+ Counter m1 = new com.netflix.servo.monitor.BasicCounter(new MonitorContext.Builder("test1").build());
+
+
String id = null;
if (args.length > 0) {
id = args[0];
}
BasicExample example = new BasicExample(tags);
DefaultMonitorRegistry.getInstance().registerAnnotatedObject(example);
+ DefaultMonitorRegistry.getInstance().register(m1);
+
while(true) {
example.counter.incrementAndGet();
+ m1.increment();
example.setSampleGauge(Math.round(Math.random() * 1000));
Thread.sleep(10000);
}
@@ -27,9 +27,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.management.DynamicMBean;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
+import javax.management.*;
+import javax.management.modelmbean.InvalidTargetObjectTypeException;
+import javax.management.modelmbean.RequiredModelMBean;
import java.lang.management.ManagementFactory;
import java.util.Collections;
import java.util.HashSet;
@@ -65,7 +65,9 @@ private void register(ObjectName name, DynamicMBean mbean)
mBeanServer.registerMBean(mbean, name);
}
- /** {@inheritDoc} */
+ /**
+ * {@inheritDoc}
+ */
public void registerAnnotatedObject(Object obj) {
Preconditions.checkNotNull(obj, "obj cannot be null");
try {
@@ -78,11 +80,13 @@ public void registerAnnotatedObject(Object obj) {
objects.add(annoObj);
} catch (Throwable t) {
logger.warn("could not register object of class "
- + obj.getClass().getCanonicalName(), t);
+ + obj.getClass().getCanonicalName(), t);
}
}
- /** {@inheritDoc} */
+ /**
+ * {@inheritDoc}
+ */
public void unregisterAnnotatedObject(Object obj) {
Preconditions.checkNotNull(obj, "obj cannot be null");
try {
@@ -96,11 +100,13 @@ public void unregisterAnnotatedObject(Object obj) {
objects.remove(annoObj);
} catch (Throwable t) {
logger.warn("could not un-register object of class "
- + obj.getClass().getCanonicalName(), t);
+ + obj.getClass().getCanonicalName(), t);
}
}
- /** {@inheritDoc} */
+ /**
+ * {@inheritDoc}
+ */
public Set<AnnotatedObject> getRegisteredAnnotatedObjects() {
return ImmutableSet.copyOf(objects);
}
@@ -123,6 +129,18 @@ public void unregisterAnnotatedObject(Object obj) {
@Override
public void register(Monitor monitor) {
+ MonitorModelMBean bean = MonitorModelMBean.newInstance(monitor);
+ try {
+ mBeanServer.registerMBean(bean.getMBean(), bean.getObjectName());
+ } catch (InstanceAlreadyExistsException e) {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ } catch (MBeanRegistrationException e) {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ } catch (NotCompliantMBeanException e) {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+
+ monitors.add(monitor);
}
/**
@@ -132,6 +150,13 @@ public void register(Monitor monitor) {
*/
@Override
public void unregister(Monitor monitor) {
-
+ try {
+ mBeanServer.unregisterMBean(MonitorModelMBean.createObjectName(monitor.getContext()));
+ } catch (InstanceNotFoundException e) {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ } catch (MBeanRegistrationException e) {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ monitors.remove(monitor);
}
}
@@ -1,77 +0,0 @@
-package com.netflix.servo.jmx;
-
-import com.netflix.servo.Monitor;
-import com.netflix.servo.MonitorContext;
-import com.netflix.servo.tag.Tag;
-
-import javax.management.*;
-import java.util.Map;
-
-/**
- * User: gorzell
- * Date: 5/1/12
- */
-public final class MonitorMBean implements DynamicMBean {
- private final Monitor monitor;
- private final ObjectName objectName;
- private final MBeanInfo beanInfo;
- private final Map<String, MonitoredAttribute> attrs;
- private final MetadataMBean metadataMBean;
-
- public MonitorMBean(Monitor monitor){
- this.monitor = monitor;
- this.objectName = createObjectName(monitor.getContext());
- }
-
- private ObjectName createObjectName(MonitorContext context){
- StringBuilder builder = new StringBuilder();
- builder.append((domain == null) ? getClass().getCanonicalName() : domain)
- .append(":class=")
- .append(className);
-
- for (Tag t : tags) {
- builder.append(",").append(t.tagString());
- }
-
- builder.append(",field=").append(field);
-
- String name = builder.toString();
- try {
- return new ObjectName(builder.toString());
- } catch (MalformedObjectNameException e) {
- throw new IllegalArgumentException("invalid ObjectName " + name, e);
- }
- }
-
- @Override
- public Object getAttribute(String s) throws AttributeNotFoundException, MBeanException, ReflectionException {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public AttributeList getAttributes(String[] strings) {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public MBeanInfo getMBeanInfo() {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
-
- //Unsupported methods
- @Override
- public Object invoke(String s, Object[] objects, String[] strings) throws MBeanException, ReflectionException {
- throw new UnsupportedOperationException("invoke(...) is not supported on this mbean");
- }
-
- @Override
- public AttributeList setAttributes(AttributeList objects) {
- throw new UnsupportedOperationException("setAttributes(...) is not supported on this mbean");
- }
-
- @Override
- public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
- throw new UnsupportedOperationException("setAttribute(...) is not supported on this mbean");
- }
-}
@@ -0,0 +1,127 @@
+package com.netflix.servo.jmx;
+
+import com.netflix.servo.Monitor;
+import com.netflix.servo.MonitorContext;
+import com.netflix.servo.tag.Tag;
+
+import javax.management.*;
+import javax.management.modelmbean.*;
+import java.lang.reflect.Method;
+
+/**
+ * User: gorzell
+ * Date: 5/8/12
+ */
+class MonitorModelMBean {
+ private final ObjectName objectName;
+ private final ModelMBean mBean;
+
+ private MonitorModelMBean(Monitor monitor) {
+ this.objectName = createObjectName(monitor.getContext());
+ try {
+ this.mBean = createModelMBean(monitor);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Could not create Mbean for Monitor:" + monitor, e);
+ }
+ }
+
+ public static MonitorModelMBean newInstance(Monitor monitor) {
+ return new MonitorModelMBean(monitor);
+ }
+
+ public ObjectName getObjectName() {
+ return objectName;
+ }
+
+ public ModelMBean getMBean() {
+ return mBean;
+ }
+
+ static ObjectName createObjectName(MonitorContext context) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("com.netflix.servo").append(":name=").append(context.getName());
+
+ for (Tag t : context.getTags()) {
+ builder.append(",").append(t.tagString());
+ }
+
+ String name = builder.toString();
+ try {
+ return new ObjectName(builder.toString());
+ } catch (MalformedObjectNameException e) {
+ throw new IllegalArgumentException("invalid ObjectName " + name, e);
+ }
+ }
+
+ private ModelMBean createModelMBean(Monitor monitor) throws IntrospectionException, NoSuchMethodException, MBeanException, InstanceNotFoundException, InvalidTargetObjectTypeException {
+ RequiredModelMBean monitorMMBean = new RequiredModelMBean(createModelMBeanInfo(monitor));
+ monitorMMBean.setManagedResource(monitor, "ObjectReference");
+ return monitorMMBean;
+ }
+
+ private ModelMBeanInfo createModelMBeanInfo(Monitor monitor) throws MBeanException, IntrospectionException, NoSuchMethodException {
+ Class monitorClass = monitor.getClass();
+ Method m = monitorClass.getMethod("getValue", null);
+ System.out.println(m.getReturnType().getCanonicalName());
+
+
+ Descriptor monitorDescription = new DescriptorSupport("name=" + objectName,
+ "descriptorType=mbean",
+ "displayName=" + monitor.getContext().getName(),
+ "type=" + monitorClass.getCanonicalName(),
+ "log=T",
+ "logFile=jmxmain.log",
+ "currencyTimeLimit=10");
+
+ ModelMBeanInfo info = new ModelMBeanInfoSupport("Monitor", "ModelMBean for Monitor objects",
+ createMonitorAttributes(monitorClass, m),
+ null,
+ createMonitorOperations(monitorClass, m),
+ null);
+
+ info.setMBeanDescriptor(monitorDescription);
+
+ return info;
+ }
+
+ private ModelMBeanOperationInfo[] createMonitorOperations(Class monitorClass, Method... methods) {
+ ModelMBeanOperationInfo[] monitorOperations =
+ new ModelMBeanOperationInfo[methods.length];
+
+ MBeanParameterInfo[] getParms = new MBeanParameterInfo[0];
+
+ for (int i = 0; i < methods.length; i++) {
+ Descriptor getValueDesc =
+ new DescriptorSupport(
+ "name=" + methods[i].getName(),
+ "descriptorType=operation",
+ "class=" + monitorClass.getCanonicalName(),
+ "role=operation");
+
+ monitorOperations[0] =
+ new ModelMBeanOperationInfo(
+ methods[i].getName(),
+ methods[i].getName(),
+ getParms,
+ methods[i].getReturnType().getCanonicalName(),
+ MBeanOperationInfo.INFO,
+ getValueDesc);
+ }
+ return monitorOperations;
+ }
+
+ private ModelMBeanAttributeInfo[] createMonitorAttributes(Class monitorClass, Method... methods) {
+ ModelMBeanAttributeInfo[] attributes = new ModelMBeanAttributeInfo[methods.length];
+
+ for (int i = 0; i < methods.length; i++) {
+ Descriptor monitorValueDescription = new DescriptorSupport("name=MonitorValue",
+ "descriptorType=attribute",
+ "displayName=MonitorValue",
+ "getMethod=" + methods[i].getName());
+
+ attributes[i] = new ModelMBeanAttributeInfo("MonitorValue", methods[i].getReturnType().getCanonicalName(),
+ "Current value of the monitor", true, false, false, monitorValueDescription);
+ }
+ return attributes;
+ }
+}

0 comments on commit 0ffc20e

Please sign in to comment.