/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase.metrics;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.metrics.MetricsRecord;
import org.apache.hadoop.metrics.util.MetricsRegistry;
import org.apache.hadoop.metrics.util.MetricsTimeVaryingRate;
import org.apache.hadoop.util.StringUtils;
/**
* This class extends MetricsTimeVaryingRate to let the metrics
* persist past a pushMetric() call
*/
@Deprecated
@InterfaceAudience.Private
public class PersistentMetricsTimeVaryingRate extends MetricsTimeVaryingRate {
protected static final Log LOG =
LogFactory.getLog("org.apache.hadoop.hbase.metrics");
protected boolean reset = false;
protected long lastOper = 0;
protected long totalOps = 0;
/**
* Constructor - create a new metric
* @param nam the name of the metrics to be used to publish the metric
* @param registry - where the metrics object will be registered
* @param description metrics description
*/
public PersistentMetricsTimeVaryingRate(final String nam,
final MetricsRegistry registry,
final String description) {
super(nam, registry, description);
}
/**
* Constructor - create a new metric
* @param nam the name of the metrics to be used to publish the metric
* @param registry - where the metrics object will be registered
*/
public PersistentMetricsTimeVaryingRate(final String nam,
MetricsRegistry registry) {
this(nam, registry, NO_DESCRIPTION);
}
/**
* Push updated metrics to the mr.
*
* Note this does NOT push to JMX
* (JMX gets the info via {@link #getPreviousIntervalAverageTime()} and
* {@link #getPreviousIntervalNumOps()}
*
* @param mr owner of this metric
*/
@Override
public synchronized void pushMetric(final MetricsRecord mr) {
// this will reset the currentInterval & num_ops += prevInterval()
super.pushMetric(mr);
// since we're retaining prevInterval(), we don't want to do the incr
// instead, we want to set that value because we have absolute ops
try {
mr.setMetric(getName() + "_num_ops", totalOps);
} catch (Exception e) {
LOG.info("pushMetric failed for " + getName() + "\n" +
StringUtils.stringifyException(e));
}
if (reset) {
// use the previous avg as our starting min/max/avg
super.inc(getPreviousIntervalAverageTime());
reset = false;
} else {
// maintain the stats that pushMetric() cleared
maintainStats();
}
}
/**
* Increment the metrics for numOps operations
* @param numOps - number of operations
* @param time - time for numOps operations
*/
@Override
public synchronized void inc(final int numOps, final long time) {
super.inc(numOps, time);
totalOps += numOps;
}
/**
* Increment the metrics for numOps operations
* @param time - time for numOps operations
*/
@Override
public synchronized void inc(final long time) {
super.inc(time);
++totalOps;
}
/**
* Rollover to a new interval
* NOTE: does not reset numOps. this is an absolute value
*/
public synchronized void resetMinMaxAvg() {
reset = true;
}
/* MetricsTimeVaryingRate will reset every time pushMetric() is called
* This is annoying for long-running stats that might not get a single
* operation in the polling period. This function ensures that values
* for those stat entries don't get reset.
*/
protected void maintainStats() {
int curOps = this.getPreviousIntervalNumOps();
if (curOps > 0) {
long curTime = this.getPreviousIntervalAverageTime();
long totalTime = curTime * curOps;
if (curTime == 0 || totalTime / curTime == curOps) {
super.inc(curOps, totalTime);
} else {
LOG.info("Stats for " + this.getName() + " overflowed! resetting");
}
}
}
}