001 package com.hammurapi.eventbus.monitoring;
002
003 import java.util.ArrayList;
004 import java.util.Collection;
005 import java.util.Map;
006 import java.util.concurrent.ConcurrentHashMap;
007
008 import javax.management.MBeanServer;
009 import javax.management.ObjectName;
010 import javax.management.StandardMBean;
011
012 import com.hammurapi.eventbus.EventBusException;
013
014 /**
015 * Statistics collector which exposes statistics as MBeans.
016 * @author Pavel Vlasov
017 *
018 */
019 public class JmxStatsCollector implements StatsCollector {
020
021 private static volatile long keyCounter;
022
023 private MBeanServer mBeanServer;
024 private String objectNamePrefix;
025
026 private Map<Stats, Iterable<ObjectName>> regInfo = new ConcurrentHashMap<Stats, Iterable<ObjectName>>();
027
028 /**
029 * @param mBeanServer MBean server to register statistics MBeans.
030 * @param objectNamePrefix Object name prefix for statistics MBeans without trailing comma.
031 * E.g. <code>mycategory:mykey=myvalue</code>.
032 */
033 public JmxStatsCollector(MBeanServer mBeanServer, String objectNamePrefix) {
034 this.mBeanServer = mBeanServer;
035 this.objectNamePrefix = objectNamePrefix;
036 }
037
038 @Override
039 public void add(Stats root) {
040 Collection<ObjectName> reg = new ArrayList<ObjectName>();
041 add(root, objectNamePrefix, reg);
042 }
043
044 private void add(Stats stats, String prefix, Collection<ObjectName> reg) {
045 @SuppressWarnings("unchecked")
046 Class<Stats> mBeanInterface = (Class<Stats>) stats.getClass().getInterfaces()[0];
047 int idx = mBeanInterface.getName().lastIndexOf('.');
048 String key = mBeanInterface.getName().substring(idx+1)+"("+(++keyCounter)+")";
049 String name = prefix+","+key+"="+stats.getName();
050 try {
051 ObjectName oName = new ObjectName(name);
052 reg.add(oName);
053 mBeanServer.registerMBean(new StandardMBean(stats, mBeanInterface), oName);
054 } catch (Exception e) {
055 throw new EventBusException(e);
056 }
057 for (Stats child: stats.children()) {
058 add(child, name, reg);
059 }
060 }
061
062 public void remove(Stats root) {
063 for (ObjectName oName: regInfo.get(root)) {
064 try {
065 mBeanServer.unregisterMBean(oName);
066 } catch (Exception e) {
067 throw new EventBusException(e);
068 }
069 }
070 }
071
072 }