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 private final MetricsInfo iNumInfo; 045 046 private final SampleStat intervalStat = new SampleStat(); 047 private final SampleStat prevStat = new SampleStat(); 048 private final SampleStat.MinMax minMax = new SampleStat.MinMax(); 049 private long numSamples = 0; 050 private boolean extended = false; 051 052 /** 053 * Construct a sample statistics metric 054 * @param name of the metric 055 * @param description of the metric 056 * @param sampleName of the metric (e.g. "Ops") 057 * @param valueName of the metric (e.g. "Time", "Latency") 058 * @param extended create extended stats (stdev, min/max etc.) by default. 059 */ 060 public MutableStat(String name, String description, 061 String sampleName, String valueName, boolean extended) { 062 String ucName = StringUtils.capitalize(name); 063 String usName = StringUtils.capitalize(sampleName); 064 String uvName = StringUtils.capitalize(valueName); 065 String desc = StringUtils.uncapitalize(description); 066 String lsName = StringUtils.uncapitalize(sampleName); 067 String lvName = StringUtils.uncapitalize(valueName); 068 numInfo = info(ucName +"Num"+ usName, "Number of "+ lsName +" for "+ desc); 069 iNumInfo = info(ucName +"INum"+ usName, 070 "Interval number of "+ lsName +" for "+ desc); 071 avgInfo = info(ucName +"Avg"+ uvName, "Average "+ lvName +" for "+ desc); 072 stdevInfo = info(ucName +"Stdev"+ uvName, 073 "Standard deviation of "+ lvName +" for "+ desc); 074 iMinInfo = info(ucName +"IMin"+ uvName, 075 "Interval min "+ lvName +" for "+ desc); 076 iMaxInfo = info(ucName + "IMax"+ uvName, 077 "Interval max "+ lvName +" for "+ desc); 078 minInfo = info(ucName +"Min"+ uvName, "Min "+ lvName +" for "+ desc); 079 maxInfo = info(ucName +"Max"+ uvName, "Max "+ lvName +" for "+ desc); 080 this.extended = extended; 081 } 082 083 /** 084 * Construct a snapshot stat metric with extended stat off by default 085 * @param name of the metric 086 * @param description of the metric 087 * @param sampleName of the metric (e.g. "Ops") 088 * @param valueName of the metric (e.g. "Time", "Latency") 089 */ 090 public MutableStat(String name, String description, 091 String sampleName, String valueName) { 092 this(name, description, sampleName, valueName, false); 093 } 094 095 /** 096 * Set whether to display the extended stats (stdev, min/max etc.) or not 097 * @param extended enable/disable displaying extended stats 098 */ 099 public synchronized void setExtended(boolean extended) { 100 this.extended = extended; 101 } 102 103 /** 104 * Add a number of samples and their sum to the running stat 105 * @param numSamples number of samples 106 * @param sum of the samples 107 */ 108 public synchronized void add(long numSamples, long sum) { 109 intervalStat.add(numSamples, sum); 110 setChanged(); 111 } 112 113 /** 114 * Add a snapshot to the metric 115 * @param value of the metric 116 */ 117 public synchronized void add(long value) { 118 intervalStat.add(value); 119 minMax.add(value); 120 setChanged(); 121 } 122 123 @Override 124 public synchronized void snapshot(MetricsRecordBuilder builder, boolean all) { 125 if (all || changed()) { 126 numSamples += intervalStat.numSamples(); 127 builder.addCounter(numInfo, numSamples) 128 .addGauge(avgInfo, lastStat().mean()); 129 if (extended) { 130 builder.addGauge(stdevInfo, lastStat().stddev()) 131 .addGauge(iMinInfo, lastStat().min()) 132 .addGauge(iMaxInfo, lastStat().max()) 133 .addGauge(minInfo, minMax.min()) 134 .addGauge(maxInfo, minMax.max()) 135 .addGauge(iNumInfo, lastStat().numSamples()); 136 } 137 if (changed()) { 138 if (numSamples > 0) { 139 intervalStat.copyTo(prevStat); 140 intervalStat.reset(); 141 } 142 clearChanged(); 143 } 144 } 145 } 146 147 /** 148 * Return a SampleStat object that supports 149 * calls like StdDev and Mean. 150 * @return SampleStat 151 */ 152 public SampleStat lastStat() { 153 return changed() ? intervalStat : prevStat; 154 } 155 156 /** 157 * Reset the all time min max of the metric 158 */ 159 public void resetMinMax() { 160 minMax.reset(); 161 } 162 163 @Override 164 public String toString() { 165 return lastStat().toString(); 166 } 167}