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.Map.Entry;
22 import java.util.Set;
23 import java.util.concurrent.ConcurrentHashMap;
24 import java.util.concurrent.ConcurrentMap;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.hadoop.metrics2.MetricsException;
29 import org.apache.hadoop.metrics2.MetricsRecordBuilder;
30 import org.apache.hadoop.metrics2.MetricsTag;
31
32
33
34
35
36
37
38
39
40
41
42 public class DynamicMetricsRegistry {
43
44 private final Log LOG = LogFactory.getLog(this.getClass());
45
46
47 public static final String CONTEXT_KEY = "context";
48
49 public static final String CONTEXT_DESC = "Metrics context";
50
51 private final ConcurrentMap<String, MetricMutable> metricsMap =
52 new ConcurrentHashMap<String, MetricMutable>();
53 private final ConcurrentMap<String, MetricsTag> tagsMap =
54 new ConcurrentHashMap<String, MetricsTag>();
55 private final String name;
56 private final MetricMutableFactory mf;
57
58
59
60
61
62 public DynamicMetricsRegistry(String name) {
63 this.name = name;
64 this.mf = new MetricMutableFactory();
65 }
66
67
68
69
70
71
72 public DynamicMetricsRegistry(String name, MetricMutableFactory factory) {
73 this.name = name;
74 this.mf = factory;
75 }
76
77
78
79
80 public String name() {
81 return name;
82 }
83
84
85
86
87
88
89 public MetricMutable get(String name) {
90 return metricsMap.get(name);
91 }
92
93
94
95
96
97
98
99
100 public MetricMutableCounterInt
101 newCounter(String name, String description, int initValue) {
102 MetricMutableCounterInt ret = mf.newCounter(name, description, initValue);
103 return addNewMetricIfAbsent(name, ret, MetricMutableCounterInt.class);
104 }
105
106
107
108
109
110
111
112
113 public MetricMutableCounterLong
114 newCounter(String name, String description, long initValue) {
115 MetricMutableCounterLong ret = mf.newCounter(name, description, initValue);
116 return addNewMetricIfAbsent(name, ret, MetricMutableCounterLong.class);
117 }
118
119
120
121
122
123
124
125
126 public MetricMutableGaugeInt
127 newGauge(String name, String description, int initValue) {
128 MetricMutableGaugeInt ret = mf.newGauge(name, description, initValue);
129 return addNewMetricIfAbsent(name, ret, MetricMutableGaugeInt.class);
130 }
131
132
133
134
135
136
137
138
139 public MetricMutableGaugeLong
140 newGauge(String name, String description, long initValue) {
141 MetricMutableGaugeLong ret = mf.newGauge(name, description, initValue);
142 return addNewMetricIfAbsent(name, ret, MetricMutableGaugeLong.class);
143 }
144
145
146
147
148
149
150
151
152
153
154 public MetricMutableStat newStat(String name, String description,
155 String sampleName, String valueName,
156 boolean extended) {
157 MetricMutableStat ret =
158 mf.newStat(name, description, sampleName, valueName, extended);
159 return addNewMetricIfAbsent(name, ret, MetricMutableStat.class);
160 }
161
162
163
164
165
166
167
168
169
170 public MetricMutableStat newStat(String name, String description,
171 String sampleName, String valueName) {
172 return newStat(name, description, sampleName, valueName, false);
173 }
174
175
176
177
178
179
180 public MetricMutableStat newStat(String name) {
181 return newStat(name, "", "ops", "time", false);
182 }
183
184
185
186
187
188
189 public MetricMutableHistogram newHistogram(String name) {
190 return newHistogram(name, "");
191 }
192
193
194
195
196
197
198
199 public MetricMutableHistogram newHistogram(String name, String desc) {
200 MetricMutableHistogram histo = new MetricMutableHistogram(name, desc);
201 return addNewMetricIfAbsent(name, histo, MetricMutableHistogram.class);
202 }
203
204
205
206
207
208
209 public MetricMutableTimeHistogram newTimeHistogram(String name) {
210 return newTimeHistogram(name, "");
211 }
212
213
214
215
216
217
218
219 public MetricMutableTimeHistogram newTimeHistogram(String name, String desc) {
220 MetricMutableTimeHistogram histo = new MetricMutableTimeHistogram(name, desc);
221 return addNewMetricIfAbsent(name, histo, MetricMutableTimeHistogram.class);
222 }
223
224
225
226
227
228
229 public MetricMutableSizeHistogram newSizeHistogram(String name) {
230 return newSizeHistogram(name, "");
231 }
232
233
234
235
236
237
238
239 public MetricMutableSizeHistogram newSizeHistogram(String name, String desc) {
240 MetricMutableSizeHistogram histo = new MetricMutableSizeHistogram(name, desc);
241 return addNewMetricIfAbsent(name, histo, MetricMutableSizeHistogram.class);
242 }
243
244
245
246
247
248
249 public MetricMutableQuantiles newQuantile(String name) {
250 return newQuantile(name, "");
251 }
252
253
254
255
256
257
258
259 public MetricMutableQuantiles newQuantile(String name, String desc) {
260 MetricMutableQuantiles histo = new MetricMutableQuantiles(name, desc);
261 return addNewMetricIfAbsent(name, histo, MetricMutableQuantiles.class);
262 }
263
264
265
266
267
268
269 public DynamicMetricsRegistry setContext(String name) {
270 return tag(CONTEXT_KEY, CONTEXT_DESC, name);
271 }
272
273
274
275
276
277
278
279
280 public DynamicMetricsRegistry tag(String name, String description, String value) {
281 return tag(name, description, value, false);
282 }
283
284
285
286
287
288
289
290
291
292 public DynamicMetricsRegistry tag(String name, String description, String value,
293 boolean override) {
294 MetricsTag tag = new MetricsTag(name, description, value);
295
296 if (!override) {
297 MetricsTag existing = tagsMap.putIfAbsent(name, tag);
298 if (existing != null) {
299 throw new MetricsException("Tag "+ name +" already exists!");
300 }
301 return this;
302 }
303
304 tagsMap.put(name, tag);
305
306 return this;
307 }
308
309
310
311
312
313 public Set<Entry<String, MetricsTag>> tags() {
314 return tagsMap.entrySet();
315 }
316
317
318
319
320
321 public Set<Entry<String, MetricMutable>> metrics() {
322 return metricsMap.entrySet();
323 }
324
325
326
327
328
329
330 public void snapshot(MetricsRecordBuilder builder, boolean all) {
331
332 for (Entry<String, MetricsTag> entry : tags()) {
333 builder.add(entry.getValue());
334 }
335 for (Entry<String, MetricMutable> entry : metrics()) {
336 entry.getValue().snapshot(builder, all);
337 }
338 }
339
340
341
342
343
344 public void removeMetric(String name) {
345 metricsMap.remove(name);
346 }
347
348
349
350
351
352
353
354
355
356 public MetricMutableGaugeLong getLongGauge(String gaugeName,
357 long potentialStartingValue) {
358
359 MetricMutable metric = metricsMap.get(gaugeName);
360
361
362 if (metric == null) {
363
364
365 MetricMutableGaugeLong newGauge = mf.newGauge(gaugeName, "",
366 potentialStartingValue);
367
368
369 metric = metricsMap.putIfAbsent(gaugeName, newGauge);
370
371
372
373
374 if (metric == null) {
375 return newGauge;
376 }
377 }
378
379 if (!(metric instanceof MetricMutableGaugeLong)) {
380 throw new MetricsException("Metric already exists in registry for metric name: " +
381 name + " and not of type MetricMutableGaugeLong");
382 }
383
384 return (MetricMutableGaugeLong) metric;
385 }
386
387
388
389
390
391
392
393
394
395 public MetricMutableCounterLong getLongCounter(String counterName,
396 long potentialStartingValue) {
397
398 MetricMutable counter = metricsMap.get(counterName);
399 if (counter == null) {
400 MetricMutableCounterLong newCounter =
401 mf.newCounter(counterName, "", potentialStartingValue);
402 counter = metricsMap.putIfAbsent(counterName, newCounter);
403 if (counter == null) {
404 return newCounter;
405 }
406 }
407
408 if (!(counter instanceof MetricMutableCounterLong)) {
409 throw new MetricsException("Metric already exists in registry for metric name: " +
410 name + "and not of type MetricMutableCounterLong");
411 }
412
413 return (MetricMutableCounterLong) counter;
414 }
415
416 public MetricMutableHistogram getHistogram(String histoName) {
417
418 MetricMutable histo = metricsMap.get(histoName);
419 if (histo == null) {
420 MetricMutableHistogram newHisto =
421 new MetricMutableHistogram(histoName, "");
422 histo = metricsMap.putIfAbsent(histoName, newHisto);
423 if (histo == null) {
424 return newHisto;
425 }
426 }
427
428 if (!(histo instanceof MetricMutableHistogram)) {
429 throw new MetricsException("Metric already exists in registry for metric name: " +
430 name + "and not of type MetricMutableHistogram");
431 }
432
433 return (MetricMutableHistogram) histo;
434 }
435
436 public MetricMutableQuantiles getQuantile(String histoName) {
437
438 MetricMutable histo = metricsMap.get(histoName);
439 if (histo == null) {
440 MetricMutableQuantiles newHisto =
441 new MetricMutableQuantiles(histoName, "");
442 histo = metricsMap.putIfAbsent(histoName, newHisto);
443 if (histo == null) {
444 return newHisto;
445 }
446 }
447
448 if (!(histo instanceof MetricMutableQuantiles)) {
449 throw new MetricsException("Metric already exists in registry for metric name: " +
450 name + "and not of type MetricMutableQuantiles");
451 }
452
453 return (MetricMutableQuantiles) histo;
454 }
455
456 private<T extends MetricMutable> T
457 addNewMetricIfAbsent(String name,
458 T ret,
459 Class<T> metricClass) {
460
461
462
463 MetricMutable metric = metricsMap.putIfAbsent(name, ret);
464 if (metric == null) {
465 return ret;
466 }
467
468 return returnExistingWithCast(metric, metricClass, name);
469 }
470
471 private<T> T returnExistingWithCast(MetricMutable metric,
472 Class<T> metricClass, String name) {
473 if (!metricClass.isAssignableFrom(metric.getClass())) {
474 throw new MetricsException("Metric already exists in registry for metric name: " +
475 name + " and not of type " + metricClass);
476 }
477
478 return (T) metric;
479 }
480
481 public void clearMetrics() {
482 metricsMap.clear();
483 }
484 }