1 15 package org.apache.hivemind.management.mbeans; 16 17 import java.util.ArrayList ; 18 import java.util.HashMap ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 import java.util.Map ; 22 import java.util.Set ; 23 24 import javax.management.AttributeNotFoundException ; 25 import javax.management.MBeanAttributeInfo ; 26 import javax.management.MBeanException ; 27 import javax.management.ReflectionException ; 28 29 import org.apache.hivemind.management.impl.PerformanceCollector; 30 import org.apache.hivemind.service.MethodSignature; 31 32 41 public class PerformanceMonitorMBean extends AbstractDynamicMBean implements PerformanceCollector 42 { 43 protected static final String DATA_TYPE_MAXIMUM_TIME = "Maximum time"; 44 45 protected static final String DATA_TYPE_MINIMUM_TIME = "Minimum time"; 46 47 protected static final String DATA_TYPE_LAST_TIME = "Last time"; 48 49 protected static final String DATA_TYPE_AVERAGE_TIME = "Average time"; 50 51 protected static final String DATA_TYPE_COUNT = "Count"; 52 53 private Set _methods; 54 55 private Map _countersByMethodSignature = new HashMap (); 56 57 private Map _countersByMethodId = new HashMap (); 58 59 private MBeanAttributeInfo [] _mBeanAttributeInfos; 60 61 private Map _mBeanAttributeNameToCounterMap = new HashMap (); 62 63 70 public PerformanceMonitorMBean(Set methods) 71 { 72 _methods = methods; 73 initCounters(); 74 } 75 76 79 protected void initCounters() 80 { 81 List mBeanAttributeInfoList = new ArrayList (); 82 for (Iterator methodIterator = _methods.iterator(); methodIterator.hasNext();) 83 { 84 MethodSignature method = (MethodSignature) methodIterator.next(); 85 Counter counter = new Counter(); 86 _countersByMethodSignature.put(method, counter); 87 _countersByMethodId.put(method.getUniqueId(), counter); 88 89 initAttributes(mBeanAttributeInfoList, counter, method); 90 } 91 _mBeanAttributeInfos = (MBeanAttributeInfo []) mBeanAttributeInfoList 92 .toArray(new MBeanAttributeInfo [mBeanAttributeInfoList.size()]); 93 } 94 95 99 protected void initAttributes(List mBeanAttributeInfoList, Counter counter, MethodSignature method) 100 { 101 addAttribute( 102 mBeanAttributeInfoList, counter, 103 method, 104 Long .class, 105 DATA_TYPE_COUNT, 106 "Number of method calls for method " + method); 107 addAttribute( 108 mBeanAttributeInfoList, counter, 109 method, 110 Long .class, 111 DATA_TYPE_AVERAGE_TIME, 112 "Average execution time in ms of method " + method); 113 addAttribute( 114 mBeanAttributeInfoList, counter, 115 method, 116 Long .class, 117 DATA_TYPE_LAST_TIME, 118 "Last execution time in ms of method " + method); 119 addAttribute( 120 mBeanAttributeInfoList, counter, 121 method, 122 Long .class, 123 DATA_TYPE_MINIMUM_TIME, 124 "Minimum execution time in ms of method " + method); 125 addAttribute( 126 mBeanAttributeInfoList, counter, 127 method, 128 Long .class, 129 DATA_TYPE_MAXIMUM_TIME, 130 "Maximum execution time in ms of method " + method); 131 132 } 133 134 137 private void addAttribute(List mBeanAttributeInfoList, Counter counter, MethodSignature method, 138 Class attributeType, String performanceDataType, String description) 139 { 140 String attributeName = null; 141 MBeanAttributeInfo attributeInfo = null; 142 try 143 { 144 attributeName = buildAttributeName(method, performanceDataType); 145 attributeInfo = new MBeanAttributeInfo (attributeName, attributeType.getName(), description, 146 true, false, false); 147 } 148 catch (IllegalArgumentException e) 149 { 150 attributeName = buildAttributeNameDefensive(method, performanceDataType); 154 attributeInfo = new MBeanAttributeInfo (attributeName, attributeType.getName(), description, 155 true, false, false); 156 } 157 mBeanAttributeInfoList.add(attributeInfo); 158 AttributeToCounterLink atcLink = new AttributeToCounterLink(counter, performanceDataType); 159 _mBeanAttributeNameToCounterMap.put(attributeName, atcLink); 160 } 161 162 165 private String makeValidJavaIdentifier(String attributeName) 166 { 167 StringBuffer result = new StringBuffer (); 168 for (int i = 0; i < attributeName.length(); i++) 169 { 170 char currentChar = attributeName.charAt(i); 171 if (Character.isJavaIdentifierPart(currentChar)) 172 result.append(currentChar); 173 else result.append('_'); 174 } 175 return result.toString(); 176 } 177 178 182 protected String buildAttributeName(MethodSignature method, String performanceDataType) 183 { 184 String attributeName = method.getUniqueId() + " : " + performanceDataType; 185 return attributeName; 186 } 187 188 195 protected String buildAttributeNameDefensive(MethodSignature method, String performanceDataType) 196 { 197 String attributeName = method.getUniqueId() + "$[" + performanceDataType; 198 return makeValidJavaIdentifier(attributeName); 199 } 200 201 204 public void addMeasurement(MethodSignature method, long executionTime) 205 { 206 Counter counter = (Counter) _countersByMethodSignature.get(method); 207 counter.addMeasurement(executionTime); 208 } 209 210 protected MBeanAttributeInfo [] createMBeanAttributeInfo() 211 { 212 return _mBeanAttributeInfos; 213 } 214 215 218 public Object getAttribute(String attribute) throws AttributeNotFoundException , MBeanException , 219 ReflectionException 220 { 221 AttributeToCounterLink atcLink = (AttributeToCounterLink) _mBeanAttributeNameToCounterMap.get(attribute); 223 if (atcLink == null) 224 throw new AttributeNotFoundException ("Attribute '" + attribute + "' not found"); 225 226 String type = atcLink.type; 227 Counter counter = atcLink.counter; 228 if (type.equals(DATA_TYPE_COUNT)) 229 return new Long (counter.count); 230 else if (type.equals(DATA_TYPE_AVERAGE_TIME)) 231 return new Long (counter.average); 232 else if (type.equals(DATA_TYPE_LAST_TIME)) 233 return new Long (counter.last); 234 else if (type.equals(DATA_TYPE_MINIMUM_TIME)) 235 return new Long (counter.min); 236 else if (type.equals(DATA_TYPE_MAXIMUM_TIME)) 237 return new Long (counter.max); 238 else 239 throw new IllegalArgumentException ("Unknown performance data type"); 240 } 241 242 } 243 244 247 248 class Counter 249 { 250 long count = 0; 251 252 long last = 0; 253 254 long average = 0; 255 256 long max = 0; 257 258 long min = 0; 259 260 public String toString() 261 { 262 return "" + count; 263 } 264 265 270 public void addMeasurement(long executionTime) 271 { 272 count++; 273 last = executionTime; 274 average = (average * (count - 1) + executionTime) / count; 276 if (executionTime < min || min == 0) 277 min = executionTime; 278 if (executionTime > max || max == 0) 279 max = executionTime; 280 } 281 } 282 283 class AttributeToCounterLink 284 { 285 Counter counter; 286 287 String type; 288 289 public AttributeToCounterLink(Counter counter, String type) 290 { 291 this.counter = counter; 292 this.type = type; 293 } 294 } 295 | Popular Tags |