Index: conf/hadoop-metrics2.properties =================================================================== --- conf/hadoop-metrics2.properties (revision 0) +++ conf/hadoop-metrics2.properties (revision 0) @@ -0,0 +1,6 @@ +# syntax: [prefix].[source|sink].[instance].[options] +# See javadoc of package-info.java for org.apache.hadoop.metrics2 for details + +*.sink.file.class=org.apache.hadoop.metrics2.sink.FileSink +# default sampling period +*.period=10 Index: hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMXBean.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMXBean.java (revision 1363838) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMXBean.java (working copy) @@ -25,6 +25,7 @@ import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.ServerLoad; +import org.apache.hadoop.hbase.master.metrics.MXBeanImpl; import org.apache.hadoop.hbase.regionserver.HRegionServer; import org.apache.hadoop.hbase.MediumTests; import org.junit.AfterClass; @@ -48,22 +49,6 @@ TEST_UTIL.shutdownMiniCluster(); } - private void verifyRegionServers(Map regions) { - Set expected = new HashSet(); - for (int i = 0; i < 4; ++i) { - HRegionServer rs = TEST_UTIL.getMiniHBaseCluster().getRegionServer(i); - expected.add(rs.getServerName().getServerName()); - } - - int found = 0; - for (java.util.Map.Entry entry : regions.entrySet()) { - if (expected.contains(entry.getKey())) { - ++found; - } - } - Assert.assertEquals(4, found); - } - @Test public void testInfo() { HMaster master = TEST_UTIL.getHBaseCluster().getMaster(); @@ -77,20 +62,18 @@ Assert.assertEquals(master.getCoprocessors().length, info.getCoprocessors().length); Assert.assertEquals(master.getServerManager().getOnlineServersList().size(), - info.getRegionServers().size()); + info.getRegionServers()); Assert.assertEquals(master.getAssignmentManager().isRegionsInTransition(), info.getRegionsInTransition().length > 0); - Assert.assertTrue(info.getRegionServers().size() == 4); + Assert.assertTrue(info.getRegionServers() == 4); String zkServers = info.getZookeeperQuorum(); Assert.assertEquals(zkServers.split(",").length, TEST_UTIL.getZkCluster().getZooKeeperServerNum()); - verifyRegionServers(info.getRegionServers()); - TEST_UTIL.getMiniHBaseCluster().stopRegionServer(3, false); TEST_UTIL.getMiniHBaseCluster().waitOnRegionServer(3); - Assert.assertTrue(info.getRegionServers().size() == 3); + Assert.assertTrue(info.getRegionServers() == 3); Assert.assertTrue(info.getDeadRegionServers().length == 1); } Index: hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterMetrics.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterMetrics.java (revision 0) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterMetrics.java (revision 0) @@ -0,0 +1,110 @@ +/** + * 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.master; + +import junit.framework.Assert; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.HBaseConfiguration; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.MediumTests; +import org.apache.hadoop.hbase.MiniHBaseCluster; +import org.apache.hadoop.hbase.master.metrics.MXBeanImpl; +import org.apache.hadoop.hbase.metrics.MetricsAsserts; +import org.apache.hadoop.hbase.protobuf.ProtobufUtil; +import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos; +import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos; +import org.apache.hadoop.hbase.regionserver.HRegionServer; +import org.apache.hadoop.hbase.util.Threads; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(MediumTests.class) +public class TestMasterMetrics { + private static final Log LOG = LogFactory.getLog(TestMasterMetrics.class); + + static { + Logger.getLogger("org.apache.hadoop.hbase").setLevel(Level.DEBUG); + } + + private MiniHBaseCluster cluster; + private HMaster master; + private Configuration conf; + private HBaseTestingUtility TEST_UTIL; + + private void startCluster() throws Exception{ + LOG.info("Starting cluster"); + conf = HBaseConfiguration.create(); + conf.getLong("hbase.splitlog.max.resubmit", 0); + // Make the failure test faster + conf.setInt("zookeeper.recovery.retry", 0); + conf.setInt(HConstants.REGIONSERVER_INFO_PORT, -1); + conf.setFloat(HConstants.LOAD_BALANCER_SLOP_KEY, (float) 100.0); // no load balancing + conf.setBoolean(HConstants.DISTRIBUTED_LOG_SPLITTING_KEY, true); + TEST_UTIL = new HBaseTestingUtility(conf); + TEST_UTIL.startMiniCluster(1, 1); + cluster = TEST_UTIL.getHBaseCluster(); + LOG.info("Waiting for active/ready master"); + cluster.waitForActiveAndReadyMaster(); + master = cluster.getMaster(); + + while (cluster.getLiveRegionServerThreads().size() < 1) { + Threads.sleep(1); + } + } + + @After + public void after() throws Exception { + if (TEST_UTIL != null) { + TEST_UTIL.shutdownMiniCluster(); + } + } + + @Test(timeout=300000) + public void testClusterRequests() throws Exception { + MetricsAsserts.getInstance(); + + startCluster(); + + long val = MetricsAsserts.getInstance() + .getCounterValue("cluster_requests", master.getMetrics().getMetricsSource()); + + // sending fake request to master to see how metric value has changed + RegionServerStatusProtos.RegionServerReportRequest.Builder request = + RegionServerStatusProtos.RegionServerReportRequest.newBuilder(); + HRegionServer rs = cluster.getRegionServer(0); + request.setServer(ProtobufUtil.toServerName(rs.getServerName())); + + HBaseProtos.ServerLoad sl = HBaseProtos.ServerLoad.newBuilder() + .setTotalNumberOfRequests(10) + .build(); + request.setLoad(sl); + master.regionServerReport(null, request.build()); + + MetricsAsserts.getInstance().assertCounter("cluster_requests", val + 10, + master.getMetrics().getMetricsSource()); + master.stopMaster(); + } +} Index: hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java (revision 1363838) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java (working copy) @@ -29,7 +29,6 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -49,6 +48,7 @@ import org.apache.hadoop.hbase.Abortable; import org.apache.hadoop.hbase.Chore; import org.apache.hadoop.hbase.ClusterStatus; +import org.apache.hadoop.hbase.CompatibilitySingletonFactory; import org.apache.hadoop.hbase.DeserializationException; import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HConstants; @@ -79,8 +79,9 @@ import org.apache.hadoop.hbase.MasterMonitorProtocol; import org.apache.hadoop.hbase.MasterAdminProtocol; import org.apache.hadoop.hbase.RegionServerStatusProtocol; +import org.apache.hadoop.hbase.master.metrics.MXBeanImpl; +import org.apache.hadoop.hbase.metrics.MBeanSource; import org.apache.hadoop.hbase.protobuf.ProtobufUtil; -import org.apache.hadoop.hbase.protobuf.RequestConverter; import org.apache.hadoop.hbase.ipc.ProtocolSignature; import org.apache.hadoop.hbase.ipc.RpcServer; import org.apache.hadoop.hbase.master.balancer.LoadBalancerFactory; @@ -388,6 +389,10 @@ } + MasterMetrics getMetrics() { + return metrics; + } + /** * Main processing loop for the HMaster. *
    @@ -2209,10 +2214,9 @@ /** * Register bean with platform management server */ - @SuppressWarnings("deprecation") void registerMBean() { MXBeanImpl mxBeanInfo = MXBeanImpl.init(this); - MBeanUtil.registerMBean("Master", "Master", mxBeanInfo); + mxBean = CompatibilitySingletonFactory.getInstance(MBeanSource.class).register("hbase", "HMaster,sub=MXBean", mxBeanInfo); LOG.info("Registered HMaster MXBean"); } } Index: hbase-server/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterMetrics.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterMetrics.java (revision 1363838) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterMetrics.java (working copy) @@ -17,25 +17,11 @@ */ package org.apache.hadoop.hbase.master.metrics; -import java.io.IOException; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.classification.InterfaceAudience; -import org.apache.hadoop.hbase.metrics.HBaseInfo; -import org.apache.hadoop.hbase.metrics.MetricsRate; -import org.apache.hadoop.hbase.metrics.histogram.MetricsHistogram; -import org.apache.hadoop.metrics.ContextFactory; -import org.apache.hadoop.metrics.MetricsContext; -import org.apache.hadoop.metrics.MetricsRecord; -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.MetricsLongValue; -import org.apache.hadoop.metrics.util.MetricsRegistry; +import org.apache.hadoop.hbase.CompatibilitySingletonFactory; - /** * This class is for maintaining the various master statistics * and publishing them through the metrics interfaces. @@ -44,131 +30,46 @@ * these variables (objects) have methods to update their values. */ @InterfaceAudience.Private -public class MasterMetrics implements Updater { +public class MasterMetrics { private final Log LOG = LogFactory.getLog(this.getClass()); - private final MetricsRecord metricsRecord; - private final MetricsRegistry registry = new MetricsRegistry(); - private final MasterStatistics masterStatistics; + private MasterMetricsSource mms; - private long lastUpdate = System.currentTimeMillis(); - private long lastExtUpdate = System.currentTimeMillis(); - private long extendedPeriod = 0; -/* - * Count of requests to the cluster since last call to metrics update - */ - private final MetricsRate cluster_requests = - new MetricsRate("cluster_requests", registry); - - /** Time it takes to finish HLog.splitLog() */ - final MetricsHistogram splitTime = new MetricsHistogram("splitTime", registry); - - /** Size of HLog files being split */ - final MetricsHistogram splitSize = new MetricsHistogram("splitSize", registry); - - /** - * Regions in Transition metrics such as number of RIT regions, oldest - * RIT time and number of such regions that are in transition - * for more than a specified threshold. - */ - public final MetricsIntValue ritCount = - new MetricsIntValue("ritCount", registry); - public final MetricsIntValue ritCountOverThreshold = - new MetricsIntValue("ritCountOverThreshold", registry); - public final MetricsLongValue ritOldestAge = - new MetricsLongValue("ritOldestAge", registry); - public MasterMetrics(final String name) { - MetricsContext context = MetricsUtil.getContext("hbase"); - metricsRecord = MetricsUtil.createRecord(context, "master"); - metricsRecord.setTag("Master", name); - context.registerUpdater(this); - JvmMetrics.init("Master", name); - HBaseInfo.init(); - - // expose the MBean for metrics - masterStatistics = new MasterStatistics(this.registry); - - // get custom attributes - try { - Object m = - ContextFactory.getFactory().getAttribute("hbase.extendedperiod"); - if (m instanceof String) { - this.extendedPeriod = Long.parseLong((String) m)*1000; - } - } catch (IOException ioe) { - LOG.info("Couldn't load ContextFactory for Metrics config info"); - } - - LOG.info("Initialized"); + mms = CompatibilitySingletonFactory.getInstance(MasterMetricsSource.class); } - public void shutdown() { - if (masterStatistics != null) - masterStatistics.shutdown(); + // for unit-test usage + public MasterMetricsSource getMetricsSource() { + return mms; } /** - * Since this object is a registered updater, this method will be called - * periodically, e.g. every 5 seconds. - * @param unused - */ - public void doUpdates(MetricsContext unused) { - synchronized (this) { - this.lastUpdate = System.currentTimeMillis(); - - // has the extended period for long-living stats elapsed? - if (this.extendedPeriod > 0 && - this.lastUpdate - this.lastExtUpdate >= this.extendedPeriod) { - this.lastExtUpdate = this.lastUpdate; - this.splitTime.clear(); - this.splitSize.clear(); - this.resetAllMinMax(); - } - - this.cluster_requests.pushMetric(metricsRecord); - this.splitTime.pushMetric(metricsRecord); - this.splitSize.pushMetric(metricsRecord); - this.ritCount.pushMetric(metricsRecord); - this.ritCountOverThreshold.pushMetric(metricsRecord); - this.ritOldestAge.pushMetric(metricsRecord); - } - this.metricsRecord.update(); - } - - public void resetAllMinMax() { - // Nothing to do - } - - /** * Record a single instance of a split * @param time time that the split took * @param size length of original HLogs that were split */ public synchronized void addSplit(long time, long size) { - splitTime.update(time); - splitSize.update(size); - } - /** - * @return Count of requests. - */ - public float getRequests() { - return this.cluster_requests.getPreviousIntervalValue(); + //TODO use new metrics histogram + } /** * @param inc How much to add to requests. */ public void incrementRequests(final int inc) { - this.cluster_requests.inc(inc); + mms.incRequests(inc); + } + + /** * set new value for number of regions in transition. * @param ritCount */ public void updateRITCount(int ritCount) { - this.ritCount.set(ritCount); + mms.setRIT(ritCount); } /** @@ -177,13 +78,13 @@ * @param ritCountOverThreshold */ public void updateRITCountOverThreshold(int ritCountOverThreshold) { - this.ritCountOverThreshold.set(ritCountOverThreshold); + mms.setRITCountOverThreshold(ritCountOverThreshold); } /** * update the timestamp for oldest region in transition metrics. * @param timestamp */ public void updateRITOldestAge(long timestamp) { - this.ritOldestAge.set(timestamp); + mms.setRITOldestAge(timestamp); } } Index: hbase-server/src/main/java/org/apache/hadoop/hbase/master/metrics/MXBean.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/metrics/MXBean.java (revision 0) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/metrics/MXBean.java (revision 0) @@ -0,0 +1,118 @@ +/** + * 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.master.metrics; + +import java.util.Map; + +import org.apache.hadoop.classification.InterfaceStability.Evolving; +import org.apache.hadoop.hbase.ServerLoad; + +/** + * This is the JMX management interface for Hbase master information + */ +@Evolving +public interface MXBean { + + /** + * Required for MXBean implementation + */ + public static interface RegionsInTransitionInfo { + /** + * Name of region in transition + */ + public String getRegionName(); + /** + * Current transition state + */ + public String getRegionState(); + /** + * Get Region Server name + */ + public String getRegionServerName(); + /** + * Get last update time + */ + public long getLastUpdateTime(); + } + + /** + * Get ServerName + */ + public String getServerName(); + + /** + * Get Average Load + * @return Average Load + */ + public double getAverageLoad(); + + /** + * Get the Cluster ID + * @return Cluster ID + */ + public String getClusterId(); + + /** + * Get the Zookeeper Quorum Info + * @return Zookeeper Quorum Info + */ + public String getZookeeperQuorum(); + + /** + * Get the co-processors + * @return Co-processors + */ + public String[] getCoprocessors(); + + /** + * Get hbase master start time + * @return Start time of master in milliseconds + */ + public long getMasterStartTime(); + + /** + * Get the hbase master active time + * @return Time in milliseconds when master became active + */ + public long getMasterActiveTime(); + + /** + * Whether this master is the active master + * @return True if this is the active master + */ + public boolean getIsActiveMaster(); + + /** + * Get the live region servers + * @return Live region servers + */ + public int getRegionServers(); + + /** + * Get the dead region servers + * @return Dead region Servers + */ + public String[] getDeadRegionServers(); + + /** + * Get information on regions in transition + * @return Regions in transition + */ + public RegionsInTransitionInfo[] getRegionsInTransition(); + +} Index: hbase-server/src/main/java/org/apache/hadoop/hbase/master/metrics/MXBeanImpl.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/metrics/MXBeanImpl.java (revision 0) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/metrics/MXBeanImpl.java (revision 0) @@ -0,0 +1,145 @@ +/** + * 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.master.metrics; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.hadoop.hbase.ServerLoad; +import org.apache.hadoop.hbase.ServerName; +import org.apache.hadoop.hbase.master.AssignmentManager.RegionState; +import org.apache.hadoop.hbase.master.HMaster; + +/** + * Impl for exposing HMaster Information through JMX + */ +public class MXBeanImpl implements MXBean { + + private final HMaster master; + + private static MXBeanImpl instance = null; + public synchronized static MXBeanImpl init(final HMaster master) { + if (instance == null) { + instance = new MXBeanImpl(master); + } + return instance; + } + + protected MXBeanImpl(final HMaster master) { + this.master = master; + } + + @Override + public double getAverageLoad() { + return master.getAverageLoad(); + } + + @Override + public String getClusterId() { + return master.getClusterId(); + } + + @Override + public String getZookeeperQuorum() { + return master.getZooKeeperWatcher().getQuorum(); + } + + @Override + public String[] getCoprocessors() { + return master.getCoprocessors(); + } + + @Override + public long getMasterStartTime() { + return master.getMasterStartTime(); + } + + @Override + public long getMasterActiveTime() { + return master.getMasterActiveTime(); + } + + @Override + public int getRegionServers() { + return this.master.getServerManager().getOnlineServers().size(); + } + + @Override + public String[] getDeadRegionServers() { + List deadServers = new ArrayList(); + for (ServerName name : master.getServerManager().getDeadServers()) { + deadServers.add(name.getHostAndPort()); + } + return deadServers.toArray(new String[0]); + } + + @Override + public RegionsInTransitionInfo[] getRegionsInTransition() { + List info = + new ArrayList(); + for (final Entry entry : + master.getAssignmentManager().copyRegionsInTransition().entrySet()) { + RegionsInTransitionInfo innerinfo = new RegionsInTransitionInfo() { + + @Override + public String getRegionState() { + return entry.getValue().getState().toString(); + } + + @Override + public String getRegionName() { + return entry.getKey(); + } + + @Override + public long getLastUpdateTime() { + return entry.getValue().getStamp(); + } + + @Override + public String getRegionServerName() { + ServerName serverName = entry.getValue().getServerName(); + if (serverName != null) { + return serverName.getServerName(); + } + else { + return ""; + } + } + }; + info.add(innerinfo); + } + RegionsInTransitionInfo[] data = + new RegionsInTransitionInfo[info.size()]; + info.toArray(data); + return data; + } + + @Override + public String getServerName() { + return master.getServerName().getServerName(); + } + + @Override + public boolean getIsActiveMaster() { + return master.isActiveMaster(); + } +} Index: hbase-server/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationSourceMetrics.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationSourceMetrics.java (revision 1363838) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationSourceMetrics.java (working copy) @@ -21,6 +21,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.hbase.CompatibilitySingletonFactory; /** * This class is for maintaining the various replication statistics for a source and publishing them @@ -65,7 +66,7 @@ logEditsFilteredKey = "source." + id + ".logEditsFiltered"; shippedBatchesKey = "source." + this.id + ".shippedBatches"; shippedOpsKey = "source." + this.id + ".shippedOps"; - rms = ReplicationMetricsSourceFactory.getInstance(); + rms = CompatibilitySingletonFactory.getInstance(ReplicationMetricsSource.class); } /** Index: hbase-server/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationSinkMetrics.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationSinkMetrics.java (revision 1363838) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationSinkMetrics.java (working copy) @@ -19,8 +19,7 @@ package org.apache.hadoop.hbase.replication.regionserver.metrics; import org.apache.hadoop.classification.InterfaceAudience; -import org.apache.hadoop.hbase.replication.regionserver.metrics.ReplicationMetricsSource; -import org.apache.hadoop.hbase.replication.regionserver.metrics.ReplicationMetricsSourceFactory; +import org.apache.hadoop.hbase.CompatibilitySingletonFactory; /** * This class is for maintaining the various replication statistics for a sink and publishing them @@ -36,7 +35,7 @@ private ReplicationMetricsSource rms; public ReplicationSinkMetrics() { - rms = ReplicationMetricsSourceFactory.getInstance(); + rms = CompatibilitySingletonFactory.getInstance(ReplicationMetricsSource.class); } /** Index: hbase-server/pom.xml =================================================================== --- hbase-server/pom.xml (revision 1363838) +++ hbase-server/pom.xml (working copy) @@ -497,6 +497,22 @@ jettison test + + org.apache.hbase + hbase-hadoop-compat + ${project.version} + test-jar + true + test + + + org.apache.hbase + ${compat.module} + ${project.version} + test-jar + true + test + Index: hbase-hadoop1-compat/src/test/java/org/apache/hadoop/hbase/metrics/MetricsAssertsImpl.java =================================================================== --- hbase-hadoop1-compat/src/test/java/org/apache/hadoop/hbase/metrics/MetricsAssertsImpl.java (revision 0) +++ hbase-hadoop1-compat/src/test/java/org/apache/hadoop/hbase/metrics/MetricsAssertsImpl.java (revision 0) @@ -0,0 +1,62 @@ +/** + * 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.hadoop.metrics2.MetricsBuilder; +import org.apache.hadoop.metrics2.MetricsRecordBuilder; +import org.mockito.Mockito; +import org.mockito.internal.stubbing.defaultanswers.ReturnsMocks; +import org.mockito.invocation.InvocationOnMock; + +public class MetricsAssertsImpl extends MetricsAsserts { + @Override + public void assertCounter(String name, long value, BaseMetricsSource ms) { + BaseMetricsSourceImpl bms = (BaseMetricsSourceImpl) ms; + org.apache.hadoop.test.MetricsAsserts.assertCounter(name, value, bms); + } + + @Override + public long getCounterValue(final String name, BaseMetricsSource ms) { + // This looks ugly, but this is is the only usable way I found + // to get metrics value in hadoop 1.0... + final long[] value = new long[1]; + final MetricsRecordBuilder mrb = Mockito.mock(MetricsRecordBuilder.class, new ReturnsMocks() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + Object[] args = invocation.getArguments(); + if (args[0].equals(name)) { // TODO: remove check? We do it in MetricsBuilder impl below + value[0] = (Long) args[2]; // args are: name, description, value + } + return invocation.getMock(); + } + }); + + BaseMetricsSourceImpl bms = (BaseMetricsSourceImpl) ms; + MetricsBuilder mb = new MetricsBuilder() { + @Override + public MetricsRecordBuilder addRecord(String s) { + return mrb; + } + }; + + bms.getMetrics(mb, true); + + return value[0]; + } +} Index: hbase-hadoop1-compat/src/test/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceImplTest.java =================================================================== --- hbase-hadoop1-compat/src/test/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceImplTest.java (revision 1363838) +++ hbase-hadoop1-compat/src/test/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceImplTest.java (working copy) @@ -18,6 +18,7 @@ package org.apache.hadoop.hbase.replication.regionserver.metrics; +import org.apache.hadoop.hbase.CompatibilitySingletonFactory; import org.junit.Test; import static org.junit.Assert.assertTrue; @@ -29,7 +30,8 @@ @Test public void testGetInstance() throws Exception { - ReplicationMetricsSource rms = ReplicationMetricsSourceFactory.getInstance(); + ReplicationMetricsSource rms = CompatibilitySingletonFactory + .getInstance(ReplicationMetricsSource.class); assertTrue(rms instanceof ReplicationMetricsSourceImpl); } } Index: hbase-hadoop1-compat/src/test/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceImplTest.java =================================================================== --- hbase-hadoop1-compat/src/test/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceImplTest.java (revision 0) +++ hbase-hadoop1-compat/src/test/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceImplTest.java (revision 0) @@ -0,0 +1,40 @@ +/** + * 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.master.metrics; + +import org.apache.hadoop.hbase.CompatibilitySingletonFactory; +import org.junit.Test; + +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +/** + * Test for MasterMetricsSourceImpl + */ +public class MasterMetricsSourceImplTest { + + @Test + public void testGetInstance() throws Exception { + MasterMetricsSource rms = CompatibilitySingletonFactory + .getInstance(MasterMetricsSource.class); + assertTrue(rms instanceof MasterMetricsSourceImpl); + assertSame(rms, CompatibilitySingletonFactory.getInstance(MasterMetricsSource.class)); + } + +} Index: hbase-hadoop1-compat/src/test/resources/META-INF/services/org.apache.hadoop.hbase.metrics.MetricsAsserts =================================================================== --- hbase-hadoop1-compat/src/test/resources/META-INF/services/org.apache.hadoop.hbase.metrics.MetricsAsserts (revision 0) +++ hbase-hadoop1-compat/src/test/resources/META-INF/services/org.apache.hadoop.hbase.metrics.MetricsAsserts (revision 0) @@ -0,0 +1 @@ +org.apache.hadoop.hbase.metrics.MetricsAssertsImpl \ No newline at end of file Index: hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/metrics/BaseMetricsSourceImpl.java =================================================================== --- hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/metrics/BaseMetricsSourceImpl.java (revision 1363838) +++ hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/metrics/BaseMetricsSourceImpl.java (working copy) @@ -24,13 +24,14 @@ import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; import org.apache.hadoop.metrics2.lib.MetricMutableCounterLong; import org.apache.hadoop.metrics2.lib.MetricMutableGaugeLong; +import org.apache.hadoop.metrics2.source.JvmMetricsSource; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; /** - * Hadoop 1 implementation of BaseMetricsSource + * Hadoop 1 metrics 1 implementation of BaseMetricsSource */ public class BaseMetricsSourceImpl implements BaseMetricsSource, MetricsSource { @@ -46,6 +47,8 @@ protected String metricsName; protected String metricsDescription; + private JvmMetricsSource jvmMetricsSource; + public BaseMetricsSourceImpl( String metricsName, String metricsDescription, @@ -58,10 +61,13 @@ //Not too worried about mutli-threaded here as all it does is spam the logs. defaultMetricsSystemInited = true; DefaultMetricsSystem.initialize(HBASE_METRICS_SYSTEM_NAME); + + //If this is the first time through register a jvm source. + jvmMetricsSource = JvmMetricsSource.create(metricsName, ""); } //Register this instance. - DefaultMetricsSystem.registerSource(this.metricsContext, this.metricsDescription, this); + DefaultMetricsSystem.INSTANCE.registerSource(this.metricsContext, this.metricsDescription, this); } /** @@ -154,7 +160,7 @@ * @param potentialStartingValue value of the new counter if we have to create it. * @return */ - private MetricMutableGaugeLong getLongGauge(String gaugeName, long potentialStartingValue) { + protected MetricMutableGaugeLong getLongGauge(String gaugeName, long potentialStartingValue) { //Try and get the guage. MetricMutableGaugeLong gauge = gauges.get(gaugeName); @@ -184,7 +190,7 @@ * @param potentialStartingValue starting value if we have to create a new counter * @return */ - private MetricMutableCounterLong getLongCounter(String counterName, long potentialStartingValue) { + protected MetricMutableCounterLong getLongCounter(String counterName, long potentialStartingValue) { //See getLongGauge for description on how this works. MetricMutableCounterLong counter = counters.get(counterName); if (counter == null) { Index: hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/metrics/MBeanSourceImpl.java =================================================================== --- hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/metrics/MBeanSourceImpl.java (revision 0) +++ hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/metrics/MBeanSourceImpl.java (revision 0) @@ -0,0 +1,41 @@ +/** + * 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.hadoop.metrics2.util.MBeans; + +import javax.management.ObjectName; + +/** + * Hadoop1 metrics2 implementation of an object that registers MBeans. + */ +public class MBeanSourceImpl implements MBeanSource { + + /** + * Register an mbean with the underlying metrics system + * @param serviceName Metrics service/system name + * @param nameName name of the metrics obejct to expose + * @param theMbean the actual MBean + * @return ObjectName from jmx + */ + @Override + public ObjectName register(String serviceName, String nameName, Object theMbean) { + return MBeans.register(serviceName, nameName, theMbean); + } +} Index: hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceImpl.java =================================================================== --- hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceImpl.java (revision 1363838) +++ hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceImpl.java (working copy) @@ -28,10 +28,8 @@ public class ReplicationMetricsSourceImpl extends BaseMetricsSourceImpl implements ReplicationMetricsSource { - public static final String METRICS_NAME = "ReplicationMetrics"; - public static final String METRICS_CONTEXT = "replicationmetrics"; - public static final String METRICS_DESCRIPTION = "Metrics about HBase replication"; + public ReplicationMetricsSourceImpl() { this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT); } Index: hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceImpl.java =================================================================== --- hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceImpl.java (revision 0) +++ hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceImpl.java (revision 0) @@ -0,0 +1,66 @@ +/** + * 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.master.metrics; + +import org.apache.hadoop.hbase.metrics.BaseMetricsSourceImpl; +import org.apache.hadoop.metrics2.lib.MetricMutableCounterLong; +import org.apache.hadoop.metrics2.lib.MetricMutableGaugeLong; + +/** + * + */ +public class MasterMetricsSourceImpl extends BaseMetricsSourceImpl implements MasterMetricsSource { + + MetricMutableCounterLong clusterRequestsCounter; + MetricMutableGaugeLong ritGauge; + MetricMutableGaugeLong ritCountOverThresholdGauge; + MetricMutableGaugeLong ritOldestAgeGauge; + + + public MasterMetricsSourceImpl() { + this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT); + } + + public MasterMetricsSourceImpl(String metricsName, + String metricsDescription, + String metricsContext) { + super(metricsName, metricsDescription, metricsContext); + + clusterRequestsCounter = getLongCounter("cluster_requests", 0); + ritGauge = getLongGauge("ritCount", 0); + ritCountOverThresholdGauge = getLongGauge("ritCountOverThreshold", 0); + ritOldestAgeGauge = getLongGauge("ritOldestAge", 0); + } + + public void incRequests(final int inc) { + this.clusterRequestsCounter.incr(inc); + } + + public void setRIT(int ritCount) { + ritGauge.set(ritCount); + } + + public void setRITCountOverThreshold(int ritCount) { + ritCountOverThresholdGauge.set(ritCount); + } + + public void setRITOldestAge(long ritCount) { + ritCountOverThresholdGauge.set(ritCount); + } +} Index: hbase-hadoop1-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.master.metrics.MasterMetricsSource =================================================================== --- hbase-hadoop1-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.master.metrics.MasterMetricsSource (revision 0) +++ hbase-hadoop1-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.master.metrics.MasterMetricsSource (revision 0) @@ -0,0 +1 @@ +org.apache.hadoop.hbase.master.metrics.MasterMetricsSourceImpl Index: hbase-hadoop1-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.metrics.MBeanSource =================================================================== --- hbase-hadoop1-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.metrics.MBeanSource (revision 0) +++ hbase-hadoop1-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.metrics.MBeanSource (revision 0) @@ -0,0 +1 @@ +org.apache.hadoop.hbase.metrics.MBeanSourceImpl Index: hbase-hadoop1-compat/pom.xml =================================================================== --- hbase-hadoop1-compat/pom.xml (revision 1363838) +++ hbase-hadoop1-compat/pom.xml (working copy) @@ -93,5 +93,13 @@ true test + + org.apache.hbase + hbase-hadoop-compat + ${project.version} + test-jar + true + test + Index: hbase-hadoop2-compat/src/test/java/org/apache/hadoop/hbase/metrics/MetricsAssertsImpl.java =================================================================== --- hbase-hadoop2-compat/src/test/java/org/apache/hadoop/hbase/metrics/MetricsAssertsImpl.java (revision 0) +++ hbase-hadoop2-compat/src/test/java/org/apache/hadoop/hbase/metrics/MetricsAssertsImpl.java (revision 0) @@ -0,0 +1,33 @@ +/** + * 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; + +public class MetricsAssertsImpl extends MetricsAsserts { + @Override + public void assertCounter(String name, long value, BaseMetricsSource ms) { + BaseMetricsSourceImpl bms = (BaseMetricsSourceImpl) ms; + org.apache.hadoop.test.MetricsAsserts.assertCounter(name, value, bms); + } + + @Override + public long getCounterValue(String name, BaseMetricsSource ms) { + BaseMetricsSourceImpl bms = (BaseMetricsSourceImpl) ms; + return bms.getCounter(name).value(); + } +} Index: hbase-hadoop2-compat/src/test/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceImplTest.java =================================================================== --- hbase-hadoop2-compat/src/test/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceImplTest.java (revision 1363838) +++ hbase-hadoop2-compat/src/test/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceImplTest.java (working copy) @@ -18,6 +18,7 @@ package org.apache.hadoop.hbase.replication.regionserver.metrics; +import org.apache.hadoop.hbase.CompatibilitySingletonFactory; import org.junit.Test; import static org.junit.Assert.assertTrue; @@ -27,7 +28,8 @@ @Test public void testGetInstance() throws Exception { - ReplicationMetricsSource rms = ReplicationMetricsSourceFactory.getInstance(); + ReplicationMetricsSource rms = CompatibilitySingletonFactory + .getInstance(ReplicationMetricsSource.class); assertTrue(rms instanceof ReplicationMetricsSourceImpl); } } Index: hbase-hadoop2-compat/src/test/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceImplTest.java =================================================================== --- hbase-hadoop2-compat/src/test/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceImplTest.java (revision 0) +++ hbase-hadoop2-compat/src/test/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceImplTest.java (revision 0) @@ -0,0 +1,40 @@ +/** + * 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.master.metrics; + +import org.apache.hadoop.hbase.CompatibilitySingletonFactory; +import org.junit.Test; + +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +/** + * Test for MasterMetricsSourceImpl + */ +public class MasterMetricsSourceImplTest { + + @Test + public void testGetInstance() throws Exception { + MasterMetricsSource rms = CompatibilitySingletonFactory + .getInstance(MasterMetricsSource.class); + assertTrue(rms instanceof MasterMetricsSourceImpl); + assertSame(rms, CompatibilitySingletonFactory.getInstance(MasterMetricsSource.class)); + } + +} Index: hbase-hadoop2-compat/src/test/resources/META-INF/services/org.apache.hadoop.hbase.metrics.MetricsAsserts =================================================================== --- hbase-hadoop2-compat/src/test/resources/META-INF/services/org.apache.hadoop.hbase.metrics.MetricsAsserts (revision 0) +++ hbase-hadoop2-compat/src/test/resources/META-INF/services/org.apache.hadoop.hbase.metrics.MetricsAsserts (revision 0) @@ -0,0 +1 @@ +org.apache.hadoop.hbase.metrics.MetricsAssertsImpl \ No newline at end of file Index: hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/metrics/BaseMetricsSourceImpl.java =================================================================== --- hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/metrics/BaseMetricsSourceImpl.java (revision 1363838) +++ hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/metrics/BaseMetricsSourceImpl.java (working copy) @@ -25,6 +25,7 @@ import org.apache.hadoop.metrics2.lib.HBaseMetricsFactory; import org.apache.hadoop.metrics2.lib.MutableCounterLong; import org.apache.hadoop.metrics2.lib.MutableGaugeLong; +import org.apache.hadoop.metrics2.source.JvmMetrics; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -45,6 +46,8 @@ protected String metricsName; protected String metricsDescription; + private JvmMetrics jvmMetricsSource; + public BaseMetricsSourceImpl(String metricsName, String metricsDescription, String metricsContext) { @@ -56,6 +59,7 @@ //Not too worried about mutlithread here as all it does is spam the logs. defaultMetricsSystemInited = true; DefaultMetricsSystem.initialize(HBASE_METRICS_SYSTEM_NAME); + jvmMetricsSource = JvmMetrics.create(metricsName, "", DefaultMetricsSystem.instance()); } DefaultMetricsSystem.instance().register(this.metricsContext, this.metricsDescription, this); @@ -145,7 +149,7 @@ * @param potentialStartingValue value of the new counter if we have to create it. * @return */ - private MutableGaugeLong getLongGauge(String gaugeName, long potentialStartingValue) { + protected MutableGaugeLong getLongGauge(String gaugeName, long potentialStartingValue) { //Try and get the guage. MutableGaugeLong gaugeInt = gauges.get(gaugeName); @@ -176,7 +180,7 @@ * @param potentialStartingValue starting value if we have to create a new counter * @return */ - private MutableCounterLong getLongCounter(String counterName, long potentialStartingValue) { + protected MutableCounterLong getLongCounter(String counterName, long potentialStartingValue) { //See getLongGauge for description on how this works. MutableCounterLong counter = counters.get(counterName); if (counter == null) { @@ -190,4 +194,11 @@ return counter; } + MutableCounterLong getCounter(String key) { + return counters.get(key); + } + + MutableGaugeLong getGauge(String key) { + return gauges.get(key); + } } Index: hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/metrics/MBeanSourceImpl.java =================================================================== --- hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/metrics/MBeanSourceImpl.java (revision 0) +++ hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/metrics/MBeanSourceImpl.java (revision 0) @@ -0,0 +1,41 @@ +/** + * 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.hadoop.metrics2.util.MBeans; + +import javax.management.ObjectName; + +/** + * Hadoop2 metrics2 implementation of an object that registers MBeans. + */ +public class MBeanSourceImpl implements MBeanSource { + + /** + * Register an mbean with the underlying metrics system + * @param serviceName Metrics service/system name + * @param nameName name of the metrics obejct to expose + * @param theMbean the actual MBean + * @return ObjectName from jmx + */ + @Override + public ObjectName register(String serviceName, String nameName, Object theMbean) { + return MBeans.register(serviceName, nameName, theMbean); + } +} Index: hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceImpl.java =================================================================== --- hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceImpl.java (revision 1363838) +++ hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceImpl.java (working copy) @@ -28,10 +28,6 @@ public class ReplicationMetricsSourceImpl extends BaseMetricsSourceImpl implements ReplicationMetricsSource { - public static final String METRICS_NAME = "ReplicationMetrics"; - public static final String METRICS_CONTEXT = "replicationmetrics"; - public static final String METRICS_DESCRIPTION = "Metrics about HBase replication"; - public ReplicationMetricsSourceImpl() { this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT); } Index: hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceImpl.java =================================================================== --- hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceImpl.java (revision 0) +++ hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceImpl.java (revision 0) @@ -0,0 +1,65 @@ +/** + * 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.master.metrics; + +import org.apache.hadoop.hbase.metrics.BaseMetricsSourceImpl; +import org.apache.hadoop.metrics2.lib.MutableCounterLong; +import org.apache.hadoop.metrics2.lib.MutableGaugeLong; + +/** + * + */ +public class MasterMetricsSourceImpl extends BaseMetricsSourceImpl implements MasterMetricsSource { + + MutableCounterLong clusterRequestsCounter; + MutableGaugeLong ritGauge; + MutableGaugeLong ritCountOverThresholdGauge; + MutableGaugeLong ritOldestAgeGauge; + + public MasterMetricsSourceImpl() { + this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT); + } + + public MasterMetricsSourceImpl(String metricsName, + String metricsDescription, + String metricsContext) { + super(metricsName, metricsDescription, metricsContext); + + clusterRequestsCounter = getLongCounter("cluster_requests", 0); + ritGauge = getLongGauge("ritCount", 0); + ritCountOverThresholdGauge = getLongGauge("ritCountOverThreshold", 0); + ritOldestAgeGauge = getLongGauge("ritOldestAge", 0); + } + + public void incRequests(final int inc) { + this.clusterRequestsCounter.incr(inc); + } + + public void setRIT(int ritCount) { + ritGauge.set(ritCount); + } + + public void setRITCountOverThreshold(int ritCount) { + ritCountOverThresholdGauge.set(ritCount); + } + + public void setRITOldestAge(long ritCount) { + ritCountOverThresholdGauge.set(ritCount); + } +} Index: hbase-hadoop2-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.master.metrics.MasterMetricsSource =================================================================== --- hbase-hadoop2-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.master.metrics.MasterMetricsSource (revision 0) +++ hbase-hadoop2-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.master.metrics.MasterMetricsSource (revision 0) @@ -0,0 +1 @@ +org.apache.hadoop.hbase.master.metrics.MasterMetricsSourceImpl Index: hbase-hadoop2-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.metrics.MBeanSource =================================================================== --- hbase-hadoop2-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.metrics.MBeanSource (revision 0) +++ hbase-hadoop2-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.metrics.MBeanSource (revision 0) @@ -0,0 +1 @@ +org.apache.hadoop.hbase.metrics.MBeanSourceImpl Index: hbase-hadoop2-compat/pom.xml =================================================================== --- hbase-hadoop2-compat/pom.xml (revision 1363838) +++ hbase-hadoop2-compat/pom.xml (working copy) @@ -129,5 +129,13 @@ hadoop-minicluster ${hadoop-two.version} + + org.apache.hbase + hbase-hadoop-compat + ${project.version} + test-jar + true + test + Index: hbase-hadoop-compat/src/test/java/org/apache/hadoop/hbase/metrics/MetricsAsserts.java =================================================================== --- hbase-hadoop-compat/src/test/java/org/apache/hadoop/hbase/metrics/MetricsAsserts.java (revision 0) +++ hbase-hadoop-compat/src/test/java/org/apache/hadoop/hbase/metrics/MetricsAsserts.java (revision 0) @@ -0,0 +1,74 @@ +/** + * 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 java.util.ServiceLoader; + +import org.apache.hadoop.hbase.metrics.BaseMetricsSource; + +/** + * Class to load MetricsAsserts from the class path. Will only return a singleton + * instance. + */ +public abstract class MetricsAsserts { + + private static MetricsAsserts factory = null; + public static final String EXCEPTION_STRING = "Could not create a MetricsAsserts metrics source. " + + "Is the hadoop compatibility jar on the classpath?"; + + + /** + * Verifies counter value + * @param name name of counter + * @param value value to verify against + * @param ms metrics source + */ + public abstract void assertCounter(String name, long value, BaseMetricsSource ms); + + /** + * Gets value of a counter. Handy in unit-tests + * @param name name of counter + * @param ms metrics source + * @return + */ + public abstract long getCounterValue(String name, BaseMetricsSource ms); + + /** + * Get the singleton instance of ReplicationMetricsSource + * + * @return the singleton + */ + public static synchronized MetricsAsserts getInstance() { + if (factory == null) { + try { + factory = ServiceLoader.load(MetricsAsserts.class).iterator().next(); + } catch (Exception e) { + throw new RuntimeException(EXCEPTION_STRING, e); + } catch (Error e) { + throw new RuntimeException(EXCEPTION_STRING, e); + } + + // If there was nothing returned and no exception then throw an exception. + if (factory == null) { + throw new RuntimeException(EXCEPTION_STRING); + } + } + return factory; + } +} Index: hbase-hadoop-compat/src/test/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceFactoryTest.java =================================================================== --- hbase-hadoop-compat/src/test/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceFactoryTest.java (revision 1363838) +++ hbase-hadoop-compat/src/test/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceFactoryTest.java (working copy) @@ -18,17 +18,18 @@ package org.apache.hadoop.hbase.replication.regionserver.metrics; +import org.apache.hadoop.hbase.CompatibilitySingletonFactory; import org.junit.Test; /** - * Test for the ReplicationMetricsSourceFactory + * Test for the CompatibilitySingletonFactory and building ReplicationMetricsSource */ public class ReplicationMetricsSourceFactoryTest { @Test(expected=RuntimeException.class) public void testGetInstanceNoHadoopCompat() throws Exception { //This should throw an exception because there is no compat lib on the class path. - ReplicationMetricsSourceFactory.getInstance(); + CompatibilitySingletonFactory.getInstance(ReplicationMetricsSource.class); } } Index: hbase-hadoop-compat/src/test/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceFactoryTest.java =================================================================== --- hbase-hadoop-compat/src/test/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceFactoryTest.java (revision 0) +++ hbase-hadoop-compat/src/test/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceFactoryTest.java (revision 0) @@ -0,0 +1,35 @@ +/** + * 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.master.metrics; + +import org.apache.hadoop.hbase.CompatibilitySingletonFactory; +import org.junit.Test; + +/** + * Test for the CompatibilitySingletonFactory and building MasterMetricsSource + */ +public class MasterMetricsSourceFactoryTest { + + @Test(expected=RuntimeException.class) + public void testGetInstanceNoHadoopCompat() throws Exception { + //This should throw an exception because there is no compat lib on the class path. + CompatibilitySingletonFactory.getInstance(MasterMetricsSource.class); + + } +} Index: hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/CompatibilitySingletonFactory.java =================================================================== --- hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/CompatibilitySingletonFactory.java (revision 0) +++ hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/CompatibilitySingletonFactory.java (revision 0) @@ -0,0 +1,65 @@ +/** + * 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; + +import org.apache.hadoop.hbase.master.metrics.MasterMetricsSource; + +import java.util.HashMap; +import java.util.Map; +import java.util.ServiceLoader; + +/** + * Factory for classes supplied by hadoop compatibility modules. + */ +public class CompatibilitySingletonFactory { + public static final String EXCEPTION_START = "Could not create "; + public static final String EXCEPTION_END = " Is the hadoop compatibility jar on the classpath?"; + + private static final Map instances = new HashMap(); + + /** + * Get the singleton instance of Any classes defined by compatibiliy jar's + * + * @return the singleton + */ + public static synchronized T getInstance(Class klass) { + T instance = (T) instances.get(klass); + if (instance == null) { + try { + instance = ServiceLoader.load(klass).iterator().next(); + } catch (Exception e) { + throw new RuntimeException(createExceptionString(klass), e); + } catch (Error e) { + throw new RuntimeException(createExceptionString(klass), e); + } + + // If there was nothing returned and no exception then throw an exception. + if (instance == null) { + throw new RuntimeException(createExceptionString(klass)); + } + instances.put(klass, instance); + } + return instance; + } + + private static String createExceptionString(Class klass) { + return EXCEPTION_START + klass.toString() + EXCEPTION_END; + } + +} Index: hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/metrics/MBeanSource.java =================================================================== --- hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/metrics/MBeanSource.java (revision 0) +++ hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/metrics/MBeanSource.java (revision 0) @@ -0,0 +1,38 @@ +/** + * 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 javax.management.ObjectName; + +/** + * Object that will register an mbean with the underlying metrics implementation. + */ +public interface MBeanSource { + + /** + * Register an mbean with the underlying metrics system + * @param serviceName Metrics service/system name + * @param nameName name of the metrics obejct to expose + * @param theMbean the actual MBean + * @return ObjectName from jmx + */ + public ObjectName register(String serviceName, String nameName, + Object theMbean); + +} Index: hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSource.java =================================================================== --- hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSource.java (revision 1363838) +++ hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSource.java (working copy) @@ -25,6 +25,19 @@ * hadoop2's metrics2 classes and publishing. */ public interface ReplicationMetricsSource extends BaseMetricsSource { - //Empty interface so that ServiceLoader can find the right implementation. + /** + * The name of the metrics + */ + public static final String METRICS_NAME = "ReplicationMetrics"; + /** + * The name of the metrics context that metrics will be under. + */ + public static final String METRICS_CONTEXT = "replicationmetrics"; + + /** + * A description. + */ + public static final String METRICS_DESCRIPTION = "Metrics about HBase replication"; + } Index: hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSource.java =================================================================== --- hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSource.java (revision 0) +++ hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSource.java (revision 0) @@ -0,0 +1,67 @@ +/** + * 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.master.metrics; + +import org.apache.hadoop.hbase.metrics.BaseMetricsSource; + +/** + * Interface that classes that expose metrics about the master will implement. + */ +public interface MasterMetricsSource extends BaseMetricsSource { + + /** + * The name of the metrics + */ + public static final String METRICS_NAME = "HMaster"; + + /** + * The name of the metrics context that metrics will be under. + */ + public static final String METRICS_CONTEXT = "HMaster,sub=Dynamic"; + + /** + * Description + */ + public static final String METRICS_DESCRIPTION = "Metrics about HBase master server"; + + /** + * Increment the number of request the cluster has seen. + * @param inc Ammount to increment the total by. + */ + public void incRequests(final int inc); + + /** + * Set the number of regions in transition. + * @param ritCount count of the regions in transition. + */ + public void setRIT(int ritCount); + + /** + * Set the count of the number of regions that have been in transition over the threshold time. + * @param ritCountOverThreshold number of regions in transition for longer than threshold. + */ + public void setRITCountOverThreshold(int ritCountOverThreshold); + + /** + * Set the oldest region in transition. + * @param age age of the oldest RIT. + */ + public void setRITOldestAge(long age); + +}