1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.metrics2.lib;
20
21 import java.util.Collection;
22 import java.util.concurrent.ConcurrentMap;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.apache.hadoop.hbase.classification.InterfaceAudience;
27 import org.apache.hadoop.metrics2.MetricsException;
28 import org.apache.hadoop.metrics2.MetricsInfo;
29 import org.apache.hadoop.metrics2.MetricsRecordBuilder;
30 import org.apache.hadoop.metrics2.MetricsTag;
31 import org.apache.hadoop.metrics2.impl.MsInfo;
32
33 import com.google.common.base.Objects;
34 import com.google.common.collect.Maps;
35
36
37
38
39
40
41
42
43
44
45
46
47 @InterfaceAudience.Private
48 public class DynamicMetricsRegistry {
49 private static final Log LOG = LogFactory.getLog(DynamicMetricsRegistry.class);
50
51 private final ConcurrentMap<String, MutableMetric> metricsMap =
52 Maps.newConcurrentMap();
53 private final ConcurrentMap<String, MetricsTag> tagsMap =
54 Maps.newConcurrentMap();
55 private final MetricsInfo metricsInfo;
56 private final DefaultMetricsSystemHelper helper = new DefaultMetricsSystemHelper();
57 private final static String[] histogramSuffixes = new String[]{
58 "_num_ops",
59 "_min",
60 "_max",
61 "_median",
62 "_75th_percentile",
63 "_90th_percentile",
64 "_95th_percentile",
65 "_99th_percentile"};
66
67
68
69
70
71 public DynamicMetricsRegistry(String name) {
72 this(Interns.info(name,name));
73 }
74
75
76
77
78
79 public DynamicMetricsRegistry(MetricsInfo info) {
80 metricsInfo = info;
81 }
82
83
84
85
86 public MetricsInfo info() {
87 return metricsInfo;
88 }
89
90
91
92
93
94
95 public MutableMetric get(String name) {
96 return metricsMap.get(name);
97 }
98
99
100
101
102
103
104 public MetricsTag getTag(String name) {
105 return tagsMap.get(name);
106 }
107
108
109
110
111
112
113
114
115 public MutableFastCounter newCounter(String name, String desc, long iVal) {
116 return newCounter(new MetricsInfoImpl(name, desc), iVal);
117 }
118
119
120
121
122
123
124
125 public MutableFastCounter newCounter(MetricsInfo info, long iVal) {
126 MutableFastCounter ret = new MutableFastCounter(info, iVal);
127 return addNewMetricIfAbsent(info.name(), ret, MutableFastCounter.class);
128 }
129
130
131
132
133
134
135
136
137 public MutableGaugeLong newGauge(String name, String desc, long iVal) {
138 return newGauge(new MetricsInfoImpl(name, desc), iVal);
139 }
140
141
142
143
144
145
146
147 public MutableGaugeLong newGauge(MetricsInfo info, long iVal) {
148 MutableGaugeLong ret = new MutableGaugeLong(info, iVal);
149 return addNewMetricIfAbsent(info.name(), ret, MutableGaugeLong.class);
150 }
151
152
153
154
155
156
157
158
159
160
161 public MutableStat newStat(String name, String desc,
162 String sampleName, String valueName, boolean extended) {
163 MutableStat ret =
164 new MutableStat(name, desc, sampleName, valueName, extended);
165 return addNewMetricIfAbsent(name, ret, MutableStat.class);
166 }
167
168
169
170
171
172
173
174
175
176 public MutableStat newStat(String name, String desc,
177 String sampleName, String valueName) {
178 return newStat(name, desc, sampleName, valueName, false);
179 }
180
181
182
183
184
185
186 public MutableRate newRate(String name) {
187 return newRate(name, name, false);
188 }
189
190
191
192
193
194
195
196 public MutableRate newRate(String name, String description) {
197 return newRate(name, description, false);
198 }
199
200
201
202
203
204
205
206
207 public MutableRate newRate(String name, String desc, boolean extended) {
208 return newRate(name, desc, extended, true);
209 }
210
211 @InterfaceAudience.Private
212 public MutableRate newRate(String name, String desc,
213 boolean extended, boolean returnExisting) {
214 if (returnExisting) {
215 MutableMetric rate = metricsMap.get(name);
216 if (rate != null) {
217 if (rate instanceof MutableRate) return (MutableRate) rate;
218 throw new MetricsException("Unexpected metrics type "+ rate.getClass()
219 +" for "+ name);
220 }
221 }
222 MutableRate ret = new MutableRate(name, desc, extended);
223 return addNewMetricIfAbsent(name, ret, MutableRate.class);
224 }
225
226
227
228
229
230
231 public MutableHistogram newHistogram(String name) {
232 return newHistogram(name, "");
233 }
234
235
236
237
238
239
240
241 public MutableHistogram newHistogram(String name, String desc) {
242 MutableHistogram histo = new MutableHistogram(name, desc);
243 return addNewMetricIfAbsent(name, histo, MutableHistogram.class);
244 }
245
246
247
248
249
250
251 public MutableTimeHistogram newTimeHistogram(String name) {
252 return newTimeHistogram(name, "");
253 }
254
255
256
257
258
259
260
261 public MutableTimeHistogram newTimeHistogram(String name, String desc) {
262 MutableTimeHistogram histo = new MutableTimeHistogram(name, desc);
263 return addNewMetricIfAbsent(name, histo, MutableTimeHistogram.class);
264 }
265
266
267
268
269
270
271 public MutableSizeHistogram newSizeHistogram(String name) {
272 return newSizeHistogram(name, "");
273 }
274
275
276
277
278
279
280
281 public MutableSizeHistogram newSizeHistogram(String name, String desc) {
282 MutableSizeHistogram histo = new MutableSizeHistogram(name, desc);
283 return addNewMetricIfAbsent(name, histo, MutableSizeHistogram.class);
284 }
285
286
287 synchronized void add(String name, MutableMetric metric) {
288 addNewMetricIfAbsent(name, metric, MutableMetric.class);
289 }
290
291
292
293
294
295
296 public void add(String name, long value) {
297 MutableMetric m = metricsMap.get(name);
298
299 if (m != null) {
300 if (m instanceof MutableStat) {
301 ((MutableStat) m).add(value);
302 }
303 else {
304 throw new MetricsException("Unsupported add(value) for metric "+ name);
305 }
306 }
307 else {
308 metricsMap.put(name, newRate(name));
309 add(name, value);
310 }
311 }
312
313
314
315
316
317
318 public DynamicMetricsRegistry setContext(String name) {
319 return tag(MsInfo.Context, name, true);
320 }
321
322
323
324
325
326
327
328
329 public DynamicMetricsRegistry tag(String name, String description, String value) {
330 return tag(name, description, value, false);
331 }
332
333
334
335
336
337
338
339
340
341 public DynamicMetricsRegistry tag(String name, String description, String value,
342 boolean override) {
343 return tag(new MetricsInfoImpl(name, description), value, override);
344 }
345
346
347
348
349
350
351
352
353 public DynamicMetricsRegistry tag(MetricsInfo info, String value, boolean override) {
354 MetricsTag tag = Interns.tag(info, value);
355
356 if (!override) {
357 MetricsTag existing = tagsMap.putIfAbsent(info.name(), tag);
358 if (existing != null) {
359 throw new MetricsException("Tag "+ info.name() +" already exists!");
360 }
361 return this;
362 }
363
364 tagsMap.put(info.name(), tag);
365
366 return this;
367 }
368
369 public DynamicMetricsRegistry tag(MetricsInfo info, String value) {
370 return tag(info, value, false);
371 }
372
373 Collection<MetricsTag> tags() {
374 return tagsMap.values();
375 }
376
377 Collection<MutableMetric> metrics() {
378 return metricsMap.values();
379 }
380
381
382
383
384
385
386 public void snapshot(MetricsRecordBuilder builder, boolean all) {
387 for (MetricsTag tag : tags()) {
388 builder.add(tag);
389 }
390 for (MutableMetric metric : metrics()) {
391 metric.snapshot(builder, all);
392 }
393 }
394
395 @Override public String toString() {
396 return Objects.toStringHelper(this)
397 .add("info", metricsInfo).add("tags", tags()).add("metrics", metrics())
398 .toString();
399 }
400
401
402
403
404
405 public void removeMetric(String name) {
406 helper.removeObjectName(name);
407 metricsMap.remove(name);
408 }
409
410 public void removeHistogramMetrics(String baseName) {
411 for (String suffix:histogramSuffixes) {
412 removeMetric(baseName+suffix);
413 }
414 }
415
416
417
418
419
420
421
422 public MutableGaugeLong getGauge(String gaugeName, long potentialStartingValue) {
423
424 MutableMetric metric = metricsMap.get(gaugeName);
425
426
427 if (metric == null) {
428
429
430 MutableGaugeLong newGauge = new MutableGaugeLong(new MetricsInfoImpl(gaugeName, ""),
431 potentialStartingValue);
432
433
434 metric = metricsMap.putIfAbsent(gaugeName, newGauge);
435
436
437
438 if (metric == null) {
439 return newGauge;
440 }
441 }
442
443 if (!(metric instanceof MutableGaugeLong)) {
444 throw new MetricsException("Metric already exists in registry for metric name: " + gaugeName +
445 " and not of type MetricMutableGaugeLong");
446 }
447
448 return (MutableGaugeLong) metric;
449 }
450
451
452
453
454
455
456
457 public MutableFastCounter getCounter(String counterName, long potentialStartingValue) {
458
459 MutableMetric counter = metricsMap.get(counterName);
460 if (counter == null) {
461 MutableFastCounter newCounter =
462 new MutableFastCounter(new MetricsInfoImpl(counterName, ""), potentialStartingValue);
463 counter = metricsMap.putIfAbsent(counterName, newCounter);
464 if (counter == null) {
465 return newCounter;
466 }
467 }
468
469
470 if (!(counter instanceof MutableCounter)) {
471 throw new MetricsException("Metric already exists in registry for metric name: " +
472 counterName + " and not of type MutableCounter");
473 }
474
475 return (MutableFastCounter) counter;
476 }
477
478 public MutableHistogram getHistogram(String histoName) {
479
480 MutableMetric histo = metricsMap.get(histoName);
481 if (histo == null) {
482 MutableHistogram newCounter =
483 new MutableHistogram(new MetricsInfoImpl(histoName, ""));
484 histo = metricsMap.putIfAbsent(histoName, newCounter);
485 if (histo == null) {
486 return newCounter;
487 }
488 }
489
490
491 if (!(histo instanceof MutableHistogram)) {
492 throw new MetricsException("Metric already exists in registry for metric name: " +
493 histoName + " and not of type MutableHistogram");
494 }
495
496 return (MutableHistogram) histo;
497 }
498
499 private<T extends MutableMetric> T
500 addNewMetricIfAbsent(String name,
501 T ret,
502 Class<T> metricClass) {
503
504
505
506 MutableMetric metric = metricsMap.putIfAbsent(name, ret);
507 if (metric == null) {
508 return ret;
509 }
510
511 return returnExistingWithCast(metric, metricClass, name);
512 }
513
514 @SuppressWarnings("unchecked")
515 private<T> T returnExistingWithCast(MutableMetric metric,
516 Class<T> metricClass, String name) {
517 if (!metricClass.isAssignableFrom(metric.getClass())) {
518 throw new MetricsException("Metric already exists in registry for metric name: " +
519 name + " and not of type " + metricClass +
520 " but instead of type " + metric.getClass());
521 }
522
523 return (T) metric;
524 }
525
526 public void clearMetrics() {
527 for (String name:metricsMap.keySet()) {
528 helper.removeObjectName(name);
529 }
530 metricsMap.clear();
531 }
532 }