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 org.apache.hadoop.hbase.classification.InterfaceAudience;
22 import org.apache.hadoop.hbase.classification.InterfaceStability;
23 import org.apache.hadoop.metrics2.MetricHistogram;
24 import org.apache.hadoop.metrics2.MetricsExecutor;
25 import org.apache.hadoop.metrics2.MetricsRecordBuilder;
26 import org.apache.hadoop.metrics2.util.MetricQuantile;
27 import org.apache.hadoop.metrics2.util.MetricSampleQuantiles;
28
29 import java.io.IOException;
30 import java.util.Map;
31 import java.util.concurrent.TimeUnit;
32
33
34
35
36
37
38 @InterfaceAudience.Private
39 public class MetricMutableQuantiles extends MetricMutable implements MetricHistogram {
40
41 static final MetricQuantile[] quantiles = {new MetricQuantile(0.50, 0.050),
42 new MetricQuantile(0.75, 0.025), new MetricQuantile(0.90, 0.010),
43 new MetricQuantile(0.95, 0.005), new MetricQuantile(0.99, 0.001)};
44
45 static final String[] quantilesSuffix = {"_Median",
46 "_75th_percentile", "_90th_percentile",
47 "_95th_percentile", "_99th_percentile"};
48
49 private final int interval;
50
51 private MetricSampleQuantiles estimator;
52 private long previousCount = 0;
53 private MetricsExecutor executor;
54
55 protected Map<MetricQuantile, Long> previousSnapshot = null;
56
57
58
59
60
61
62
63
64
65
66
67 public MetricMutableQuantiles(String name, String description, String sampleName,
68 String valueName, int interval) {
69 super(name, description);
70
71 estimator = new MetricSampleQuantiles(quantiles);
72
73 executor = new MetricsExecutorImpl();
74
75 this.interval = interval;
76 executor.getExecutor().scheduleAtFixedRate(new RolloverSample(this),
77 interval,
78 interval,
79 TimeUnit.SECONDS);
80 }
81
82 public MetricMutableQuantiles(String name, String description) {
83 this(name, description, "Ops", "", 60);
84 }
85
86 @Override
87 public synchronized void snapshot(MetricsRecordBuilder builder, boolean all) {
88 if (all || changed()) {
89 builder.addCounter(name + "NumOps", description, previousCount);
90 for (int i = 0; i < quantiles.length; i++) {
91 long newValue = 0;
92
93 if (previousSnapshot != null) {
94 newValue = previousSnapshot.get(quantiles[i]);
95 }
96 builder.addGauge(name + quantilesSuffix[i], description, newValue);
97 }
98 if (changed()) {
99 clearChanged();
100 }
101 }
102 }
103
104 public synchronized void add(long value) {
105 estimator.insert(value);
106 }
107
108 public int getInterval() {
109 return interval;
110 }
111
112
113 private static class RolloverSample implements Runnable {
114
115 MetricMutableQuantiles parent;
116
117 public RolloverSample(MetricMutableQuantiles parent) {
118 this.parent = parent;
119 }
120
121 @Override
122 public void run() {
123 synchronized (parent) {
124 try {
125 parent.previousCount = parent.estimator.getCount();
126 parent.previousSnapshot = parent.estimator.snapshot();
127 } catch (IOException e) {
128
129 parent.previousCount = 0;
130 parent.previousSnapshot = null;
131 }
132 parent.estimator.clear();
133 }
134 parent.setChanged();
135 }
136
137 }
138 }