package com.paessler.prtg.jmx.mbean; import java.lang.management.ManagementFactory; import java.lang.reflect.Constructor; import javax.management.InstanceAlreadyExistsException; import javax.management.MBeanAttributeInfo; import javax.management.MBeanConstructorInfo; import javax.management.MBeanInfo; import javax.management.MBeanNotificationInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanParameterInfo; import javax.management.MBeanRegistrationException; import javax.management.NotCompliantMBeanException; import javax.management.ReflectionException; import javax.management.InstanceNotFoundException; import javax.management.MBeanException; import javax.management.MBeanServer; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.management.StandardMBean; //import javax.management.MBeanInfo; //import javax.management.DynamicMBean; // http://www.javaworld.com/article/2072243/playing-with-jmx-2-0-annotations.html // http://stackoverflow.com/questions/20050127/jmx-mbeaninfo-and-descriptors //@JmxResource(description = "") //@JmxResource(description = "Paessler PRTG Performance stats", domainName = "j256") //@JMXBean(description = "My first JMX bean test") public class PRTGInterface extends StandardMBean implements PRTGInterfaceMBean{ private long id = System.currentTimeMillis(); private String beanName = null; private long queryCount = 0; private long avgExecutionTime = 0; private long avgUploadTime = 0; private long avgSenorCreationTime = 0; private int sensorCount = 0; public PRTGInterface (String name) throws NotCompliantMBeanException{ super(PRTGInterfaceMBean.class); beanName = name; buildMBeanInfo(); } public static String getObjectName(String name){ return "com.paessler.prtg.jmx.mbean.PRTGBean:name="+name; } public static ObjectName getJMXObjectName(String beanname){ ObjectName retVal = null; try { retVal = new ObjectName(beanname); } catch (MalformedObjectNameException e) { } return retVal; } public String getBeanName() {return beanName;} public String getObjectName(){ return getObjectName(getBeanName()); } @Override public long getID() { // TODO Auto-generated method stub return 0; } public void setQueryCount(long val) {queryCount = val;} @Override public long getQueryCount() { // TODO Auto-generated method stub return queryCount; } // -------------------------------------------------------------- public long addTime(long val, long add) { long retVal = val; if(getQueryCount() < 2){ retVal = add; setQueryCount(1); } else if(getQueryCount() == 2){ retVal = (retVal + add)/2; } else { // http://stackoverflow.com/questions/12636613/how-to-calculate-moving-average-without-keeping-the-count-and-data-total long n = getQueryCount(); long newval = add/n; long rem = (long)(retVal * ((double)(n-1)/n)); retVal = rem + newval; } return retVal; } // -------------------------------------------------------------- // @Override public void addQueryCount(long n) { queryCount += n;} // -------------------------------------------------------------- @Override public long getAvgExecutionTime() { return avgExecutionTime;} @Override public void addExecutionTime(long val) { avgExecutionTime = addTime(avgExecutionTime, val); } // -------------------------------------------------------------- // read-write attribute 'AvgUploadTime' public long getAvgUploadTime(){ return avgUploadTime; } @Override public void addUploadTime(long val) { avgUploadTime = addTime(avgUploadTime, val); } // -------------------------------------------------------------- // read-write attribute 'AvgUploadTime' public long getAvgSenorCreationTime(){ return avgSenorCreationTime; } @Override public void addSenorCreationTime(long val) { avgSenorCreationTime = addTime(avgSenorCreationTime, val); } // read-write attribute 'SensorCount' public int getSensorCount() {return sensorCount;}; public void setSensorCount(int val) {sensorCount = val;}; @Override public String printInfo() { // TODO Auto-generated method stub return "Query Count: " + getQueryCount() +"\nAvgExecutionTime: "+getAvgExecutionTime()+"ms"; } public static String getDefaultBeanName(){ return "JMXMiniProbe";} public static PRTGInterface getBean(String beanname){ PRTGInterface retVal = null; if(retVal == null){ try { retVal = new PRTGInterface(beanname); } catch (NotCompliantMBeanException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } // if return retVal; } public static PRTGInterface getAndRegisterBean(String beanname){ // Find an agent from this JVM. Null argument will return // a list of all MBeanServer instances. MBeanServer server =ManagementFactory.getPlatformMBeanServer(); ObjectName name = getJMXObjectName(getObjectName(beanname)); PRTGInterface retVal = getBean(beanname); try { if(server.isRegistered(name)){ server.unregisterMBean(name); } // register the MBean server.registerMBean(retVal, name); // Invoke the printInfo operation on an // uninitialized MBean instance. Object result = server.invoke( name, // MBean name "printInfo", // operation name null, // no parameters null // void signature ); } catch (InstanceNotFoundException e) { e.printStackTrace(); } catch (MBeanException e) { e.getTargetException().printStackTrace(); } catch (ReflectionException e) { e.printStackTrace(); } catch (InstanceAlreadyExistsException e) { e.printStackTrace(); } catch (NotCompliantMBeanException e) { e.printStackTrace(); } return retVal; } public static void unregisterBean(PRTGInterface bean){ final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); try { server.unregisterMBean(new ObjectName(bean.getObjectName())); } catch (MalformedObjectNameException mone) { mone.printStackTrace(); } catch (MBeanRegistrationException mbre) { mbre.printStackTrace(); } catch (InstanceNotFoundException infe) { infe.printStackTrace(); } } /** * This method provides the exposed attributes and operations of the * Dynamic MBean. It provides this information using an MBeanInfo object. */ public MBeanInfo getMBeanInfo() { // Return the information we want to expose for management: // the dMBeanInfo private field has been built at instanciation time // return dMBeanInfo; } /* * ----------------------------------------------------- * PRIVATE METHODS * ----------------------------------------------------- */ /** * Build the private dMBeanInfo field, * which represents the management interface exposed by the MBean, * that is, the set of attributes, constructors, operations and * notifications which are available for management. * * A reference to the dMBeanInfo object is returned by the getMBeanInfo() * method of the DynamicMBean interface. Note that, once constructed, an * MBeanInfo object is immutable. */ private void buildMBeanInfo() { dAttributes[0] = new MBeanAttributeInfo("QueryCount", "java.lang.long", "QueryCount, Number of queries run.", true, true, false); dAttributes[1] = new MBeanAttributeInfo("AvgExecutionTime", "java.lang.long", "AvgExecutionTime, Average query Execution Time[ms].", true, false, false); dAttributes[2] = new MBeanAttributeInfo("AvgUploadTime", "java.lang.long", "avgUploadTime, Average time to upload data Time[ms].", true, false, false); dAttributes[3] = new MBeanAttributeInfo("AvgSenorCreationTime", "java.lang.long", "AvgSenorCreationTime, Average sensor creation Execution.", true, false, false); dAttributes[4] = new MBeanAttributeInfo("sensorCount", "java.lang.int", "SensorCount, Number of sensors.", true, false, false); Constructor[] constructors = this.getClass().getConstructors(); dConstructors[0] = new MBeanConstructorInfo("Constructs a " + "PRTGInterface object", constructors[0]); MBeanParameterInfo[] params = new MBeanParameterInfo[1]; params[0] = new MBeanParameterInfo("val", "java.lang.long", "Last execution time[ms] to add"); dOperations[0] = new MBeanOperationInfo("addExecutionTime", "addExecutionTime, Add execution run stats", params , "void", MBeanOperationInfo.ACTION); // dNotifications[0] = // new MBeanNotificationInfo( // new String[] { AttributeChangeNotification.ATTRIBUTE_CHANGE }, // AttributeChangeNotification.class.getName(), // "This notification is emitted when the reset() method is called."); dMBeanInfo = new MBeanInfo(dClassName, dDescription, dAttributes, dConstructors, dOperations, dNotifications); } /* * ----------------------------------------------------- * PRIVATE VARIABLES * ----------------------------------------------------- */ private String dClassName = this.getClass().getName(); private String dDescription = "JMX: PRTG JMXMiniProbe statistics"; private MBeanAttributeInfo[] dAttributes = new MBeanAttributeInfo[5]; private MBeanConstructorInfo[] dConstructors = new MBeanConstructorInfo[1]; private MBeanNotificationInfo[] dNotifications = new MBeanNotificationInfo[1]; private MBeanOperationInfo[] dOperations = new MBeanOperationInfo[1]; private MBeanInfo dMBeanInfo = null; }