source: proiecte/HadoopJUnit/hadoop-0.20.1/src/core/org/apache/hadoop/metrics/util/MetricsDynamicMBeanBase.java @ 120

Last change on this file since 120 was 120, checked in by (none), 14 years ago

Added the mail files for the Hadoop JUNit Project

  • Property svn:executable set to *
File size: 8.9 KB
Line 
1/**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements.  See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership.  The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License.  You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18package org.apache.hadoop.metrics.util;
19
20import java.util.ArrayList;
21import java.util.HashMap;
22import java.util.List;
23import java.util.Map;
24
25import javax.management.Attribute;
26import javax.management.AttributeList;
27import javax.management.AttributeNotFoundException;
28import javax.management.DynamicMBean;
29import javax.management.InvalidAttributeValueException;
30import javax.management.MBeanAttributeInfo;
31import javax.management.MBeanException;
32import javax.management.MBeanInfo;
33import javax.management.MBeanOperationInfo;
34import javax.management.ReflectionException;
35
36import org.apache.hadoop.metrics.MetricsUtil;
37
38
39
40/**
41 * This abstract base class facilitates creating dynamic mbeans automatically from
42 * metrics.
43 * The metrics constructors registers metrics in a registry.
44 * Different categories of metrics should be in differnt classes with their own
45 * registry (as in NameNodeMetrics and DataNodeMetrics).
46 * Then the MBean can be created passing the registry to the constructor.
47 * The MBean should be then registered using a mbean name (example):
48 *  MetricsHolder myMetrics = new MetricsHolder(); // has metrics and registry
49 *  MetricsTestMBean theMBean = new MetricsTestMBean(myMetrics.mregistry);
50 *  ObjectName mbeanName = MBeanUtil.registerMBean("ServiceFoo",
51 *                "TestStatistics", theMBean);
52 *
53 *
54 */
55public abstract class MetricsDynamicMBeanBase implements DynamicMBean {
56  private final static String AVG_TIME = "AvgTime";
57  private final static String MIN_TIME = "MinTime";
58  private final static String MAX_TIME = "MaxTime";
59  private final static String NUM_OPS = "NumOps";
60  private final static String RESET_ALL_MIN_MAX_OP = "resetAllMinMax";
61  private MetricsRegistry metricsRegistry;
62  private MBeanInfo mbeanInfo;
63  private Map<String, MetricsBase> metricsRateAttributeMod;
64  private int numEntriesInRegistry = 0;
65  private String mbeanDescription;
66 
67  protected MetricsDynamicMBeanBase(final MetricsRegistry mr, final String aMBeanDescription) {
68    metricsRegistry = mr;
69    mbeanDescription = aMBeanDescription;
70    createMBeanInfo();
71  }
72 
73  private void updateMbeanInfoIfMetricsListChanged()  {
74    if (numEntriesInRegistry != metricsRegistry.size())
75      createMBeanInfo();
76  }
77 
78  private void createMBeanInfo() {
79    metricsRateAttributeMod = new HashMap<String, MetricsBase>();
80    boolean needsMinMaxResetOperation = false;
81    List<MBeanAttributeInfo> attributesInfo = new ArrayList<MBeanAttributeInfo>();
82    MBeanOperationInfo[] operationsInfo = null;
83    numEntriesInRegistry = metricsRegistry.size();
84   
85    for (MetricsBase o : metricsRegistry.getMetricsList()) {
86
87      if (MetricsTimeVaryingRate.class.isInstance(o)) {
88        // For each of the metrics there are 3 different attributes
89        attributesInfo.add(new MBeanAttributeInfo(o.getName() + NUM_OPS, "java.lang.Integer",
90            o.getDescription(), true, false, false));
91        attributesInfo.add(new MBeanAttributeInfo(o.getName() + AVG_TIME, "java.lang.Long",
92            o.getDescription(), true, false, false));
93        attributesInfo.add(new MBeanAttributeInfo(o.getName() + MIN_TIME, "java.lang.Long",
94            o.getDescription(), true, false, false));
95        attributesInfo.add(new MBeanAttributeInfo(o.getName() + MAX_TIME, "java.lang.Long",
96            o.getDescription(), true, false, false));
97        needsMinMaxResetOperation = true;  // the min and max can be reset.
98       
99        // Note the special attributes (AVG_TIME, MIN_TIME, ..) are derived from metrics
100        // Rather than check for the suffix we store them in a map.
101        metricsRateAttributeMod.put(o.getName() + NUM_OPS, o);
102        metricsRateAttributeMod.put(o.getName() + AVG_TIME, o);
103        metricsRateAttributeMod.put(o.getName() + MIN_TIME, o);
104        metricsRateAttributeMod.put(o.getName() + MAX_TIME, o);
105       
106      }  else if ( MetricsIntValue.class.isInstance(o) || MetricsTimeVaryingInt.class.isInstance(o) ) {
107        attributesInfo.add(new MBeanAttributeInfo(o.getName(), "java.lang.Integer",
108            o.getDescription(), true, false, false)); 
109      } else if ( MetricsLongValue.class.isInstance(o) || MetricsTimeVaryingLong.class.isInstance(o) ) {
110        attributesInfo.add(new MBeanAttributeInfo(o.getName(), "java.lang.Long",
111            o.getDescription(), true, false, false));     
112      } else {
113        MetricsUtil.LOG.error("unknown metrics type: " + o.getClass().getName());
114      }
115
116      if (needsMinMaxResetOperation) {
117        operationsInfo = new MBeanOperationInfo[] {
118            new MBeanOperationInfo(RESET_ALL_MIN_MAX_OP, "Reset (zero) All Min Max",
119                    null, "void", MBeanOperationInfo.ACTION) };
120      }
121    }
122    MBeanAttributeInfo[] attrArray = new MBeanAttributeInfo[attributesInfo.size()];
123    mbeanInfo =  new MBeanInfo(this.getClass().getName(), mbeanDescription, 
124        attributesInfo.toArray(attrArray), null, operationsInfo, null);
125  }
126 
127  @Override
128  public Object getAttribute(String attributeName) throws AttributeNotFoundException,
129      MBeanException, ReflectionException {
130    if (attributeName == null || attributeName.equals("")) 
131      throw new IllegalArgumentException();
132   
133    updateMbeanInfoIfMetricsListChanged();
134   
135    Object o = metricsRateAttributeMod.get(attributeName);
136    if (o == null) {
137      o = metricsRegistry.get(attributeName);
138    }
139    if (o == null)
140      throw new AttributeNotFoundException();
141   
142    if (o instanceof MetricsIntValue)
143      return ((MetricsIntValue) o).get();
144    else if (o instanceof MetricsLongValue)
145      return ((MetricsLongValue) o).get();
146    else if (o instanceof MetricsTimeVaryingInt)
147      return ((MetricsTimeVaryingInt) o).getPreviousIntervalValue();
148    else if (o instanceof MetricsTimeVaryingLong)
149      return ((MetricsTimeVaryingLong) o).getPreviousIntervalValue();
150    else if (o instanceof MetricsTimeVaryingRate) {
151      MetricsTimeVaryingRate or = (MetricsTimeVaryingRate) o;
152      if (attributeName.endsWith(NUM_OPS))
153        return or.getPreviousIntervalNumOps();
154      else if (attributeName.endsWith(AVG_TIME))
155        return or.getPreviousIntervalAverageTime();
156      else if (attributeName.endsWith(MIN_TIME))
157        return or.getMinTime();
158      else if (attributeName.endsWith(MAX_TIME))
159        return or.getMaxTime();
160      else {
161        MetricsUtil.LOG.error("Unexpected attrubute suffix");
162        throw new AttributeNotFoundException();
163      }
164    } else {
165        MetricsUtil.LOG.error("unknown metrics type: " + o.getClass().getName());
166        throw new AttributeNotFoundException();
167    }
168  }
169
170  @Override
171  public AttributeList getAttributes(String[] attributeNames) {
172    if (attributeNames == null || attributeNames.length == 0) 
173      throw new IllegalArgumentException();
174   
175    updateMbeanInfoIfMetricsListChanged();
176   
177    AttributeList result = new AttributeList(attributeNames.length);
178    for (String iAttributeName : attributeNames) {
179      try {
180        Object value = getAttribute(iAttributeName);
181        result.add(new Attribute(iAttributeName, value));
182      } catch (Exception e) {
183        continue;
184      } 
185    }
186    return result;
187  }
188
189  @Override
190  public MBeanInfo getMBeanInfo() {
191    return mbeanInfo;
192  }
193
194  @Override
195  public Object invoke(String actionName, Object[] parms, String[] signature)
196      throws MBeanException, ReflectionException {
197   
198    if (actionName == null || actionName.equals("")) 
199      throw new IllegalArgumentException();
200   
201   
202    // Right now we support only one fixed operation (if it applies)
203    if (!(actionName.equals(RESET_ALL_MIN_MAX_OP)) || 
204        mbeanInfo.getOperations().length != 1) {
205      throw new ReflectionException(new NoSuchMethodException(actionName));
206    }
207    for (MetricsBase m : metricsRegistry.getMetricsList())  {
208      if ( MetricsTimeVaryingRate.class.isInstance(m) ) {
209        MetricsTimeVaryingRate.class.cast(m).resetMinMax();
210      }
211    }
212    return null;
213  }
214
215  @Override
216  public void setAttribute(Attribute attribute)
217      throws AttributeNotFoundException, InvalidAttributeValueException,
218      MBeanException, ReflectionException {
219    throw new ReflectionException(new NoSuchMethodException("set" + attribute));
220  }
221
222  @Override
223  public AttributeList setAttributes(AttributeList attributes) {
224    return null;
225  }
226}
Note: See TracBrowser for help on using the repository browser.