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