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 019package org.apache.hadoop.metrics2.lib; 020 021import org.apache.commons.lang.StringUtils; 022import org.apache.hadoop.classification.InterfaceAudience; 023import org.apache.hadoop.classification.InterfaceStability; 024import org.apache.hadoop.metrics2.MetricsInfo; 025import org.apache.hadoop.metrics2.MetricsRecordBuilder; 026import org.apache.hadoop.metrics2.util.SampleStat; 027import 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 036public 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 /** 143 * Return a SampleStat object that supports 144 * calls like StdDev and Mean. 145 * @return SampleStat 146 */ 147 public SampleStat lastStat() { 148 return changed() ? intervalStat : prevStat; 149 } 150 151 /** 152 * Reset the all time min max of the metric 153 */ 154 public void resetMinMax() { 155 minMax.reset(); 156 } 157 158 @Override 159 public String toString() { 160 return lastStat().toString(); 161 } 162}