001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package org.apache.hadoop.metrics2.lib;
020
021 import org.apache.commons.lang.StringUtils;
022 import org.apache.hadoop.classification.InterfaceAudience;
023 import org.apache.hadoop.classification.InterfaceStability;
024 import org.apache.hadoop.metrics2.MetricsInfo;
025 import org.apache.hadoop.metrics2.MetricsRecordBuilder;
026 import org.apache.hadoop.metrics2.util.SampleStat;
027 import static org.apache.hadoop.metrics2.lib.Interns.*;
028
029 /**
030 * A mutable metric with stats.
031 *
032 * Useful for keeping throughput/latency stats.
033 */
034 @InterfaceAudience.Public
035 @InterfaceStability.Evolving
036 public class MutableStat extends MutableMetric {
037 private final MetricsInfo numInfo;
038 private final MetricsInfo avgInfo;
039 private final MetricsInfo stdevInfo;
040 private final MetricsInfo iMinInfo;
041 private final MetricsInfo iMaxInfo;
042 private final MetricsInfo minInfo;
043 private final MetricsInfo maxInfo;
044
045 private final SampleStat intervalStat = new SampleStat();
046 private final SampleStat prevStat = new SampleStat();
047 private final SampleStat.MinMax minMax = new SampleStat.MinMax();
048 private long numSamples = 0;
049 private boolean extended = false;
050
051 /**
052 * Construct a sample statistics metric
053 * @param name of the metric
054 * @param description of the metric
055 * @param sampleName of the metric (e.g. "Ops")
056 * @param valueName of the metric (e.g. "Time", "Latency")
057 * @param extended create extended stats (stdev, min/max etc.) by default.
058 */
059 public MutableStat(String name, String description,
060 String sampleName, String valueName, boolean extended) {
061 String ucName = StringUtils.capitalize(name);
062 String usName = StringUtils.capitalize(sampleName);
063 String uvName = StringUtils.capitalize(valueName);
064 String desc = StringUtils.uncapitalize(description);
065 String lsName = StringUtils.uncapitalize(sampleName);
066 String lvName = StringUtils.uncapitalize(valueName);
067 numInfo = info(ucName +"Num"+ usName, "Number of "+ lsName +" for "+ desc);
068 avgInfo = info(ucName +"Avg"+ uvName, "Average "+ lvName +" for "+ desc);
069 stdevInfo = info(ucName +"Stdev"+ uvName,
070 "Standard deviation of "+ lvName +" for "+ desc);
071 iMinInfo = info(ucName +"IMin"+ uvName,
072 "Interval min "+ lvName +" for "+ desc);
073 iMaxInfo = info(ucName + "IMax"+ uvName,
074 "Interval max "+ lvName +" for "+ desc);
075 minInfo = info(ucName +"Min"+ uvName, "Min "+ lvName +" for "+ desc);
076 maxInfo = info(ucName +"Max"+ uvName, "Max "+ lvName +" for "+ desc);
077 this.extended = extended;
078 }
079
080 /**
081 * Construct a snapshot stat metric with extended stat off by default
082 * @param name of the metric
083 * @param description of the metric
084 * @param sampleName of the metric (e.g. "Ops")
085 * @param valueName of the metric (e.g. "Time", "Latency")
086 */
087 public MutableStat(String name, String description,
088 String sampleName, String valueName) {
089 this(name, description, sampleName, valueName, false);
090 }
091
092 /**
093 * Set whether to display the extended stats (stdev, min/max etc.) or not
094 * @param extended enable/disable displaying extended stats
095 */
096 public synchronized void setExtended(boolean extended) {
097 this.extended = extended;
098 }
099
100 /**
101 * Add a number of samples and their sum to the running stat
102 * @param numSamples number of samples
103 * @param sum of the samples
104 */
105 public synchronized void add(long numSamples, long sum) {
106 intervalStat.add(numSamples, sum);
107 setChanged();
108 }
109
110 /**
111 * Add a snapshot to the metric
112 * @param value of the metric
113 */
114 public synchronized void add(long value) {
115 intervalStat.add(value);
116 minMax.add(value);
117 setChanged();
118 }
119
120 public synchronized void snapshot(MetricsRecordBuilder builder, boolean all) {
121 if (all || changed()) {
122 numSamples += intervalStat.numSamples();
123 builder.addCounter(numInfo, numSamples)
124 .addGauge(avgInfo, lastStat().mean());
125 if (extended) {
126 builder.addGauge(stdevInfo, lastStat().stddev())
127 .addGauge(iMinInfo, lastStat().min())
128 .addGauge(iMaxInfo, lastStat().max())
129 .addGauge(minInfo, minMax.min())
130 .addGauge(maxInfo, minMax.max());
131 }
132 if (changed()) {
133 if (numSamples > 0) {
134 intervalStat.copyTo(prevStat);
135 intervalStat.reset();
136 }
137 clearChanged();
138 }
139 }
140 }
141
142 private SampleStat lastStat() {
143 return changed() ? intervalStat : prevStat;
144 }
145
146 /**
147 * Reset the all time min max of the metric
148 */
149 public void resetMinMax() {
150 minMax.reset();
151 }
152
153 }