1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.metrics;
21
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26
27 import javax.management.AttributeNotFoundException;
28 import javax.management.MBeanAttributeInfo;
29 import javax.management.MBeanException;
30 import javax.management.MBeanInfo;
31 import javax.management.ReflectionException;
32 import org.apache.hadoop.hbase.metrics.histogram.MetricsHistogram;
33
34 import com.yammer.metrics.stats.Snapshot;
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.apache.hadoop.metrics.util.MetricsBase;
38 import org.apache.hadoop.metrics.util.MetricsDynamicMBeanBase;
39 import org.apache.hadoop.metrics.util.MetricsRegistry;
40
41
42
43
44
45
46
47
48 public class MetricsMBeanBase extends MetricsDynamicMBeanBase {
49
50 private static final Log LOG = LogFactory.getLog("org.apache.hadoop.hbase.metrics");
51
52 protected final MetricsRegistry registry;
53 protected final String description;
54 protected int registryLength;
55
56
57
58 protected Map<String,MetricsBase> extendedAttributes =
59 new HashMap<String,MetricsBase>();
60 protected MBeanInfo extendedInfo;
61
62 protected MetricsMBeanBase( MetricsRegistry mr, String description ) {
63 super(copyMinusHBaseMetrics(mr), description);
64 this.registry = mr;
65 this.description = description;
66 this.init();
67 }
68
69
70
71
72
73 private static MetricsRegistry copyMinusHBaseMetrics(final MetricsRegistry mr) {
74 MetricsRegistry copy = new MetricsRegistry();
75 for (MetricsBase metric : mr.getMetricsList()) {
76 if (metric instanceof MetricsRate || metric instanceof MetricsString ||
77 metric instanceof MetricsHistogram || metric instanceof ExactCounterMetric) {
78 continue;
79 }
80 copy.add(metric.getName(), metric);
81 }
82 return copy;
83 }
84
85 protected void init() {
86 List<MBeanAttributeInfo> attributes = new ArrayList<MBeanAttributeInfo>();
87 MBeanInfo parentInfo = super.getMBeanInfo();
88 List<String> parentAttributes = new ArrayList<String>();
89 for (MBeanAttributeInfo attr : parentInfo.getAttributes()) {
90 attributes.add(attr);
91 parentAttributes.add(attr.getName());
92 }
93
94 this.registryLength = this.registry.getMetricsList().size();
95
96 for (MetricsBase metric : this.registry.getMetricsList()) {
97 if (metric.getName() == null || parentAttributes.contains(metric.getName()))
98 continue;
99
100
101 if (metric instanceof MetricsRate) {
102 attributes.add( new MBeanAttributeInfo(metric.getName(),
103 "java.lang.Float", metric.getDescription(), true, false, false) );
104 extendedAttributes.put(metric.getName(), metric);
105 } else if (metric instanceof MetricsString) {
106 attributes.add( new MBeanAttributeInfo(metric.getName(),
107 "java.lang.String", metric.getDescription(), true, false, false) );
108 extendedAttributes.put(metric.getName(), metric);
109 LOG.info("MetricsString added: " + metric.getName());
110 } else if (metric instanceof MetricsHistogram) {
111
112 String metricName = metric.getName() + MetricsHistogram.NUM_OPS_METRIC_NAME;
113 attributes.add(new MBeanAttributeInfo(metricName,
114 "java.lang.Long", metric.getDescription(), true, false, false));
115 extendedAttributes.put(metricName, metric);
116
117 metricName = metric.getName() + MetricsHistogram.MIN_METRIC_NAME;
118 attributes.add(new MBeanAttributeInfo(metricName,
119 "java.lang.Long", metric.getDescription(), true, false, false));
120 extendedAttributes.put(metricName, metric);
121
122 metricName = metric.getName() + MetricsHistogram.MAX_METRIC_NAME;
123 attributes.add(new MBeanAttributeInfo(metricName,
124 "java.lang.Long", metric.getDescription(), true, false, false));
125 extendedAttributes.put(metricName, metric);
126
127 metricName = metric.getName() + MetricsHistogram.MEAN_METRIC_NAME;
128 attributes.add(new MBeanAttributeInfo(metricName,
129 "java.lang.Float", metric.getDescription(), true, false, false));
130 extendedAttributes.put(metricName, metric);
131
132 metricName = metric.getName() + MetricsHistogram.STD_DEV_METRIC_NAME;
133 attributes.add(new MBeanAttributeInfo(metricName,
134 "java.lang.Float", metric.getDescription(), true, false, false));
135 extendedAttributes.put(metricName, metric);
136
137 metricName = metric.getName() + MetricsHistogram.MEDIAN_METRIC_NAME;
138 attributes.add(new MBeanAttributeInfo(metricName,
139 "java.lang.Float", metric.getDescription(), true, false, false));
140 extendedAttributes.put(metricName, metric);
141
142 metricName = metric.getName() + MetricsHistogram.SEVENTY_FIFTH_PERCENTILE_METRIC_NAME;
143 attributes.add(new MBeanAttributeInfo(metricName,
144 "java.lang.Float", metric.getDescription(), true, false, false));
145 extendedAttributes.put(metricName, metric);
146
147 metricName = metric.getName() + MetricsHistogram.NINETY_FIFTH_PERCENTILE_METRIC_NAME;
148 attributes.add(new MBeanAttributeInfo(metricName,
149 "java.lang.Float", metric.getDescription(), true, false, false));
150 extendedAttributes.put(metricName, metric);
151
152 metricName = metric.getName() + MetricsHistogram.NINETY_NINETH_PERCENTILE_METRIC_NAME;
153 attributes.add(new MBeanAttributeInfo(metricName,
154 "java.lang.Float", metric.getDescription(), true, false, false));
155 extendedAttributes.put(metricName, metric);
156 }
157
158 }
159
160 LOG.info("new MBeanInfo");
161 this.extendedInfo = new MBeanInfo( this.getClass().getName(),
162 this.description, attributes.toArray( new MBeanAttributeInfo[0] ),
163 parentInfo.getConstructors(), parentInfo.getOperations(),
164 parentInfo.getNotifications() );
165 }
166
167 private void checkAndUpdateAttributes() {
168 if (this.registryLength != this.registry.getMetricsList().size())
169 this.init();
170 }
171
172 @Override
173 public Object getAttribute( String name )
174 throws AttributeNotFoundException, MBeanException,
175 ReflectionException {
176
177 if (name == null) {
178 throw new IllegalArgumentException("Attribute name is NULL");
179 }
180
181
182
183
184
185
186
187
188 try {
189 return super.getAttribute(name);
190 } catch (AttributeNotFoundException ex) {
191
192 checkAndUpdateAttributes();
193
194 MetricsBase metric = this.extendedAttributes.get(name);
195 if (metric != null) {
196 if (metric instanceof MetricsRate) {
197 return ((MetricsRate) metric).getPreviousIntervalValue();
198 } else if (metric instanceof MetricsString) {
199 return ((MetricsString)metric).getValue();
200 } else if (metric instanceof MetricsHistogram) {
201 MetricsHistogram hist = (MetricsHistogram) metric;
202 if (name.endsWith(MetricsHistogram.NUM_OPS_METRIC_NAME)) {
203 return hist.getCount();
204 } else if (name.endsWith(MetricsHistogram.MIN_METRIC_NAME)) {
205 return hist.getMin();
206 } else if (name.endsWith(MetricsHistogram.MAX_METRIC_NAME)) {
207 return hist.getMax();
208 } else if (name.endsWith(MetricsHistogram.MEAN_METRIC_NAME)) {
209 return (float) hist.getMean();
210 } else if (name.endsWith(MetricsHistogram.STD_DEV_METRIC_NAME)) {
211 return (float) hist.getStdDev();
212 } else if (name.endsWith(MetricsHistogram.MEDIAN_METRIC_NAME)) {
213 Snapshot s = hist.getSnapshot();
214 return (float) s.getMedian();
215 } else if (name.endsWith(MetricsHistogram.SEVENTY_FIFTH_PERCENTILE_METRIC_NAME)) {
216 Snapshot s = hist.getSnapshot();
217 return (float) s.get75thPercentile();
218 } else if (name.endsWith(MetricsHistogram.NINETY_FIFTH_PERCENTILE_METRIC_NAME)) {
219 Snapshot s = hist.getSnapshot();
220 return (float) s.get95thPercentile();
221 } else if (name.endsWith(MetricsHistogram.NINETY_NINETH_PERCENTILE_METRIC_NAME)) {
222 Snapshot s = hist.getSnapshot();
223 return (float) s.get99thPercentile();
224 }
225
226 } else {
227 LOG.warn( String.format("unknown metrics type %s for attribute %s",
228 metric.getClass().getName(), name) );
229 }
230 }
231 }
232
233 throw new AttributeNotFoundException();
234 }
235
236 @Override
237 public MBeanInfo getMBeanInfo() {
238 return this.extendedInfo;
239 }
240
241 }