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 MetricMutableQuantiles newQuantile(String name) {
281 return newQuantile(name, "");
282 }
283
284 public MetricMutableQuantiles newQuantile(String name, String desc) {
285 MetricMutableQuantiles histo = new MetricMutableQuantiles(name, desc, "Ops", "", 60);
286 return addNewMetricIfAbsent(name, histo, MetricMutableQuantiles.class);
287 }
288
289 synchronized void add(String name, MutableMetric metric) {
290 addNewMetricIfAbsent(name, metric, MutableMetric.class);
291 }
292
293
294
295
296
297
298 public void add(String name, long value) {
299 MutableMetric m = metricsMap.get(name);
300
301 if (m != null) {
302 if (m instanceof MutableStat) {
303 ((MutableStat) m).add(value);
304 }
305 else {
306 throw new MetricsException("Unsupported add(value) for metric "+ name);
307 }
308 }
309 else {
310 metricsMap.put(name, newRate(name));
311 add(name, value);
312 }
313 }
314
315
316
317
318
319
320 public DynamicMetricsRegistry setContext(String name) {
321 return tag(MsInfo.Context, name, true);
322 }
323
324
325
326
327
328
329
330
331 public DynamicMetricsRegistry tag(String name, String description, String value) {
332 return tag(name, description, value, false);
333 }
334
335
336
337
338
339
340
341
342
343 public DynamicMetricsRegistry tag(String name, String description, String value,
344 boolean override) {
345 return tag(new MetricsInfoImpl(name, description), value, override);
346 }
347
348
349
350
351
352
353
354
355 public DynamicMetricsRegistry tag(MetricsInfo info, String value, boolean override) {
356 MetricsTag tag = Interns.tag(info, value);
357
358 if (!override) {
359 MetricsTag existing = tagsMap.putIfAbsent(info.name(), tag);
360 if (existing != null) {
361 throw new MetricsException("Tag "+ info.name() +" already exists!");
362 }
363 return this;
364 }
365
366 tagsMap.put(info.name(), tag);
367
368 return this;
369 }
370
371 public DynamicMetricsRegistry tag(MetricsInfo info, String value) {
372 return tag(info, value, false);
373 }
374
375 Collection<MetricsTag> tags() {
376 return tagsMap.values();
377 }
378
379 Collection<MutableMetric> metrics() {
380 return metricsMap.values();
381 }
382
383
384
385
386
387
388 public void snapshot(MetricsRecordBuilder builder, boolean all) {
389 for (MetricsTag tag : tags()) {
390 builder.add(tag);
391 }
392 for (MutableMetric metric : metrics()) {
393 metric.snapshot(builder, all);
394 }
395 }
396
397 @Override public String toString() {
398 return Objects.toStringHelper(this)
399 .add("info", metricsInfo).add("tags", tags()).add("metrics", metrics())
400 .toString();
401 }
402
403
404
405
406
407 public void removeMetric(String name) {
408 metricsMap.remove(name);
409 }
410
411
412
413
414
415
416
417 public MutableGaugeLong getLongGauge(String gaugeName, long potentialStartingValue) {
418
419 MutableMetric metric = metricsMap.get(gaugeName);
420
421
422 if (metric == null) {
423
424
425 MutableGaugeLong newGauge = new MutableGaugeLong(new MetricsInfoImpl(gaugeName, ""),
426 potentialStartingValue);
427
428
429 metric = metricsMap.putIfAbsent(gaugeName, newGauge);
430
431
432
433 if (metric == null) {
434 return newGauge;
435 }
436 }
437
438 if (!(metric instanceof MutableGaugeLong)) {
439 throw new MetricsException("Metric already exists in registry for metric name: " + gaugeName +
440 " and not of type MetricMutableGaugeLong");
441 }
442
443 return (MutableGaugeLong) metric;
444 }
445
446
447
448
449
450
451
452 public MutableCounterLong getLongCounter(String counterName, long potentialStartingValue) {
453
454 MutableMetric counter = metricsMap.get(counterName);
455 if (counter == null) {
456 MutableCounterLong newCounter =
457 new MutableCounterLong(new MetricsInfoImpl(counterName, ""), potentialStartingValue);
458 counter = metricsMap.putIfAbsent(counterName, newCounter);
459 if (counter == null) {
460 return newCounter;
461 }
462 }
463
464
465 if (!(counter instanceof MutableCounterLong)) {
466 throw new MetricsException("Metric already exists in registry for metric name: " +
467 counterName + " and not of type MetricMutableCounterLong");
468 }
469
470 return (MutableCounterLong) counter;
471 }
472
473 public MutableHistogram getHistogram(String histoName) {
474
475 MutableMetric histo = metricsMap.get(histoName);
476 if (histo == null) {
477 MutableHistogram newCounter =
478 new MutableHistogram(new MetricsInfoImpl(histoName, ""));
479 histo = metricsMap.putIfAbsent(histoName, newCounter);
480 if (histo == null) {
481 return newCounter;
482 }
483 }
484
485
486 if (!(histo instanceof MutableHistogram)) {
487 throw new MetricsException("Metric already exists in registry for metric name: " +
488 histoName + " and not of type MutableHistogram");
489 }
490
491 return (MutableHistogram) histo;
492 }
493
494 public MetricMutableQuantiles getQuantile(String histoName) {
495
496 MutableMetric histo = metricsMap.get(histoName);
497 if (histo == null) {
498 MetricMutableQuantiles newCounter =
499 new MetricMutableQuantiles(histoName, "", "Ops", "", 60);
500 histo = metricsMap.putIfAbsent(histoName, newCounter);
501 if (histo == null) {
502 return newCounter;
503 }
504 }
505
506
507 if (!(histo instanceof MetricMutableQuantiles)) {
508 throw new MetricsException("Metric already exists in registry for metric name: " +
509 histoName + " and not of type MutableHistogram");
510 }
511
512 return (MetricMutableQuantiles) histo;
513 }
514
515 private<T extends MutableMetric> T
516 addNewMetricIfAbsent(String name,
517 T ret,
518 Class<T> metricClass) {
519
520
521
522 MutableMetric metric = metricsMap.putIfAbsent(name, ret);
523 if (metric == null) {
524 return ret;
525 }
526
527 return returnExistingWithCast(metric, metricClass, name);
528 }
529
530 @SuppressWarnings("unchecked")
531 private<T> T returnExistingWithCast(MutableMetric metric,
532 Class<T> metricClass, String name) {
533 if (!metricClass.isAssignableFrom(metric.getClass())) {
534 throw new MetricsException("Metric already exists in registry for metric name: " +
535 name + " and not of type " + metricClass +
536 " but instead of type " + metric.getClass());
537 }
538
539 return (T) metric;
540 }
541
542 public void clearMetrics() {
543 metricsMap.clear();
544 }
545 }