1 | package com.hammurapi.eventbus.monitoring; |
2 | |
3 | import java.util.ArrayList; |
4 | import java.util.Collection; |
5 | import java.util.Map; |
6 | import java.util.concurrent.ConcurrentHashMap; |
7 | |
8 | import javax.management.MBeanServer; |
9 | import javax.management.ObjectName; |
10 | import javax.management.StandardMBean; |
11 | |
12 | import com.hammurapi.eventbus.EventBusException; |
13 | |
14 | /** |
15 | * Statistics collector which exposes statistics as MBeans. |
16 | * @author Pavel Vlasov |
17 | * |
18 | */ |
19 | public class JmxStatsCollector implements StatsCollector { |
20 | |
21 | private static volatile long keyCounter; |
22 | |
23 | private MBeanServer mBeanServer; |
24 | private String objectNamePrefix; |
25 | |
26 | private Map<Stats, Iterable<ObjectName>> regInfo = new ConcurrentHashMap<Stats, Iterable<ObjectName>>(); |
27 | |
28 | /** |
29 | * @param mBeanServer MBean server to register statistics MBeans. |
30 | * @param objectNamePrefix Object name prefix for statistics MBeans without trailing comma. |
31 | * E.g. <code>mycategory:mykey=myvalue</code>. |
32 | */ |
33 | public JmxStatsCollector(MBeanServer mBeanServer, String objectNamePrefix) { |
34 | this.mBeanServer = mBeanServer; |
35 | this.objectNamePrefix = objectNamePrefix; |
36 | } |
37 | |
38 | @Override |
39 | public void add(Stats root) { |
40 | Collection<ObjectName> reg = new ArrayList<ObjectName>(); |
41 | add(root, objectNamePrefix, reg); |
42 | } |
43 | |
44 | private void add(Stats stats, String prefix, Collection<ObjectName> reg) { |
45 | @SuppressWarnings("unchecked") |
46 | Class<Stats> mBeanInterface = (Class<Stats>) stats.getClass().getInterfaces()[0]; |
47 | int idx = mBeanInterface.getName().lastIndexOf('.'); |
48 | String key = mBeanInterface.getName().substring(idx+1)+"("+(++keyCounter)+")"; |
49 | String name = prefix+","+key+"="+stats.getName(); |
50 | try { |
51 | ObjectName oName = new ObjectName(name); |
52 | reg.add(oName); |
53 | mBeanServer.registerMBean(new StandardMBean(stats, mBeanInterface), oName); |
54 | } catch (Exception e) { |
55 | throw new EventBusException(e); |
56 | } |
57 | for (Stats child: stats.children()) { |
58 | add(child, name, reg); |
59 | } |
60 | } |
61 | |
62 | public void remove(Stats root) { |
63 | for (ObjectName oName: regInfo.get(root)) { |
64 | try { |
65 | mBeanServer.unregisterMBean(oName); |
66 | } catch (Exception e) { |
67 | throw new EventBusException(e); |
68 | } |
69 | } |
70 | } |
71 | |
72 | } |