Simple DynamicMBean to monitor
JMX API Includes possibility to create "Dynamic MBean", whose management interface is determined at runtime. It means management interface can not be determined by looking at the source code.
Here is a simple example using Spring.
JMX Bean Configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<description>KPI Agent Context</description>
<context:annotation-config />
<context:component-scan base-package="com.test.dm.kpi.agent" />
<!-- JMX Beans -->
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="autodetect" value="true" />
<property name="namingStrategy" ref="namingStrategy" />
<property name="assembler" ref="assembler" />
</bean>
<bean id="jmxAttributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />
<bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
<property name="attributeSource" ref="jmxAttributeSource" />
</bean>
<bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
<property name="attributeSource" ref="jmxAttributeSource" />
</bean>
</beans>
Create DynamicMBean :
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.DynamicMBean;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.ReflectionException;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.stereotype.Component;
@Component
@ManagedResource(objectName = "performancedyna:name=ProfilingDataDyna", description = "Profiling Data for dynamic profiled methods.")
public class ProfilingDataDynamicMBean implements DynamicMBean {
protected Map<String, String> methodExecutionData = new ConcurrentHashMap<String, String>();
private MBeanAttributeInfo[] mbeanAttributesInfo = new MBeanAttributeInfo[2];
private MBeanInfo mbeanInfo = null;
public ProfilingDataDynamicMBean() {
this.buildDynamicMBeanInfo();
}
@Override
public Object getAttribute(String attribute) throws AttributeNotFoundException,
MBeanException, ReflectionException {
return methodExecutionData.get(attribute);
}
@Override
public AttributeList getAttributes(String[] attributes) {
if (attributes == null) {
return new AttributeList();
}
final List<Attribute> result = new ArrayList<Attribute>(attributes.length);
for (String attr : attributes) {
result.add(new Attribute(attr, methodExecutionData.get(attr)));
}
return new AttributeList(result);
}
@Override
public MBeanInfo getMBeanInfo() {
return mbeanInfo;
}
@Override
public Object invoke(String arg0, Object[] arg1, String[] arg2)
throws MBeanException, ReflectionException {
return null;
}
@Override
public void setAttribute(Attribute arg0) throws AttributeNotFoundException,
InvalidAttributeValueException, MBeanException, ReflectionException {
}
@Override
public AttributeList setAttributes(AttributeList arg0) {
return null;
}
private void buildDynamicMBeanInfo() {
mbeanAttributesInfo[0] = new MBeanAttributeInfo("TestAttribute1", "java.lang.String", "Its a test attribute 1", false, false, false); // writable
mbeanAttributesInfo[1] = new MBeanAttributeInfo("TestAttribute2", "java.lang.String", "Its a test attribute 2", false, false, false);
mbeanInfo = new MBeanInfo("com.test.dm.kpi.agent.application.ProfilingDataDynamicMBean", "ProfilingDataDynamicMBean", mbeanAttributesInfo, null, null, null);
methodExecutionData.put("TestAttribute1", "Test Values 1");
methodExecutionData.put("TestAttribute2", "Test Values 2");
}
private Map<String, String> getMethodExecutionData() {
return methodExecutionData;
}
public void setMethodExecutionData(Map<String, String> methodExecutionData) {
this.methodExecutionData = methodExecutionData;
}
public void addMethodExcutionData(String key, String value) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
this.getMethodExecutionData().put(key, value);
}
}
Adding Dynamic Attribute at Runtime:
User the ProfilingDataDynamicMBean to add execution data like below.
dataDynamicBean.addMethodExcutionData("TestAttribute1", (System.currentTimeMillis() + "1111"));
No comments:
Post a Comment