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 MetricMutableQuantiles newQuantile(String name) {
210 return newQuantile(name, "");
211 }
212
213
214
215
216
217
218
219 public MetricMutableQuantiles newQuantile(String name, String desc) {
220 MetricMutableQuantiles histo = new MetricMutableQuantiles(name, desc);
221 return addNewMetricIfAbsent(name, histo, MetricMutableQuantiles.class);
222 }
223
224
225
226
227
228
229 public DynamicMetricsRegistry setContext(String name) {
230 return tag(CONTEXT_KEY, CONTEXT_DESC, name);
231 }
232
233
234
235
236
237
238
239
240 public DynamicMetricsRegistry tag(String name, String description, String value) {
241 return tag(name, description, value, false);
242 }
243
244
245
246
247
248
249
250
251
252 public DynamicMetricsRegistry tag(String name, String description, String value,
253 boolean override) {
254 MetricsTag tag = new MetricsTag(name, description, value);
255
256 if (!override) {
257 MetricsTag existing = tagsMap.putIfAbsent(name, tag);
258 if (existing != null) {
259 throw new MetricsException("Tag "+ name +" already exists!");
260 }
261 return this;
262 }
263
264 tagsMap.put(name, tag);
265
266 return this;
267 }
268
269
270
271
272
273 public Set<Entry<String, MetricsTag>> tags() {
274 return tagsMap.entrySet();
275 }
276
277
278
279
280
281 public Set<Entry<String, MetricMutable>> metrics() {
282 return metricsMap.entrySet();
283 }
284
285
286
287
288
289
290 public void snapshot(MetricsRecordBuilder builder, boolean all) {
291
292 for (Entry<String, MetricsTag> entry : tags()) {
293 builder.add(entry.getValue());
294 }
295 for (Entry<String, MetricMutable> entry : metrics()) {
296 entry.getValue().snapshot(builder, all);
297 }
298 }
299
300
301
302
303
304 public void removeMetric(String name) {
305 metricsMap.remove(name);
306 }
307
308
309
310
311
312
313
314
315
316 public MetricMutableGaugeLong getLongGauge(String gaugeName,
317 long potentialStartingValue) {
318
319 MetricMutable metric = metricsMap.get(gaugeName);
320
321
322 if (metric == null) {
323
324
325 MetricMutableGaugeLong newGauge = mf.newGauge(gaugeName, "",
326 potentialStartingValue);
327
328
329 metric = metricsMap.putIfAbsent(gaugeName, newGauge);
330
331
332
333
334 if (metric == null) {
335 return newGauge;
336 }
337 }
338
339 if (!(metric instanceof MetricMutableGaugeLong)) {
340 throw new MetricsException("Metric already exists in registry for metric name: " +
341 name + " and not of type MetricMutableGaugeLong");
342 }
343
344 return (MetricMutableGaugeLong) metric;
345 }
346
347
348
349
350
351
352
353
354
355 public MetricMutableCounterLong getLongCounter(String counterName,
356 long potentialStartingValue) {
357
358 MetricMutable counter = metricsMap.get(counterName);
359 if (counter == null) {
360 MetricMutableCounterLong newCounter =
361 mf.newCounter(counterName, "", potentialStartingValue);
362 counter = metricsMap.putIfAbsent(counterName, newCounter);
363 if (counter == null) {
364 return newCounter;
365 }
366 }
367
368 if (!(counter instanceof MetricMutableCounterLong)) {
369 throw new MetricsException("Metric already exists in registry for metric name: " +
370 name + "and not of type MetricMutableCounterLong");
371 }
372
373 return (MetricMutableCounterLong) counter;
374 }
375
376 public MetricMutableHistogram getHistogram(String histoName) {
377
378 MetricMutable histo = metricsMap.get(histoName);
379 if (histo == null) {
380 MetricMutableHistogram newHisto =
381 new MetricMutableHistogram(histoName, "");
382 histo = metricsMap.putIfAbsent(histoName, newHisto);
383 if (histo == null) {
384 return newHisto;
385 }
386 }
387
388 if (!(histo instanceof MetricMutableHistogram)) {
389 throw new MetricsException("Metric already exists in registry for metric name: " +
390 name + "and not of type MetricMutableHistogram");
391 }
392
393 return (MetricMutableHistogram) histo;
394 }
395
396 public MetricMutableQuantiles getQuantile(String histoName) {
397
398 MetricMutable histo = metricsMap.get(histoName);
399 if (histo == null) {
400 MetricMutableQuantiles newHisto =
401 new MetricMutableQuantiles(histoName, "");
402 histo = metricsMap.putIfAbsent(histoName, newHisto);
403 if (histo == null) {
404 return newHisto;
405 }
406 }
407
408 if (!(histo instanceof MetricMutableQuantiles)) {
409 throw new MetricsException("Metric already exists in registry for metric name: " +
410 name + "and not of type MetricMutableQuantiles");
411 }
412
413 return (MetricMutableQuantiles) histo;
414 }
415
416 private<T extends MetricMutable> T
417 addNewMetricIfAbsent(String name,
418 T ret,
419 Class<T> metricClass) {
420
421
422
423 MetricMutable metric = metricsMap.putIfAbsent(name, ret);
424 if (metric == null) {
425 return ret;
426 }
427
428 return returnExistingWithCast(metric, metricClass, name);
429 }
430
431 private<T> T returnExistingWithCast(MetricMutable metric,
432 Class<T> metricClass, String name) {
433 if (!metricClass.isAssignableFrom(metric.getClass())) {
434 throw new MetricsException("Metric already exists in registry for metric name: " +
435 name + " and not of type " + metricClass);
436 }
437
438 return (T) metric;
439 }
440
441 public void clearMetrics() {
442 metricsMap.clear();
443 }
444 }