View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.metrics2.lib;
20  
21  import org.apache.commons.lang.StringUtils;
22  import org.apache.hadoop.hbase.classification.InterfaceAudience;
23  import org.apache.hadoop.hbase.metrics.Interns;
24  import org.apache.hadoop.hbase.util.Counter;
25  import org.apache.hadoop.hbase.util.FastLongHistogram;
26  import org.apache.hadoop.metrics2.MetricHistogram;
27  import org.apache.hadoop.metrics2.MetricsInfo;
28  import org.apache.hadoop.metrics2.MetricsRecordBuilder;
29  
30  /**
31   * A histogram implementation that runs in constant space, and exports to hadoop2's metrics2 system.
32   */
33  @InterfaceAudience.Private
34  public class MutableHistogram extends MutableMetric implements MetricHistogram {
35    // Double buffer the two FastLongHistograms.
36    // As they are reset they learn how the buckets should be spaced
37    // So keep two around and use them
38    protected final FastLongHistogram histogram;
39  
40    protected final String name;
41    protected final String desc;
42  
43    protected final Counter counter = new Counter(0);
44  
45    private boolean metricsInfoStringInited = false;
46    private String NUM_OPS_METRIC;
47    private String MIN_METRIC;
48    private String MAX_METRIC;
49    private String MEAN_METRIC;
50    private String MEDIAN_METRIC;
51    private String TWENTY_FIFTH_PERCENTILE_METRIC;
52    private String SEVENTY_FIFTH_PERCENTILE_METRIC;
53    private String NINETIETH_PERCENTILE_METRIC;
54    private String NINETY_FIFTH_PERCENTILE_METRIC;
55    private String NINETY_EIGHTH_PERCENTILE_METRIC;
56    private String NINETY_NINETH_PERCENTILE_METRIC;
57    private String NINETY_NINE_POINT_NINETH_PERCENTILE_METRIC;
58  
59    public MutableHistogram(MetricsInfo info) {
60      this(info.name(), info.description());
61    }
62  
63    public MutableHistogram(String name, String description) {
64      this(name, description, Integer.MAX_VALUE << 2);
65    }
66  
67    protected MutableHistogram(String name, String description, long maxExpected) {
68      this.name = StringUtils.capitalize(name);
69      this.desc = StringUtils.uncapitalize(description);
70  
71      this.histogram = new FastLongHistogram(FastLongHistogram.DEFAULT_NBINS, 1, maxExpected);
72    }
73  
74    public void add(final long val) {
75      counter.increment();
76      histogram.add(val, 1);
77    }
78  
79    public long getMax() {
80      return histogram.getMax();
81    }
82  
83    @Override
84    public synchronized void snapshot(MetricsRecordBuilder metricsRecordBuilder, boolean all) {
85      // Get a reference to the old histogram.
86      FastLongHistogram histo = histogram.reset();
87      if (histo != null) {
88        updateSnapshotMetrics(metricsRecordBuilder, histo);
89      }
90    }
91  
92    protected void updateSnapshotMetrics(MetricsRecordBuilder metricsRecordBuilder,
93                                         FastLongHistogram histo) {
94      if (!metricsInfoStringInited) {
95        NUM_OPS_METRIC = name + NUM_OPS_METRIC_NAME;
96        MIN_METRIC = name + MIN_METRIC_NAME;
97        MAX_METRIC = name + MAX_METRIC_NAME;
98        MEAN_METRIC = name + MEAN_METRIC_NAME;
99        MEDIAN_METRIC = name + MEDIAN_METRIC_NAME;
100       TWENTY_FIFTH_PERCENTILE_METRIC = name + TWENTY_FIFTH_PERCENTILE_METRIC_NAME;
101       SEVENTY_FIFTH_PERCENTILE_METRIC = name + SEVENTY_FIFTH_PERCENTILE_METRIC_NAME;
102       NINETIETH_PERCENTILE_METRIC = name + NINETIETH_PERCENTILE_METRIC_NAME;
103       NINETY_FIFTH_PERCENTILE_METRIC = name + NINETY_FIFTH_PERCENTILE_METRIC_NAME;
104       NINETY_EIGHTH_PERCENTILE_METRIC = name + NINETY_EIGHTH_PERCENTILE_METRIC_NAME;
105       NINETY_NINETH_PERCENTILE_METRIC = name + NINETY_NINETH_PERCENTILE_METRIC_NAME;
106       NINETY_NINE_POINT_NINETH_PERCENTILE_METRIC = name +
107           NINETY_NINE_POINT_NINETH_PERCENTILE_METRIC_NAME;
108 
109       metricsInfoStringInited = true;
110     }
111 
112     metricsRecordBuilder.addCounter(Interns.info(NUM_OPS_METRIC, desc), counter.get());
113     metricsRecordBuilder.addGauge(Interns.info(MIN_METRIC, desc), histo.getMin());
114     metricsRecordBuilder.addGauge(Interns.info(MAX_METRIC, desc), histo.getMax());
115     metricsRecordBuilder.addGauge(Interns.info(MEAN_METRIC, desc), histo.getMean());
116 
117     long[] percentiles = histo.getQuantiles();
118 
119     metricsRecordBuilder.addGauge(Interns.info(TWENTY_FIFTH_PERCENTILE_METRIC, desc),
120         percentiles[0]);
121     metricsRecordBuilder.addGauge(Interns.info(MEDIAN_METRIC, desc),
122         percentiles[1]);
123     metricsRecordBuilder.addGauge(Interns.info(SEVENTY_FIFTH_PERCENTILE_METRIC, desc),
124         percentiles[2]);
125     metricsRecordBuilder.addGauge(Interns.info(NINETIETH_PERCENTILE_METRIC, desc),
126         percentiles[3]);
127     metricsRecordBuilder.addGauge(Interns.info(NINETY_FIFTH_PERCENTILE_METRIC, desc),
128         percentiles[4]);
129     metricsRecordBuilder.addGauge(Interns.info(NINETY_EIGHTH_PERCENTILE_METRIC, desc),
130         percentiles[5]);
131     metricsRecordBuilder.addGauge(Interns.info(NINETY_NINETH_PERCENTILE_METRIC, desc),
132         percentiles[6]);
133     metricsRecordBuilder.addGauge(
134         Interns.info(NINETY_NINE_POINT_NINETH_PERCENTILE_METRIC, desc),
135         percentiles[7]);
136   }
137 }