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