Clover coverage report - Code Coverage for hivemind-jmx release 1.1-beta-2
Coverage timestamp: Tue Jun 28 2005 10:29:45 EDT
file stats: LOC: 239   Methods: 10
NCLOC: 146   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
PerformanceMonitorMBean.java 88.9% 95.8% 90% 93.4%
coverage coverage
 1    // Copyright 2005 The Apache Software Foundation
 2    //
 3    // Licensed under the Apache License, Version 2.0 (the "License");
 4    // you may not use this file except in compliance with the License.
 5    // You may obtain a copy of the License at
 6    //
 7    // http://www.apache.org/licenses/LICENSE-2.0
 8    //
 9    // Unless required by applicable law or agreed to in writing, software
 10    // distributed under the License is distributed on an "AS IS" BASIS,
 11    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12    // See the License for the specific language governing permissions and
 13    // limitations under the License.
 14   
 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    /**
 33    * MBean that holds and calculates the performance data for service method calls intercepted by the
 34    * {@link org.apache.hivemind.management.impl.PerformanceMonitorFactory performanceMonitor}
 35    * interceptor. Creates for each intercepted method 5 MBean attributes: Number of Calls, Minimum,
 36    * maximum, average and last execution time
 37    *
 38    * @author Achim Huegen
 39    * @since 1.1
 40    */
 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 static final String DATA_TYPE_SEPARATOR = " : ";
 54   
 55    private Set _methods;
 56   
 57    private Map _countersByMethodSignature = new HashMap();
 58   
 59    private Map _countersByMethodId = new HashMap();
 60   
 61    private MBeanAttributeInfo[] mBeanAttributeInfos;
 62   
 63    /**
 64    * Creates a new instance
 65    *
 66    * @param methods
 67    * Set with instances of {@link org.apache.hivemind.service.MethodSignature}.
 68    * Contains the methods for that calls can be counted by this MBean
 69    */
 70  2 public PerformanceMonitorMBean(Set methods)
 71    {
 72  2 _methods = methods;
 73  2 initCounters();
 74  2 initAttributes();
 75    }
 76   
 77    /**
 78    * Builds two maps for accessing the counters by method signature and method id
 79    */
 80  2 protected void initCounters()
 81    {
 82  2 for (Iterator methodIterator = _methods.iterator(); methodIterator.hasNext();)
 83    {
 84  6 MethodSignature method = (MethodSignature) methodIterator.next();
 85  6 Counter counter = new Counter();
 86  6 _countersByMethodSignature.put(method, counter);
 87  6 _countersByMethodId.put(method.getUniqueId(), counter);
 88    }
 89    }
 90   
 91    /**
 92    * Creates for each intercepted method 5 MBean attributes: Number of Calls, Minimum, maximum,
 93    * average and last execution time
 94    */
 95  2 protected void initAttributes()
 96    {
 97  2 List mBeanAttributeInfoList = new ArrayList();
 98  2 for (Iterator methodIterator = _methods.iterator(); methodIterator.hasNext();)
 99    {
 100  6 MethodSignature method = (MethodSignature) methodIterator.next();
 101   
 102  6 addAttribute(
 103    mBeanAttributeInfoList,
 104    method,
 105    Long.class,
 106    DATA_TYPE_COUNT,
 107    "Number of method calls for method " + method);
 108  6 addAttribute(
 109    mBeanAttributeInfoList,
 110    method,
 111    Long.class,
 112    DATA_TYPE_AVERAGE_TIME,
 113    "Average execution time in ms of method " + method);
 114  6 addAttribute(
 115    mBeanAttributeInfoList,
 116    method,
 117    Long.class,
 118    DATA_TYPE_LAST_TIME,
 119    "Last execution time in ms of method " + method);
 120  6 addAttribute(
 121    mBeanAttributeInfoList,
 122    method,
 123    Long.class,
 124    DATA_TYPE_MINIMUM_TIME,
 125    "Minimum execution time in ms of method " + method);
 126  6 addAttribute(
 127    mBeanAttributeInfoList,
 128    method,
 129    Long.class,
 130    DATA_TYPE_MAXIMUM_TIME,
 131    "Maximum execution time in ms of method " + method);
 132   
 133    }
 134  2 mBeanAttributeInfos = (MBeanAttributeInfo[]) mBeanAttributeInfoList
 135    .toArray(new MBeanAttributeInfo[mBeanAttributeInfoList.size()]);
 136    }
 137   
 138    /**
 139    * Creates a new MBean Attribute for a performance counter
 140    */
 141  30 private void addAttribute(List mBeanAttributeInfoList, MethodSignature method,
 142    Class attributeType, String performanceDataType, String description)
 143    {
 144  30 String attributeName = buildAttributeName(method, performanceDataType);
 145  30 MBeanAttributeInfo infoCount = new MBeanAttributeInfo(attributeName, attributeType
 146    .getName(), description, true, false, false);
 147  30 mBeanAttributeInfoList.add(infoCount);
 148    }
 149   
 150    /**
 151    * Builds the attribute name that holds the measurement data of type
 152    * <code>performanceDataType</code> for the method
 153    */
 154  35 protected String buildAttributeName(MethodSignature method, String performanceDataType)
 155    {
 156  35 String attributeName = method.getUniqueId() + DATA_TYPE_SEPARATOR + performanceDataType;
 157  35 return attributeName;
 158    }
 159   
 160    /**
 161    * @see PerformanceCollector#addMeasurement(MethodSignature, long)
 162    */
 163  5 public void addMeasurement(MethodSignature method, long executionTime)
 164    {
 165  5 Counter counter = (Counter) _countersByMethodSignature.get(method);
 166  5 counter.addMeasurement(executionTime);
 167    }
 168   
 169  1 protected MBeanAttributeInfo[] createMBeanAttributeInfo()
 170    {
 171  1 return mBeanAttributeInfos;
 172    }
 173   
 174    /**
 175    * @see AbstractDynamicMBean#getAttribute(java.lang.String)
 176    */
 177  5 public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException,
 178    ReflectionException
 179    {
 180    // Split the attribute to get method id and performance data type separately
 181  5 int posSep = attribute.indexOf(DATA_TYPE_SEPARATOR);
 182  5 String methodId = attribute.substring(0, posSep);
 183  5 String type = attribute
 184    .substring(posSep + DATA_TYPE_SEPARATOR.length(), attribute.length());
 185  5 Counter counter = (Counter) _countersByMethodId.get(methodId);
 186  5 if (type.equals(DATA_TYPE_COUNT))
 187  1 return new Long(counter.count);
 188  4 else if (type.equals(DATA_TYPE_AVERAGE_TIME))
 189  1 return new Long(counter.average);
 190  3 else if (type.equals(DATA_TYPE_LAST_TIME))
 191  1 return new Long(counter.last);
 192  2 else if (type.equals(DATA_TYPE_MINIMUM_TIME))
 193  1 return new Long(counter.min);
 194  1 else if (type.equals(DATA_TYPE_MAXIMUM_TIME))
 195  1 return new Long(counter.max);
 196    else
 197  0 throw new IllegalArgumentException("Unknown performance data type");
 198    }
 199   
 200    }
 201   
 202    /**
 203    * Class that holds and calculates the performance data for a single method
 204    */
 205   
 206    class Counter
 207    {
 208    long count = 0;
 209   
 210    long last = 0;
 211   
 212    long average = 0;
 213   
 214    long max = 0;
 215   
 216    long min = 0;
 217   
 218  0 public String toString()
 219    {
 220  0 return "" + count;
 221    }
 222   
 223    /**
 224    * Should be synchronized, but this could slow things really down
 225    *
 226    * @param executionTime
 227    */
 228  5 public void addMeasurement(long executionTime)
 229    {
 230  5 count++;
 231  5 last = executionTime;
 232    // not an exact value without a complete history and stored as long
 233  5 average = (average * (count - 1) + executionTime) / count;
 234  5 if (executionTime < min || min == 0)
 235  5 min = executionTime;
 236  5 if (executionTime > max || max == 0)
 237  3 max = executionTime;
 238    }
 239    }