1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.hadoop.hbase.regionserver.metrics;
22
23 import java.lang.reflect.Field;
24 import java.lang.reflect.Method;
25 import java.util.Map;
26 import java.util.Map.Entry;
27 import java.util.concurrent.atomic.AtomicInteger;
28 import java.util.concurrent.atomic.AtomicLong;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.hadoop.hbase.regionserver.HRegionServer;
33 import org.apache.hadoop.hbase.util.Pair;
34 import org.apache.hadoop.metrics.MetricsContext;
35 import org.apache.hadoop.metrics.MetricsRecord;
36 import org.apache.hadoop.metrics.MetricsUtil;
37 import org.apache.hadoop.metrics.Updater;
38 import org.apache.hadoop.metrics.util.MetricsBase;
39 import org.apache.hadoop.metrics.util.MetricsLongValue;
40 import org.apache.hadoop.metrics.util.MetricsRegistry;
41 import org.apache.hadoop.metrics.util.MetricsTimeVaryingRate;
42
43
44
45
46
47
48
49
50
51
52
53
54 public class RegionServerDynamicMetrics implements Updater {
55 private static final String UNABLE_TO_CLEAR = "Unable to clear RegionServerDynamicMetrics";
56
57 private MetricsRecord metricsRecord;
58 private MetricsContext context;
59 private final RegionServerDynamicStatistics rsDynamicStatistics;
60 private Method updateMbeanInfoIfMetricsListChanged = null;
61 private HRegionServer regionServer;
62 private static final Log LOG =
63 LogFactory.getLog(RegionServerDynamicStatistics.class);
64
65 private boolean reflectionInitialized = false;
66 private boolean needsUpdateMessage = false;
67 private Field recordMetricMapField;
68 private Field registryMetricMapField;
69
70
71
72
73
74
75 public final MetricsRegistry registry = new MetricsRegistry();
76
77 private RegionServerDynamicMetrics(HRegionServer regionServer) {
78 this.context = MetricsUtil.getContext("hbase");
79 this.metricsRecord = MetricsUtil.createRecord(
80 this.context,
81 "RegionServerDynamicStatistics");
82 context.registerUpdater(this);
83 this.rsDynamicStatistics = new RegionServerDynamicStatistics(this.registry);
84 this.regionServer = regionServer;
85 try {
86 updateMbeanInfoIfMetricsListChanged =
87 this.rsDynamicStatistics.getClass().getSuperclass()
88 .getDeclaredMethod("updateMbeanInfoIfMetricsListChanged",
89 new Class[]{});
90 updateMbeanInfoIfMetricsListChanged.setAccessible(true);
91 } catch (Exception e) {
92 LOG.error(e);
93 }
94 }
95
96 public static RegionServerDynamicMetrics newInstance(HRegionServer regionServer) {
97 RegionServerDynamicMetrics metrics =
98 new RegionServerDynamicMetrics(regionServer);
99 return metrics;
100 }
101
102 public synchronized void setNumericMetric(String name, long amt) {
103 MetricsLongValue m = (MetricsLongValue)registry.get(name);
104 if (m == null) {
105 m = new MetricsLongValue(name, this.registry);
106 this.needsUpdateMessage = true;
107 }
108 m.set(amt);
109 }
110
111 public synchronized void incrTimeVaryingMetric(
112 String name,
113 long amt,
114 int numOps) {
115 MetricsTimeVaryingRate m = (MetricsTimeVaryingRate)registry.get(name);
116 if (m == null) {
117 m = new MetricsTimeVaryingRate(name, this.registry);
118 this.needsUpdateMessage = true;
119 }
120 if (numOps > 0) {
121 m.inc(numOps, amt);
122 }
123 }
124
125
126
127
128
129 @SuppressWarnings("rawtypes")
130 public void clear() {
131 this.needsUpdateMessage = true;
132
133
134
135
136 if (!this.reflectionInitialized) {
137 this.reflectionInitialized = true;
138 try {
139 this.recordMetricMapField = this.metricsRecord.getClass().getDeclaredField("metricTable");
140 this.recordMetricMapField.setAccessible(true);
141 } catch (SecurityException e) {
142 LOG.debug(UNABLE_TO_CLEAR);
143 return;
144 } catch (NoSuchFieldException e) {
145 LOG.debug(UNABLE_TO_CLEAR);
146 return;
147 }
148
149 try {
150 this.registryMetricMapField = this.registry.getClass().getDeclaredField("metricsList");
151 this.registryMetricMapField.setAccessible(true);
152 } catch (SecurityException e) {
153 LOG.debug(UNABLE_TO_CLEAR);
154 return;
155 } catch (NoSuchFieldException e) {
156 LOG.debug(UNABLE_TO_CLEAR);
157 return;
158 }
159 }
160
161
162
163 if (this.recordMetricMapField != null && this.registryMetricMapField != null) {
164 try {
165 Map recordMap = (Map) this.recordMetricMapField.get(this.metricsRecord);
166 recordMap.clear();
167 Map registryMap = (Map) this.registryMetricMapField.get(this.registry);
168 registryMap.clear();
169 } catch (IllegalArgumentException e) {
170 LOG.debug(UNABLE_TO_CLEAR);
171 } catch (IllegalAccessException e) {
172 LOG.debug(UNABLE_TO_CLEAR);
173 }
174 } else {
175 LOG.debug(UNABLE_TO_CLEAR);
176 }
177 }
178
179
180
181
182
183 public void doUpdates(MetricsContext context) {
184
185 for (Entry<String, AtomicLong> entry : RegionMetricsStorage.getNumericMetrics().entrySet()) {
186 this.setNumericMetric(entry.getKey(), entry.getValue().getAndSet(0));
187 }
188
189
190 if (regionServer != null) {
191 long responseQueueSize = regionServer.getResponseQueueSize();
192 this.setNumericMetric("responseQueuesSize", responseQueueSize);
193 }
194
195
196
197 for (Entry<String, AtomicLong> entry : RegionMetricsStorage.getNumericPersistentMetrics().entrySet()) {
198 this.setNumericMetric(entry.getKey(), entry.getValue().get());
199 }
200
201 for (Entry<String, Pair<AtomicLong, AtomicInteger>> entry :
202 RegionMetricsStorage.getTimeVaryingMetrics().entrySet()) {
203 Pair<AtomicLong, AtomicInteger> value = entry.getValue();
204 this.incrTimeVaryingMetric(entry.getKey(),
205 value.getFirst().getAndSet(0),
206 value.getSecond().getAndSet(0));
207 }
208
209
210
211 if (needsUpdateMessage) {
212 try {
213 if (updateMbeanInfoIfMetricsListChanged != null) {
214 updateMbeanInfoIfMetricsListChanged.invoke(this.rsDynamicStatistics,
215 new Object[]{});
216 }
217 } catch (Exception e) {
218 LOG.error(e);
219 }
220 needsUpdateMessage = false;
221 }
222
223
224 synchronized (registry) {
225
226 for (String metricName : registry.getKeyList() ) {
227 MetricsBase value = registry.get(metricName);
228 value.pushMetric(metricsRecord);
229 }
230 }
231 metricsRecord.update();
232 }
233
234 public void shutdown() {
235 if (rsDynamicStatistics != null)
236 rsDynamicStatistics.shutdown();
237 }
238 }