diff --git a/src/java/org/apache/hadoop/hbase/metrics/MetricsRate.java b/src/java/org/apache/hadoop/hbase/metrics/MetricsRate.java new file mode 100644 index 0000000..a328cd2 --- /dev/null +++ b/src/java/org/apache/hadoop/hbase/metrics/MetricsRate.java @@ -0,0 +1,73 @@ +/** + * 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.metrics.MetricsRecord; +import org.apache.hadoop.util.StringUtils; + +/** + * Publishes a rate based on a counter - you increment the counter each + * time an event occurs (eg: an RPC call) and this publishes a rate. + */ +public class MetricsRate { + private static final Log LOG = LogFactory.getLog("org.apache.hadoop.hbase.metrics"); + + private String name; + private int value; + private float prevRate; + private long ts; + + public MetricsRate(final String name) { + this.name = name; + this.value = 0; + this.prevRate = 0; + this.ts = System.currentTimeMillis(); + } + + public synchronized void inc(final int incr) { + value += incr; + } + + public synchronized void inc() { + value++; + } + + private synchronized void intervalHeartBeat() { + long now = System.currentTimeMillis(); + long diff = (now-ts)/1000; + if (diff == 0) diff = 1; // sigh this is crap. + this.prevRate = value / diff; + this.value = 0; + this.ts = now; + } + + public synchronized void pushMetric(final MetricsRecord mr) { + intervalHeartBeat(); + try { + mr.setMetric(name, getPreviousIntervalValue()); + } catch (Exception e) { + LOG.info("pushMetric failed for " + name + "\n" + + StringUtils.stringifyException(e)); + } + } + public synchronized float getPreviousIntervalValue() { + return this.prevRate; + } +} diff --git a/src/java/org/apache/hadoop/hbase/regionserver/metrics/RegionServerMetrics.java b/src/java/org/apache/hadoop/hbase/regionserver/metrics/RegionServerMetrics.java index d5c67f7..2f0e4b6 100644 --- a/src/java/org/apache/hadoop/hbase/regionserver/metrics/RegionServerMetrics.java +++ b/src/java/org/apache/hadoop/hbase/regionserver/metrics/RegionServerMetrics.java @@ -22,6 +22,7 @@ import java.lang.management.MemoryUsage; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.hbase.metrics.MetricsRate; import org.apache.hadoop.hbase.util.Strings; import org.apache.hadoop.metrics.MetricsContext; import org.apache.hadoop.metrics.MetricsRecord; @@ -29,6 +30,7 @@ import org.apache.hadoop.metrics.MetricsUtil; import org.apache.hadoop.metrics.Updater; import org.apache.hadoop.metrics.jvm.JvmMetrics; import org.apache.hadoop.metrics.util.MetricsIntValue; +import org.apache.hadoop.metrics.util.MetricsTimeVaryingRate; /** @@ -44,34 +46,34 @@ public class RegionServerMetrics implements Updater { /** * Count of regions carried by this regionserver */ - public final MetricsIntValue regions = new MetricsIntValue("regions"); + public final MetricsIntValue regions = new MetricsIntValue("hbase_regions"); /* * Count of requests to the regionservers since last call to metrics update */ - private final MetricsIntValue requests = new MetricsIntValue("requests"); + private final MetricsRate requests = new MetricsRate("hbase_requests"); /** * Count of stores open on the regionserver. */ - public final MetricsIntValue stores = new MetricsIntValue("stores"); + public final MetricsIntValue stores = new MetricsIntValue("hbase_stores"); /** * Count of storefiles open on the regionserver. */ - public final MetricsIntValue storefiles = new MetricsIntValue("storefiles"); + public final MetricsIntValue storefiles = new MetricsIntValue("hbase_storefiles"); /** * Sum of all the storefile index sizes in this regionserver in MB */ public final MetricsIntValue storefileIndexSizeMB = - new MetricsIntValue("storefileIndexSizeMB"); + new MetricsIntValue("hbase_storefileIndexSizeMB"); /** * Sum of all the memcache sizes in this regionserver in MB */ public final MetricsIntValue memcacheSizeMB = - new MetricsIntValue("memcachSizeMB"); + new MetricsIntValue("hbase_memcacheSizeMB"); public RegionServerMetrics() { MetricsContext context = MetricsUtil.getContext("hbase"); @@ -102,11 +106,7 @@ public class RegionServerMetrics implements Updater { this.storefileIndexSizeMB.pushMetric(this.metricsRecord); this.memcacheSizeMB.pushMetric(this.metricsRecord); this.regions.pushMetric(this.metricsRecord); - synchronized(this.requests) { - this.requests.pushMetric(this.metricsRecord); - // Set requests down to zero again. - this.requests.set(0); - } + this.requests.pushMetric(this.metricsRecord); } this.metricsRecord.update(); this.lastUpdate = System.currentTimeMillis(); @@ -119,17 +120,15 @@ public class RegionServerMetrics implements Updater { /** * @return Count of requests. */ - public int getRequests() { - return this.requests.get(); + public float getRequests() { + return this.requests.getPreviousIntervalValue(); } /** * @param inc How much to add to requests. */ public void incrementRequests(final int inc) { - synchronized(this.requests) { - this.requests.inc(inc); - } + this.requests.inc(inc); } @Override @@ -140,7 +139,7 @@ public class RegionServerMetrics implements Updater { seconds = 1; } sb = Strings.appendKeyValue(sb, "request", - Integer.valueOf(this.requests.get()/seconds)); + Float.valueOf(this.requests.getPreviousIntervalValue())); sb = Strings.appendKeyValue(sb, "regions", Integer.valueOf(this.regions.get())); sb = Strings.appendKeyValue(sb, "stores",