diff --git conf/hadoop-metrics2.properties conf/hadoop-metrics2.properties new file mode 100644 index 0000000..de1ea54 --- /dev/null +++ conf/hadoop-metrics2.properties @@ -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 diff --git hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/CompatibilitySingletonFactory.java hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/CompatibilitySingletonFactory.java new file mode 100644 index 0000000..6fed868 --- /dev/null +++ hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/CompatibilitySingletonFactory.java @@ -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; + +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 { + private static MasterMetricsSource masterMetricsSource = null; + 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; + } + +} diff --git 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 new file mode 100644 index 0000000..2b214f9 --- /dev/null +++ hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSource.java @@ -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); + +} diff --git 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 new file mode 100644 index 0000000..1e0133a --- /dev/null +++ hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/metrics/MBeanSource.java @@ -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); + +} diff --git 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 index 2e4d28d..ccd38b6 100644 --- 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 @@ -25,6 +25,19 @@ import org.apache.hadoop.hbase.metrics.BaseMetricsSource; * 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"; } diff --git hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceFactory.java hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceFactory.java deleted file mode 100644 index 83a829f..0000000 --- hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/replication/regionserver/metrics/ReplicationMetricsSourceFactory.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * 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.replication.regionserver.metrics; - -import java.util.ServiceLoader; - -/** - * Class to load ReplicationMetricsSource from the class path. Will only return a singleton - * instance. - */ -public class ReplicationMetricsSourceFactory { - - private static ReplicationMetricsSource rms = null; - public static final String EXCEPTION_STRING = "Could not create a Replication metrics source. " + - "Is the hadoop compatibility jar on the classpath?"; - - /** - * Get the singleton instance of ReplicationMetricsSource - * - * @return the singleton - */ - public static synchronized ReplicationMetricsSource getInstance() { - if (rms == null) { - try { - rms = ServiceLoader.load(ReplicationMetricsSource.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 (rms == null) { - throw new RuntimeException(EXCEPTION_STRING); - } - } - return rms; - } -} diff --git 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 new file mode 100644 index 0000000..f6fbfee --- /dev/null +++ hbase-hadoop-compat/src/test/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceFactoryTest.java @@ -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); + + } +} diff --git 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 index d82e628..4bb4d75 100644 --- 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 @@ -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); } } diff --git 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 new file mode 100644 index 0000000..d42c686 --- /dev/null +++ hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceImpl.java @@ -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); + } +} diff --git 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 index 189a6a5..cc736f0 100644 --- 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 @@ -24,13 +24,14 @@ import org.apache.hadoop.metrics2.MetricsSource; 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 @@ public class BaseMetricsSourceImpl implements BaseMetricsSource, MetricsSource { protected String metricsName; protected String metricsDescription; + private JvmMetricsSource jvmMetricsSource; + public BaseMetricsSourceImpl( String metricsName, String metricsDescription, @@ -58,10 +61,13 @@ public class BaseMetricsSourceImpl implements BaseMetricsSource, MetricsSource { //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 @@ public class BaseMetricsSourceImpl implements BaseMetricsSource, MetricsSource { * @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 @@ public class BaseMetricsSourceImpl implements BaseMetricsSource, MetricsSource { * @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) { diff --git 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 new file mode 100644 index 0000000..d015be0 --- /dev/null +++ hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/metrics/MBeanSourceImpl.java @@ -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); + } +} diff --git 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 index c0fd8f6..51daedc 100644 --- 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 @@ -28,9 +28,7 @@ import org.apache.hadoop.metrics2.MetricsSource; 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); diff --git 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 new file mode 100644 index 0000000..fcd2f56 --- /dev/null +++ hbase-hadoop1-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.master.metrics.MasterMetricsSource @@ -0,0 +1 @@ +org.apache.hadoop.hbase.master.metrics.MasterMetricsSourceImpl diff --git 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 new file mode 100644 index 0000000..48aeafc --- /dev/null +++ hbase-hadoop1-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.metrics.MBeanSource @@ -0,0 +1 @@ +org.apache.hadoop.hbase.metrics.MBeanSourceImpl diff --git 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 new file mode 100644 index 0000000..000cf69 --- /dev/null +++ hbase-hadoop1-compat/src/test/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceImplTest.java @@ -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)); + } + +} diff --git 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 index 717aca5..66385a9 100644 --- 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 @@ -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 @@ public class ReplicationMetricsSourceImplTest { @Test public void testGetInstance() throws Exception { - ReplicationMetricsSource rms = ReplicationMetricsSourceFactory.getInstance(); + ReplicationMetricsSource rms = CompatibilitySingletonFactory + .getInstance(ReplicationMetricsSource.class); assertTrue(rms instanceof ReplicationMetricsSourceImpl); } } diff --git 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 new file mode 100644 index 0000000..f016bff8 --- /dev/null +++ hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceImpl.java @@ -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); + } +} diff --git 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 index 769b7e9..4748410 100644 --- 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 @@ -25,6 +25,7 @@ import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; 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 @@ public class BaseMetricsSourceImpl implements BaseMetricsSource, MetricsSource { protected String metricsName; protected String metricsDescription; + private JvmMetrics jvmMetricsSource; + public BaseMetricsSourceImpl(String metricsName, String metricsDescription, String metricsContext) { @@ -56,6 +59,7 @@ public class BaseMetricsSourceImpl implements BaseMetricsSource, MetricsSource { //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 @@ public class BaseMetricsSourceImpl implements BaseMetricsSource, MetricsSource { * @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 @@ public class BaseMetricsSourceImpl implements BaseMetricsSource, MetricsSource { * @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) { diff --git 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 new file mode 100644 index 0000000..594c3a1 --- /dev/null +++ hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/metrics/MBeanSourceImpl.java @@ -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); + } +} diff --git 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 index 002316e..e7285dd 100644 --- 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 @@ -28,10 +28,6 @@ import org.apache.hadoop.metrics2.MetricsSource; 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); } diff --git 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 new file mode 100644 index 0000000..fcd2f56 --- /dev/null +++ hbase-hadoop2-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.master.metrics.MasterMetricsSource @@ -0,0 +1 @@ +org.apache.hadoop.hbase.master.metrics.MasterMetricsSourceImpl diff --git 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 new file mode 100644 index 0000000..48aeafc --- /dev/null +++ hbase-hadoop2-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.metrics.MBeanSource @@ -0,0 +1 @@ +org.apache.hadoop.hbase.metrics.MBeanSourceImpl diff --git 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 new file mode 100644 index 0000000..000cf69 --- /dev/null +++ hbase-hadoop2-compat/src/test/java/org/apache/hadoop/hbase/master/metrics/MasterMetricsSourceImplTest.java @@ -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)); + } + +} diff --git 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 index af31c6e..93f1e4a 100644 --- 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 @@ -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 @@ public class ReplicationMetricsSourceImplTest { @Test public void testGetInstance() throws Exception { - ReplicationMetricsSource rms = ReplicationMetricsSourceFactory.getInstance(); + ReplicationMetricsSource rms = CompatibilitySingletonFactory + .getInstance(ReplicationMetricsSource.class); assertTrue(rms instanceof ReplicationMetricsSourceImpl); } } diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java index a97a433..7af6766 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java @@ -29,7 +29,6 @@ import java.util.ArrayList; 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.conf.Configuration; 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.ipc.HBaseServer; 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; @@ -2209,10 +2210,9 @@ Server { /** * 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"); } } diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/master/MXBean.java hbase-server/src/main/java/org/apache/hadoop/hbase/master/MXBean.java deleted file mode 100644 index 535bf95..0000000 --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/MXBean.java +++ /dev/null @@ -1,118 +0,0 @@ -/** - * 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 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 Map 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(); - -} diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/master/MXBeanImpl.java hbase-server/src/main/java/org/apache/hadoop/hbase/master/MXBeanImpl.java deleted file mode 100644 index 70d4581..0000000 --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/MXBeanImpl.java +++ /dev/null @@ -1,149 +0,0 @@ -/** - * 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 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; - -/** - * 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 Map getRegionServers() { - Map data = new HashMap(); - for (final Entry entry: - this.master.getServerManager().getOnlineServers().entrySet()) { - data.put(entry.getKey().getServerName(), entry.getValue()); - } - return data; - } - - @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(); - } -} diff --git 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 new file mode 100644 index 0000000..6a22439 --- /dev/null +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/metrics/MXBean.java @@ -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(); + +} diff --git 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 new file mode 100644 index 0000000..e72bf5b --- /dev/null +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/metrics/MXBeanImpl.java @@ -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(); + } +} diff --git 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 index c262cc3..4db73e3 100644 --- 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 @@ -17,24 +17,10 @@ */ 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 @@ -44,123 +30,31 @@ import org.apache.hadoop.metrics.util.MetricsRegistry; * 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 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); + private MasterMetricsSource mms; 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"); - } - - public void shutdown() { - if (masterStatistics != null) - masterStatistics.shutdown(); + mms = CompatibilitySingletonFactory.getInstance(MasterMetricsSource.class); } /** - * 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); + } /** @@ -168,7 +62,7 @@ public class MasterMetrics implements Updater { * @param ritCount */ public void updateRITCount(int ritCount) { - this.ritCount.set(ritCount); + mms.setRIT(ritCount); } /** @@ -177,13 +71,13 @@ public class MasterMetrics implements Updater { * @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); } } diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterStatistics.java hbase-server/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterStatistics.java deleted file mode 100644 index ced1d7e..0000000 --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/metrics/MasterStatistics.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * 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 javax.management.ObjectName; - -import org.apache.hadoop.classification.InterfaceAudience; -import org.apache.hadoop.hbase.metrics.MetricsMBeanBase; -import org.apache.hadoop.metrics.util.MBeanUtil; -import org.apache.hadoop.metrics.util.MetricsRegistry; - -/** - * Exports the {@link MasterMetrics} statistics as an MBean - * for JMX. - */ -@InterfaceAudience.Private -public class MasterStatistics extends MetricsMBeanBase { - private final ObjectName mbeanName; - - public MasterStatistics(MetricsRegistry registry) { - super(registry, "MasterStatistics"); - mbeanName = MBeanUtil.registerMBean("Master", "MasterStatistics", this); - } - - public void shutdown() { - if (mbeanName != null) - MBeanUtil.unregisterMBean(mbeanName); - } -} diff --git 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 index 7bab049..1b57aee 100644 --- 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 @@ -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 @@ public class ReplicationSinkMetrics { private ReplicationMetricsSource rms; public ReplicationSinkMetrics() { - rms = ReplicationMetricsSourceFactory.getInstance(); + rms = CompatibilitySingletonFactory.getInstance(ReplicationMetricsSource.class); } /** diff --git 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 index 35e3f55..fe24d39 100644 --- 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 @@ -21,6 +21,7 @@ package org.apache.hadoop.hbase.replication.regionserver.metrics; 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 @@ public class ReplicationSourceMetrics { logEditsFilteredKey = "source." + id + ".logEditsFiltered"; shippedBatchesKey = "source." + this.id + ".shippedBatches"; shippedOpsKey = "source." + this.id + ".shippedOps"; - rms = ReplicationMetricsSourceFactory.getInstance(); + rms = CompatibilitySingletonFactory.getInstance(ReplicationMetricsSource.class); } /** diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMXBean.java hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMXBean.java index cdcd4fd..939a841 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMXBean.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMXBean.java @@ -25,6 +25,7 @@ import junit.framework.Assert; 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 @@ public class TestMXBean { 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 @@ public class TestMXBean { 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); }