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 * Add a number of samples and their sum to the running stat 094 * @param numSamples number of samples 095 * @param sum of the samples 096 */ 097 public synchronized void add(long numSamples, long sum) { 098 intervalStat.add(numSamples, sum); 099 setChanged(); 100 } 101 102 /** 103 * Add a snapshot to the metric 104 * @param value of the metric 105 */ 106 public synchronized void add(long value) { 107 intervalStat.add(value); 108 minMax.add(value); 109 setChanged(); 110 } 111 112 public synchronized void snapshot(MetricsRecordBuilder builder, boolean all) { 113 if (all || changed()) { 114 numSamples += intervalStat.numSamples(); 115 builder.addCounter(numInfo, numSamples) 116 .addGauge(avgInfo, lastStat().mean()); 117 if (extended) { 118 builder.addGauge(stdevInfo, lastStat().stddev()) 119 .addGauge(iMinInfo, lastStat().min()) 120 .addGauge(iMaxInfo, lastStat().max()) 121 .addGauge(minInfo, minMax.min()) 122 .addGauge(maxInfo, minMax.max()); 123 } 124 if (changed()) { 125 if (numSamples > 0) { 126 intervalStat.copyTo(prevStat); 127 intervalStat.reset(); 128 } 129 clearChanged(); 130 } 131 } 132 } 133 134 private SampleStat lastStat() { 135 return changed() ? intervalStat : prevStat; 136 } 137 138 /** 139 * Reset the all time min max of the metric 140 */ 141 public void resetMinMax() { 142 minMax.reset(); 143 } 144 145 }