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