HBASE-6412 Move external servers to metrics2 (thrift,thrift2,rest)

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1387323 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael Stack 2012-09-18 19:10:03 +00:00
parent 1de90b853b
commit 2627730b7d
59 changed files with 1765 additions and 423 deletions

View File

@ -382,9 +382,9 @@ checkJavadocWarnings () {
echo "======================================================================"
echo ""
echo ""
echo "$MVN clean compile javadoc:javadoc -DskipTests -D${PROJECT_NAME}PatchProcess > $PATCH_DIR/patchJavadocWarnings.txt 2>&1"
echo "$MVN clean package javadoc:javadoc -DskipTests -D${PROJECT_NAME}PatchProcess > $PATCH_DIR/patchJavadocWarnings.txt 2>&1"
export MAVEN_OPTS="${MAVEN_OPTS}"
$MVN clean compile javadoc:javadoc -DskipTests -D${PROJECT_NAME}PatchProcess > $PATCH_DIR/patchJavadocWarnings.txt 2>&1
$MVN clean package javadoc:javadoc -DskipTests -D${PROJECT_NAME}PatchProcess > $PATCH_DIR/patchJavadocWarnings.txt 2>&1
javadocWarnings=`$GREP '\[WARNING\]' $PATCH_DIR/patchJavadocWarnings.txt | $AWK '/Javadoc Warnings/,EOF' | $GREP warning | $AWK 'BEGIN {total = 0} {total += 1} END {print total}'`
echo ""
echo ""
@ -415,9 +415,9 @@ checkJavacWarnings () {
echo "======================================================================"
echo ""
echo ""
echo "$MVN clean compile -DskipTests -D${PROJECT_NAME}PatchProcess > $PATCH_DIR/patchJavacWarnings.txt 2>&1"
echo "$MVN clean package -DskipTests -D${PROJECT_NAME}PatchProcess > $PATCH_DIR/patchJavacWarnings.txt 2>&1"
export MAVEN_OPTS="${MAVEN_OPTS}"
$MVN clean compile -DskipTests -D${PROJECT_NAME}PatchProcess > $PATCH_DIR/patchJavacWarnings.txt 2>&1
$MVN clean package -DskipTests -D${PROJECT_NAME}PatchProcess > $PATCH_DIR/patchJavacWarnings.txt 2>&1
if [[ $? != 0 ]] ; then
JIRA_COMMENT="$JIRA_COMMENT
@ -501,9 +501,9 @@ checkStyle () {
echo "THIS IS NOT IMPLEMENTED YET"
echo ""
echo ""
echo "$MVN compile checkstyle:checkstyle -D${PROJECT_NAME}PatchProcess"
echo "$MVN package checkstyle:checkstyle -D${PROJECT_NAME}PatchProcess -DskipTests"
export MAVEN_OPTS="${MAVEN_OPTS}"
$MVN compile checkstyle:checkstyle -D${PROJECT_NAME}PatchProcess
$MVN package checkstyle:checkstyle -D${PROJECT_NAME}PatchProcess -DskipTests
JIRA_COMMENT_FOOTER="Checkstyle results: $BUILD_URL/artifact/trunk/build/test/checkstyle-errors.html
$JIRA_COMMENT_FOOTER"
@ -534,9 +534,9 @@ checkFindbugsWarnings () {
echo "======================================================================"
echo ""
echo ""
echo "$MVN clean compile findbugs:findbugs -D${PROJECT_NAME}PatchProcess"
echo "$MVN clean package findbugs:findbugs -D${PROJECT_NAME}PatchProcess"
export MAVEN_OPTS="${MAVEN_OPTS}"
$MVN clean compile findbugs:findbugs -D${PROJECT_NAME}PatchProcess < /dev/null
$MVN clean package findbugs:findbugs -D${PROJECT_NAME}PatchProcess -DskipTests < /dev/null
if [ $? != 0 ] ; then
JIRA_COMMENT="$JIRA_COMMENT

View File

@ -0,0 +1,70 @@
/**
* 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.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.Iterator;
import java.util.ServiceLoader;
/**
* Class that will create many instances of classes provided by the hbase-hadoop{1|2}-compat jars.
*/
public class CompatibilityFactory {
private static final Log LOG = LogFactory.getLog(CompatibilitySingletonFactory.class);
public static final String EXCEPTION_START = "Could not create ";
public static final String EXCEPTION_END = " Is the hadoop compatibility jar on the classpath?";
public static synchronized <T> T getInstance(Class<T> klass) {
T instance = null;
try {
ServiceLoader<T> loader = ServiceLoader.load(klass);
Iterator<T> it = loader.iterator();
instance = it.next();
if (it.hasNext()) {
StringBuilder msg = new StringBuilder();
msg.append("ServiceLoader provided more than one implementation for class: ")
.append(klass)
.append(", using implementation: ").append(instance.getClass())
.append(", other implementations: {");
while (it.hasNext()) {
msg.append(it.next()).append(" ");
}
msg.append("}");
LOG.warn(msg);
}
} 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));
}
return instance;
}
protected static String createExceptionString(Class klass) {
return EXCEPTION_START + klass.toString() + EXCEPTION_END;
}
}

View File

@ -20,7 +20,6 @@ package org.apache.hadoop.hbase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.master.metrics.MasterMetricsSource;
import java.util.HashMap;
import java.util.Iterator;
@ -28,12 +27,11 @@ import java.util.Map;
import java.util.ServiceLoader;
/**
* Factory for classes supplied by hadoop compatibility modules.
* Factory for classes supplied by hadoop compatibility modules. Only one of each class will be
* created.
*/
public class CompatibilitySingletonFactory {
public class CompatibilitySingletonFactory extends CompatibilityFactory {
private static final Log LOG = LogFactory.getLog(CompatibilitySingletonFactory.class);
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<Class, Object> instances = new HashMap<Class, Object>();
@ -75,9 +73,4 @@ public class CompatibilitySingletonFactory {
}
return instance;
}
private static String createExceptionString(Class klass) {
return EXCEPTION_START + klass.toString() + EXCEPTION_END;
}
}

View File

@ -23,6 +23,11 @@ package org.apache.hadoop.hbase.metrics;
*/
public interface BaseMetricsSource {
/**
* Clear out the metrics and re-prepare the source.
*/
public void init();
/**
* Set a gauge to a specific value.
*

View File

@ -0,0 +1,91 @@
/**
* 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.rest.metrics;
import org.apache.hadoop.hbase.metrics.BaseMetricsSource;
/**
* Interface of the Metrics Source that will export data to Hadoop's Metrics2 system.
*/
public interface RESTMetricsSource extends BaseMetricsSource {
public static String METRICS_NAME = "Rest";
public static String CONTEXT = "rest";
public static String JMX_CONTEXT = "Rest";
public static String METRICS_DESCRIPTION = "Metrics about the HBase REST server";
static String REQUEST_KEY = "requests";
static String SUCCESSFUL_GET_KEY = "successfulGet";
static String SUCCESSFUL_PUT_KEY = "successfulPut";
static String SUCCESSFUL_DELETE_KEY = "successfulDelete";
static String FAILED_GET_KEY = "failedGet";
static String FAILED_PUT_KEY = "failedPut";
static String FAILED_DELETE_KEY = "failedDelete";
/**
* Increment the number of requests
* @param inc Ammount to increment by
*/
void incrementRequests(int inc);
/**
* Increment the number of successful Get requests.
* @param inc Number of successful get requests.
*/
void incrementSucessfulGetRequests(int inc);
/**
* Increment the number of successful Put requests.
* @param inc Number of successful put requests.
*/
void incrementSucessfulPutRequests(int inc);
/**
* Increment the number of successful Delete requests.
* @param inc
*/
void incrementSucessfulDeleteRequests(int inc);
/**
* Increment the number of failed Put Requests.
* @param inc Number of failed Put requests.
*/
void incrementFailedPutRequests(int inc);
/**
* Increment the number of failed Get requests.
* @param inc The number of failed Get Requests.
*/
void incrementFailedGetRequests(int inc);
/**
* Increment the number of failed Delete requests.
* @param inc The number of failed delete requests.
*/
void incrementFailedDeleteRequests(int inc);
}

View File

@ -0,0 +1,78 @@
/**
* 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.thrift.metrics;
import org.apache.hadoop.hbase.metrics.BaseMetricsSource;
/**
* Inteface of a class that will export metrics about Thrift to hadoop's metrics2.
*/
public interface ThriftServerMetricsSource extends BaseMetricsSource {
public static final String BATCH_GET_KEY = "batchGet";
public static final String BATCH_MUTATE_KEY = "batchMutate";
public static final String TIME_IN_QUEUE_KEY = "timeInQueue";
public static final String THRIFT_CALL_KEY = "thriftCall";
public static final String SLOW_THRIFT_CALL_KEY = "slowThriftCall";
public static final String CALL_QUEUE_LEN_KEY = "callQueueLen";
/**
* Add how long an operation was in the queue.
* @param time
*/
public void incTimeInQueue(long time);
/**
* Set the call queue length.
* @param len Time
*/
public void setCallQueueLen(int len);
/**
* Add how many keys were in a batch get.
* @param diff Num Keys
*/
public void incNumRowKeysInBatchGet(int diff);
/**
* Add how many keys were in a batch mutate.
* @param diff Num Keys
*/
public void incNumRowKeysInBatchMutate(int diff);
/**
* Add how long a method took
* @param name Method name
* @param time Time
*/
public void incMethodTime(String name, long time);
/**
* Add how long a call took
* @param time Time
*/
public void incCall(long time);
/**
* Increment how long a slow call took.
* @param time Time
*/
public void incSlowCall(long time);
}

View File

@ -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.thrift.metrics;
/** Factory that will be used to create metrics sources for the two diffent types of thrift servers. */
public interface ThriftServerMetricsSourceFactory {
public static final String METRICS_NAME = "Thrift";
public static final String METRICS_DESCRIPTION = "Thrift Server Metrics";
public static final String THRIFT_ONE_METRICS_CONTEXT = "thrift-one";
public static final String THRIFT_ONE_JMX_CONTEXT = "Thrift,sub=ThriftOne";
public static final String THRIFT_TWO_METRICS_CONTEXT = "thrift-two";
public static final String THRIFT_TWO_JMX_CONTEXT = "Thrift,sub=ThriftTwo";
public ThriftServerMetricsSource createThriftOneSource();
public ThriftServerMetricsSource createThriftTwoSource();
}

View File

@ -24,7 +24,7 @@ import org.junit.Test;
/**
* Test for the CompatibilitySingletonFactory and building MasterMetricsSource
*/
public class MasterMetricsSourceFactoryTest {
public class TestMasterMetricsSourceFactory {
@Test(expected=RuntimeException.class)
public void testGetInstanceNoHadoopCompat() throws Exception {

View File

@ -24,7 +24,7 @@ import org.junit.Test;
/**
* Test for the CompatibilitySingletonFactory and building ReplicationMetricsSource
*/
public class ReplicationMetricsSourceFactoryTest {
public class TestReplicationMetricsSourceFactory {
@Test(expected=RuntimeException.class)
public void testGetInstanceNoHadoopCompat() throws Exception {

View File

@ -0,0 +1,36 @@
/**
* 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.rest.metrics;
import org.apache.hadoop.hbase.CompatibilitySingletonFactory;
import org.junit.Test;
/**
* Test of Rest Metrics Source interface.
*/
public class TestRESTMetricsSource {
@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(RESTMetricsSource.class);
}
}

View File

@ -0,0 +1,48 @@
/**
* 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.test;
import org.apache.hadoop.hbase.metrics.BaseMetricsSource;
/**
*
*/
public interface MetricsAssertHelper {
public void assertTag(String name, String expected, BaseMetricsSource source);
public void assertGauge(String name, long expected, BaseMetricsSource source);
public void assertGaugeGt(String name, long expected, BaseMetricsSource source);
public void assertGaugeLt(String name, long expected, BaseMetricsSource source);
public void assertGauge(String name, double expected, BaseMetricsSource source);
public void assertGaugeGt(String name, double expected, BaseMetricsSource source);
public void assertGaugeLt(String name, double expected, BaseMetricsSource source);
public void assertCounter(String name, long expected, BaseMetricsSource source);
public void assertCounterGt(String name, long expected, BaseMetricsSource source);
public void assertCounterLt(String name, long expected, BaseMetricsSource source);
}

View File

@ -0,0 +1,36 @@
/**
* 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.thrift.metrics;
import org.apache.hadoop.hbase.CompatibilitySingletonFactory;
import org.junit.Test;
/**
* Test for the interface of ThriftServerMetricsSourceFactory
*/
public class TestThriftServerMetricsSourceFactory {
@Test(expected=RuntimeException.class)
public void testGetInstanceNoHadoopCompat() throws RuntimeException {
//This should throw an exception because there is no compat lib on the class path.
CompatibilitySingletonFactory.getInstance(ThriftServerMetricsSourceFactory.class);
}
}

View File

@ -61,6 +61,7 @@ limitations under the License.
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-hadoop-compat</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>

View File

@ -22,9 +22,16 @@ package org.apache.hadoop.hbase.master.metrics;
* Factory to create MasterMetricsSource when given a MasterMetricsWrapper
*/
public class MasterMetricsSourceFactoryImpl implements MasterMetricsSourceFactory {
private static enum FactoryStorage {
INSTANCE;
MasterMetricsSource source;
}
@Override
public MasterMetricsSource create(MasterMetricsWrapper beanWrapper) {
return new MasterMetricsSourceImpl(beanWrapper);
public synchronized MasterMetricsSource create(MasterMetricsWrapper beanWrapper) {
if (FactoryStorage.INSTANCE.source == null ) {
FactoryStorage.INSTANCE.source = new MasterMetricsSourceImpl(beanWrapper);
}
return FactoryStorage.INSTANCE.source;
}
}

View File

@ -26,18 +26,16 @@ import org.apache.hadoop.metrics2.MetricsRecordBuilder;
import org.apache.hadoop.metrics2.lib.MetricMutableCounterLong;
import org.apache.hadoop.metrics2.lib.MetricMutableGaugeLong;
/**
* Hadoop1 implementation of MasterMetricsSource.
*/
/** Hadoop1 implementation of MasterMetricsSource. */
public class MasterMetricsSourceImpl
extends BaseMetricsSourceImpl implements MasterMetricsSource {
extends BaseMetricsSourceImpl implements MasterMetricsSource {
private static final Log LOG = LogFactory.getLog(MasterMetricsSourceImpl.class.getName());
final MetricMutableCounterLong clusterRequestsCounter;
final MetricMutableGaugeLong ritGauge;
final MetricMutableGaugeLong ritCountOverThresholdGauge;
final MetricMutableGaugeLong ritOldestAgeGauge;
MetricMutableCounterLong clusterRequestsCounter;
MetricMutableGaugeLong ritGauge;
MetricMutableGaugeLong ritCountOverThresholdGauge;
MetricMutableGaugeLong ritOldestAgeGauge;
private final MasterMetricsWrapper masterWrapper;
@ -51,12 +49,16 @@ public class MasterMetricsSourceImpl
String metricsJmxContext,
MasterMetricsWrapper masterWrapper) {
super(metricsName, metricsDescription, metricsContext, metricsJmxContext);
this.masterWrapper = masterWrapper;
clusterRequestsCounter = metricsRegistry.newCounter("cluster_requests", "", 0l);
ritGauge = metricsRegistry.newGauge("ritCount", "", 0l);
ritCountOverThresholdGauge = metricsRegistry.newGauge("ritCountOverThreshold","", 0l);
ritOldestAgeGauge = metricsRegistry.newGauge("ritOldestAge", "", 0l);
}
@Override
public void init() {
this.metricsRegistry.clearMetrics();
clusterRequestsCounter = getMetricsRegistry().getLongCounter("cluster_requests", 0);
ritGauge = getMetricsRegistry().getLongGauge("ritCount", 0);
ritCountOverThresholdGauge = getMetricsRegistry().getLongGauge("ritCountOverThreshold", 0);
ritOldestAgeGauge = getMetricsRegistry().getLongGauge("ritOldestAge", 0);
}
public void incRequests(final int inc) {
@ -110,4 +112,5 @@ public class MasterMetricsSourceImpl
metricsRegistry.snapshot(metricsRecordBuilder, true);
}
}

View File

@ -75,6 +75,11 @@ public class BaseMetricsSourceImpl implements BaseMetricsSource, MetricsSource {
//Register this instance.
DefaultMetricsSystem.INSTANCE.registerSource(metricsJmxContext, metricsDescription, this);
init();
}
public void init() {
this.metricsRegistry.clearMetrics();
}
@ -151,4 +156,12 @@ public class BaseMetricsSourceImpl implements BaseMetricsSource, MetricsSource {
public void getMetrics(MetricsBuilder metricsBuilder, boolean all) {
metricsRegistry.snapshot(metricsBuilder.addRecord(metricsRegistry.name()), all);
}
/**
* Used to get at the DynamicMetricsRegistry.
* @return
*/
protected DynamicMetricsRegistry getMetricsRegistry() {
return metricsRegistry;
}
}

View File

@ -0,0 +1,97 @@
/**
* 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.rest.metrics;
import org.apache.hadoop.hbase.metrics.BaseMetricsSourceImpl;
import org.apache.hadoop.metrics2.lib.MetricMutableCounterLong;
/**
* Hadoop One implementation of a metrics2 source that will export metrics from the Rest server to
* the hadoop metrics2 subsystem.
*/
public class RESTMetricsSourceImpl extends BaseMetricsSourceImpl implements RESTMetricsSource {
private MetricMutableCounterLong request;
private MetricMutableCounterLong sucGet;
private MetricMutableCounterLong sucPut;
private MetricMutableCounterLong sucDel;
private MetricMutableCounterLong fGet;
private MetricMutableCounterLong fPut;
private MetricMutableCounterLong fDel;
public RESTMetricsSourceImpl() {
this(METRICS_NAME, METRICS_DESCRIPTION, CONTEXT, JMX_CONTEXT);
}
public RESTMetricsSourceImpl(String metricsName,
String metricsDescription,
String metricsContext,
String metricsJmxContext) {
super(metricsName, metricsDescription, metricsContext, metricsJmxContext);
}
@Override
public void init() {
super.init();
request = getMetricsRegistry().getLongCounter(REQUEST_KEY, 0l);
sucGet = getMetricsRegistry().getLongCounter(SUCCESSFUL_GET_KEY, 0l);
sucPut = getMetricsRegistry().getLongCounter(SUCCESSFUL_PUT_KEY, 0l);
sucDel = getMetricsRegistry().getLongCounter(SUCCESSFUL_DELETE_KEY, 0l);
fGet = getMetricsRegistry().getLongCounter(FAILED_GET_KEY, 0l);
fPut = getMetricsRegistry().getLongCounter(FAILED_PUT_KEY, 0l);
fDel = getMetricsRegistry().getLongCounter(FAILED_DELETE_KEY, 0l);
}
@Override
public void incrementRequests(int inc) {
request.incr(inc);
}
@Override
public void incrementSucessfulGetRequests(int inc) {
sucGet.incr(inc);
}
@Override
public void incrementSucessfulPutRequests(int inc) {
sucPut.incr(inc);
}
@Override
public void incrementSucessfulDeleteRequests(int inc) {
sucDel.incr(inc);
}
@Override
public void incrementFailedGetRequests(int inc) {
fGet.incr(inc);
}
@Override
public void incrementFailedPutRequests(int inc) {
fPut.incr(inc);
}
@Override
public void incrementFailedDeleteRequests(int inc) {
fDel.incr(inc);
}
}

View File

@ -0,0 +1,52 @@
/**
* 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.thrift.metrics;
/**
* Class used to create metrics sources for Thrift and Thrift2 servers in hadoop 1's compat
* library.
*/
public class ThriftServerMetricsSourceFactoryImpl implements ThriftServerMetricsSourceFactory {
/**
* A singleton used to make sure that only one thrift metrics source per server type is ever
* created.
*/
private static enum FactoryStorage {
INSTANCE;
ThriftServerMetricsSourceImpl thriftOne = new ThriftServerMetricsSourceImpl(METRICS_NAME,
METRICS_DESCRIPTION,
THRIFT_ONE_METRICS_CONTEXT,
THRIFT_ONE_JMX_CONTEXT);
ThriftServerMetricsSourceImpl thriftTwo = new ThriftServerMetricsSourceImpl(METRICS_NAME,
METRICS_DESCRIPTION,
THRIFT_TWO_METRICS_CONTEXT,
THRIFT_TWO_JMX_CONTEXT);
}
@Override
public ThriftServerMetricsSource createThriftOneSource() {
return FactoryStorage.INSTANCE.thriftOne;
}
@Override
public ThriftServerMetricsSource createThriftTwoSource() {
return FactoryStorage.INSTANCE.thriftTwo;
}
}

View File

@ -0,0 +1,97 @@
/**
* 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.thrift.metrics;
import org.apache.hadoop.hbase.metrics.BaseMetricsSourceImpl;
import org.apache.hadoop.hbase.thrift.metrics.ThriftServerMetricsSource;
import org.apache.hadoop.metrics2.lib.MetricMutableGaugeLong;
import org.apache.hadoop.metrics2.lib.MetricMutableStat;
/**
* Hadoop 1 version of ThriftServerMetricsSource{@link ThriftServerMetricsSource}
*/
public class ThriftServerMetricsSourceImpl extends BaseMetricsSourceImpl implements
ThriftServerMetricsSource {
private MetricMutableStat batchGetStat;
private MetricMutableStat batchMutateStat;
private MetricMutableStat queueTimeStat;
private MetricMutableStat thriftCallStat;
private MetricMutableStat thriftSlowCallStat;
private MetricMutableGaugeLong callQueueLenGauge;
public ThriftServerMetricsSourceImpl(String metricsName,
String metricsDescription,
String metricsContext,
String metricsJmxContext) {
super(metricsName, metricsDescription, metricsContext, metricsJmxContext);
}
@Override
public void init() {
super.init();
batchGetStat = getMetricsRegistry().newStat(BATCH_GET_KEY, "", "Keys", "Ops");
batchMutateStat = getMetricsRegistry().newStat(BATCH_MUTATE_KEY, "", "Keys", "Ops");
queueTimeStat = getMetricsRegistry().newStat(TIME_IN_QUEUE_KEY);
thriftCallStat = getMetricsRegistry().newStat(THRIFT_CALL_KEY);
thriftSlowCallStat = getMetricsRegistry().newStat(SLOW_THRIFT_CALL_KEY);
callQueueLenGauge = getMetricsRegistry().getLongGauge(CALL_QUEUE_LEN_KEY, 0);
}
@Override
public void incTimeInQueue(long time) {
queueTimeStat.add(time);
}
@Override
public void setCallQueueLen(int len) {
callQueueLenGauge.set(len);
}
@Override
public void incNumRowKeysInBatchGet(int diff) {
batchGetStat.add(diff);
}
@Override
public void incNumRowKeysInBatchMutate(int diff) {
batchMutateStat.add(diff);
}
@Override
public void incMethodTime(String name, long time) {
MetricMutableStat s = getMetricsRegistry().newStat(name);
s.add(time);
}
@Override
public void incCall(long time) {
thriftCallStat.add(time);
}
@Override
public void incSlowCall(long time) {
thriftSlowCallStat.add(time);
}
}

View File

@ -352,4 +352,8 @@ public class DynamicMetricsRegistry {
return (T) metric;
}
public void clearMetrics() {
metricsMap.clear();
}
}

View File

@ -0,0 +1 @@
org.apache.hadoop.hbase.rest.metrics.RESTMetricsSourceImpl

View File

@ -0,0 +1 @@
org.apache.hadoop.hbase.thrift.metrics.ThriftServerMetricsSourceFactoryImpl

View File

@ -27,7 +27,7 @@ import static org.junit.Assert.assertTrue;
/**
* Test for MasterMetricsSourceImpl
*/
public class MasterMetricsSourceImplTest {
public class TestMasterMetricsSourceImpl {
@Test
public void testGetInstance() throws Exception {

View File

@ -30,7 +30,7 @@ import static org.junit.Assert.assertSame;
/**
* Test of the default BaseMetricsSource implementation for hadoop 1
*/
public class BaseMetricsSourceImplTest {
public class TestBaseMetricsSourceImplTest {
private static BaseMetricsSourceImpl bmsi;

View File

@ -26,7 +26,7 @@ import static org.junit.Assert.assertTrue;
/**
* Test to make sure that ReplicationMetricsSourceImpl is hooked up to ServiceLoader
*/
public class ReplicationMetricsSourceImplTest {
public class TestReplicationMetricsSourceImpl {
@Test
public void testGetInstance() throws Exception {

View File

@ -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.rest.metrics;
import org.apache.hadoop.hbase.CompatibilitySingletonFactory;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
* Test for hadoop1's version of RESTMetricsSource
*/
public class TestRESTMetricsSourceImpl {
@Test
public void ensureCompatRegistered() throws Exception {
assertNotNull(CompatibilitySingletonFactory.getInstance(RESTMetricsSource.class));
assertTrue(CompatibilitySingletonFactory.getInstance(RESTMetricsSource.class) instanceof RESTMetricsSourceImpl);
}
}

View File

@ -0,0 +1,214 @@
/**
* 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.test;
import org.apache.hadoop.hbase.metrics.BaseMetricsSource;
import org.apache.hadoop.hbase.metrics.BaseMetricsSourceImpl;
import org.apache.hadoop.metrics2.Metric;
import org.apache.hadoop.metrics2.MetricsBuilder;
import org.apache.hadoop.metrics2.MetricsRecordBuilder;
import org.apache.hadoop.metrics2.MetricsTag;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.*;
/**
* A helper class that will allow tests to get into hadoop1's metrics2 values.
*/
public class MetricsAssertHelperImpl implements MetricsAssertHelper {
private Map<String, String> tags = new HashMap<String, String>();
private Map<String, Number> gauges = new HashMap<String, Number>();
private Map<String, Long> counters = new HashMap<String, Long>();
public class MockMetricsBuilder implements MetricsBuilder {
@Override
public MetricsRecordBuilder addRecord(String s) {
return new MockRecordBuilder();
}
}
public class MockRecordBuilder extends MetricsRecordBuilder {
@Override
public MetricsRecordBuilder tag(String s, String s1, String s2) {
tags.put(canonicalizeMetricName(s), s2);
return this;
}
@Override
public MetricsRecordBuilder add(MetricsTag metricsTag) {
tags.put(canonicalizeMetricName(metricsTag.name()), metricsTag.value());
return this;
}
@Override
public MetricsRecordBuilder setContext(String s) {
return this;
}
@Override
public MetricsRecordBuilder addCounter(String s, String s1, int i) {
counters.put(canonicalizeMetricName(s), Long.valueOf(i));
return this;
}
@Override
public MetricsRecordBuilder addCounter(String s, String s1, long l) {
counters.put(canonicalizeMetricName(s), Long.valueOf(l));
return this;
}
@Override
public MetricsRecordBuilder addGauge(String s, String s1, int i) {
gauges.put(canonicalizeMetricName(s), Long.valueOf(i));
return this;
}
@Override
public MetricsRecordBuilder addGauge(String s, String s1, long l) {
gauges.put(canonicalizeMetricName(s), Long.valueOf(l));
return this;
}
@Override
public MetricsRecordBuilder addGauge(String s, String s1, float v) {
gauges.put(canonicalizeMetricName(s), Double.valueOf(v));
return this;
}
@Override
public MetricsRecordBuilder addGauge(String s, String s1, double v) {
gauges.put(canonicalizeMetricName(s), Double.valueOf(v));
return this;
}
@Override
public MetricsRecordBuilder add(Metric metric) {
gauges.put(canonicalizeMetricName(metric.name()), metric.value());
return this;
}
}
@Override
public void assertTag(String name, String expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertEquals("Tags should be equal", expected, tags.get(cName));
}
@Override
public void assertGauge(String name, long expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertEquals("Metrics Should be equal", Long.valueOf(expected), gauges.get(cName));
}
@Override
public void assertGaugeGt(String name, long expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertNotNull(gauges.get(cName));
long found = gauges.get(cName).longValue();
assertTrue(name + " (" + found + ") should be greater than " + expected, found > expected);
}
@Override
public void assertGaugeLt(String name, long expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertNotNull(gauges.get(cName));
long found = gauges.get(cName).longValue();
assertTrue(name + "(" + found + ") should be less than " + expected, found < expected);
}
@Override
public void assertGauge(String name, double expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertEquals("Metrics Should be equal", Double.valueOf(expected), gauges.get(cName));
}
@Override
public void assertGaugeGt(String name, double expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertNotNull(gauges.get(cName));
double found = gauges.get(cName).doubleValue();
assertTrue(name + "(" + found + ") should be greater than " + expected, found > expected);
}
@Override
public void assertGaugeLt(String name, double expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertNotNull(gauges.get(cName));
double found = gauges.get(cName).doubleValue();
assertTrue(name + "(" + found + ") should be less than " + expected, found < expected);
}
@Override
public void assertCounter(String name, long expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertEquals("Metrics Counters should be equal", Long.valueOf(expected), counters.get(cName));
}
@Override
public void assertCounterGt(String name, long expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertNotNull(counters.get(cName));
long found = counters.get(cName).longValue();
assertTrue(name + " (" + found + ") should be greater than " + expected, found > expected);
}
@Override
public void assertCounterLt(String name, long expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertNotNull(counters.get(cName));
long found = counters.get(cName).longValue();
assertTrue(name + "(" + found + ") should be less than " + expected, found < expected);
}
private void reset() {
tags.clear();
gauges.clear();
counters.clear();
}
private void getMetrics(BaseMetricsSource source) {
reset();
if (!(source instanceof BaseMetricsSourceImpl)) {
assertTrue(false);
}
BaseMetricsSourceImpl impl = (BaseMetricsSourceImpl) source;
impl.getMetrics(new MockMetricsBuilder(), true);
}
private String canonicalizeMetricName(String in) {
return in.toLowerCase().replaceAll("[^A-Za-z0-9 ]", "");
}
}

View File

@ -0,0 +1,53 @@
/**
* 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.thrift.metrics;
import org.apache.hadoop.hbase.CompatibilitySingletonFactory;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
/**
* Test the hadoop 1 version of ThriftServerMetricsSourceFactory
*/
public class TestThriftServerMetricsSourceFactoryImpl {
@Test
public void testCompatabilityRegistered() throws Exception {
assertNotNull(CompatibilitySingletonFactory.getInstance(ThriftServerMetricsSourceFactory.class));
assertTrue(CompatibilitySingletonFactory.getInstance(ThriftServerMetricsSourceFactory.class) instanceof ThriftServerMetricsSourceFactoryImpl);
}
@Test
public void testCreateThriftOneSource() throws Exception {
//Make sure that the factory gives back a singleton.
assertSame(new ThriftServerMetricsSourceFactoryImpl().createThriftOneSource(),
new ThriftServerMetricsSourceFactoryImpl().createThriftOneSource());
}
@Test
public void testCreateThriftTwoSource() throws Exception {
//Make sure that the factory gives back a singleton.
assertSame(new ThriftServerMetricsSourceFactoryImpl().createThriftTwoSource(),
new ThriftServerMetricsSourceFactoryImpl().createThriftTwoSource());
}
}

View File

@ -0,0 +1 @@
org.apache.hadoop.hbase.test.MetricsAssertHelperImpl

View File

@ -115,6 +115,7 @@ limitations under the License.
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-hadoop-compat</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
@ -128,6 +129,11 @@ limitations under the License.
<artifactId>hadoop-annotations</artifactId>
<version>${hadoop-two.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>${hadoop-two.version}</version>
</dependency>
<!-- This was marked as test dep in earlier pom, but was scoped compile. Where
do we actually need it? -->
<dependency>

View File

@ -22,9 +22,16 @@ package org.apache.hadoop.hbase.master.metrics;
* Factory to create MasterMetricsSource when given a MasterMetricsWrapper
*/
public class MasterMetricsSourceFactoryImpl implements MasterMetricsSourceFactory {
private static enum FactoryStorage {
INSTANCE;
MasterMetricsSource source;
}
@Override
public MasterMetricsSource create(MasterMetricsWrapper beanWrapper) {
return new MasterMetricsSourceImpl(beanWrapper);
public synchronized MasterMetricsSource create(MasterMetricsWrapper beanWrapper) {
if (FactoryStorage.INSTANCE.source == null ) {
FactoryStorage.INSTANCE.source = new MasterMetricsSourceImpl(beanWrapper);
}
return FactoryStorage.INSTANCE.source;
}
}

View File

@ -50,11 +50,15 @@ public class MasterMetricsSourceImpl
MasterMetricsWrapper masterWrapper) {
super(metricsName, metricsDescription, metricsContext, metricsJmxContext);
this.masterWrapper = masterWrapper;
}
clusterRequestsCounter = metricsRegistry.newCounter("cluster_requests", "", 0l);
ritGauge = metricsRegistry.newGauge("ritCount", "", 0l);
ritCountOverThresholdGauge = metricsRegistry.newGauge("ritCountOverThreshold", "" , 0l);
ritOldestAgeGauge = metricsRegistry.newGauge("ritOldestAge", "", 0l);
@Override
public void init() {
super.init();
clusterRequestsCounter = getMetricsRegistry().getLongCounter("cluster_requests", 0);
ritGauge = getMetricsRegistry().getLongGauge("ritCount", 0);
ritCountOverThresholdGauge = getMetricsRegistry().getLongGauge("ritCountOverThreshold", 0);
ritOldestAgeGauge = getMetricsRegistry().getLongGauge("ritOldestAge", 0);
}
public void incRequests(final int inc) {

View File

@ -58,14 +58,20 @@ public class BaseMetricsSourceImpl implements BaseMetricsSource, MetricsSource {
if (!defaultMetricsSystemInited) {
//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(metricsJmxContext, metricsDescription, this);
init();
}
public void init() {
this.metricsRegistry.clearMetrics();
}
/**
* Set a single gauge to a value.
*
@ -129,8 +135,14 @@ public class BaseMetricsSourceImpl implements BaseMetricsSource, MetricsSource {
metricsRegistry.removeMetric(key);
}
protected DynamicMetricsRegistry getMetricsRegistry() {
return metricsRegistry;
}
@Override
public void getMetrics(MetricsCollector metricsCollector, boolean all) {
metricsRegistry.snapshot(metricsCollector.addRecord(metricsRegistry.info()), all);
}
}

View File

@ -19,7 +19,6 @@
package org.apache.hadoop.hbase.replication.regionserver.metrics;
import org.apache.hadoop.hbase.metrics.BaseMetricsSourceImpl;
import org.apache.hadoop.metrics2.MetricsSource;
/**
* Hadoop2 implementation of ReplicationMetricsSource. This provides access to metrics gauges and

View File

@ -0,0 +1,97 @@
/**
* 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.rest.metrics;
import org.apache.hadoop.hbase.metrics.BaseMetricsSourceImpl;
import org.apache.hadoop.metrics2.lib.MutableCounterLong;
/**
* Hadoop Two implementation of a metrics2 source that will export metrics from the Rest server to
* the hadoop metrics2 subsystem.
*/
public class RESTMetricsSourceImpl extends BaseMetricsSourceImpl implements RESTMetricsSource {
private MutableCounterLong request;
private MutableCounterLong sucGet;
private MutableCounterLong sucPut;
private MutableCounterLong sucDel;
private MutableCounterLong fGet;
private MutableCounterLong fPut;
private MutableCounterLong fDel;
public RESTMetricsSourceImpl() {
this(METRICS_NAME, METRICS_DESCRIPTION, CONTEXT, JMX_CONTEXT);
}
public RESTMetricsSourceImpl(String metricsName,
String metricsDescription,
String metricsContext,
String metricsJmxContext) {
super(metricsName, metricsDescription, metricsContext, metricsJmxContext);
}
@Override
public void init() {
super.init();
request = getMetricsRegistry().getLongCounter(REQUEST_KEY, 0l);
sucGet = getMetricsRegistry().getLongCounter(SUCCESSFUL_GET_KEY, 0l);
sucPut = getMetricsRegistry().getLongCounter(SUCCESSFUL_PUT_KEY, 0l);
sucDel = getMetricsRegistry().getLongCounter(SUCCESSFUL_DELETE_KEY, 0l);
fGet = getMetricsRegistry().getLongCounter(FAILED_GET_KEY, 0l);
fPut = getMetricsRegistry().getLongCounter(FAILED_PUT_KEY, 0l);
fDel = getMetricsRegistry().getLongCounter(FAILED_DELETE_KEY, 0l);
}
@Override
public void incrementRequests(int inc) {
request.incr(inc);
}
@Override
public void incrementSucessfulGetRequests(int inc) {
sucGet.incr(inc);
}
@Override
public void incrementSucessfulPutRequests(int inc) {
sucPut.incr(inc);
}
@Override
public void incrementSucessfulDeleteRequests(int inc) {
sucDel.incr(inc);
}
@Override
public void incrementFailedGetRequests(int inc) {
fGet.incr(inc);
}
@Override
public void incrementFailedPutRequests(int inc) {
fPut.incr(inc);
}
@Override
public void incrementFailedDeleteRequests(int inc) {
fDel.incr(inc);
}
}

View File

@ -0,0 +1,51 @@
/**
* 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.thrift.metrics;
/**
* Class used to create metrics sources for Thrift and Thrift2 servers.
*/
public class ThriftServerMetricsSourceFactoryImpl implements ThriftServerMetricsSourceFactory {
/**
* A singleton used to make sure that only one thrift metrics source per server type is ever
* created.
*/
private static enum FactoryStorage {
INSTANCE;
ThriftServerMetricsSourceImpl thriftOne = new ThriftServerMetricsSourceImpl(METRICS_NAME,
METRICS_DESCRIPTION,
THRIFT_ONE_METRICS_CONTEXT,
THRIFT_ONE_JMX_CONTEXT);
ThriftServerMetricsSourceImpl thriftTwo = new ThriftServerMetricsSourceImpl(METRICS_NAME,
METRICS_DESCRIPTION,
THRIFT_TWO_METRICS_CONTEXT,
THRIFT_TWO_JMX_CONTEXT);
}
@Override
public ThriftServerMetricsSource createThriftOneSource() {
return FactoryStorage.INSTANCE.thriftOne;
}
@Override
public ThriftServerMetricsSource createThriftTwoSource() {
return FactoryStorage.INSTANCE.thriftTwo;
}
}

View File

@ -0,0 +1,98 @@
/**
* 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.thrift.metrics;
import org.apache.hadoop.hbase.metrics.BaseMetricsSourceImpl;
import org.apache.hadoop.hbase.thrift.metrics.ThriftServerMetricsSource;
import org.apache.hadoop.metrics2.lib.MutableGaugeLong;
import org.apache.hadoop.metrics2.lib.MutableStat;
/**
* Hadoop 2 version of ThriftServerMetricsSource{@link ThriftServerMetricsSource}
*/
public class ThriftServerMetricsSourceImpl extends BaseMetricsSourceImpl implements
ThriftServerMetricsSource {
private MutableStat batchGetStat;
private MutableStat batchMutateStat;
private MutableStat queueTimeStat;
private MutableStat thriftCallStat;
private MutableStat thriftSlowCallStat;
private MutableGaugeLong callQueueLenGauge;
public ThriftServerMetricsSourceImpl(String metricsName,
String metricsDescription,
String metricsContext,
String metricsJmxContext) {
super(metricsName, metricsDescription, metricsContext, metricsJmxContext);
}
@Override
public void init() {
super.init();
batchGetStat = getMetricsRegistry().newStat(BATCH_GET_KEY, "", "Keys", "Ops");
batchMutateStat = getMetricsRegistry().newStat(BATCH_MUTATE_KEY, "", "Keys", "Ops");
queueTimeStat = getMetricsRegistry().newRate(TIME_IN_QUEUE_KEY) ;
thriftCallStat = getMetricsRegistry().newRate(THRIFT_CALL_KEY);
thriftSlowCallStat = getMetricsRegistry().newRate(SLOW_THRIFT_CALL_KEY);
callQueueLenGauge = getMetricsRegistry().getLongGauge(CALL_QUEUE_LEN_KEY, 0) ;
}
@Override
public void incTimeInQueue(long time) {
queueTimeStat.add(time);
}
@Override
public void setCallQueueLen(int len) {
callQueueLenGauge.set(len);
}
@Override
public void incNumRowKeysInBatchGet(int diff) {
batchGetStat.add(diff);
}
@Override
public void incNumRowKeysInBatchMutate(int diff) {
batchMutateStat.add(diff);
}
@Override
public void incMethodTime(String name, long time) {
MutableStat s = getMetricsRegistry().newRate(name);
s.add(time);
}
@Override
public void incCall(long time) {
thriftCallStat.add(time);
}
@Override
public void incSlowCall(long time) {
thriftSlowCallStat.add(time);
}
}

View File

@ -465,4 +465,8 @@ public class DynamicMetricsRegistry {
return (T) metric;
}
public void clearMetrics() {
metricsMap.clear();
}
}

View File

@ -0,0 +1 @@
org.apache.hadoop.hbase.rest.metrics.RESTMetricsSourceImpl

View File

@ -0,0 +1 @@
org.apache.hadoop.hbase.thrift.metrics.ThriftServerMetricsSourceFactoryImpl

View File

@ -27,7 +27,7 @@ import static org.junit.Assert.assertTrue;
/**
* Test for MasterMetricsSourceImpl
*/
public class MasterMetricsSourceImplTest {
public class TestMasterMetricsSourceImpl {
@Test
public void testGetInstance() throws Exception {

View File

@ -29,7 +29,7 @@ import static org.junit.Assert.assertNull;
/**
* Test of default BaseMetricsSource for hadoop 2
*/
public class BaseMetricsSourceImplTest {
public class TestBaseMetricsSourceImpl {
private static BaseMetricsSourceImpl bmsi;

View File

@ -24,7 +24,7 @@ import org.junit.Test;
import static org.junit.Assert.assertTrue;
/** Test for ReplicationMetricsSourceImpl */
public class ReplicationMetricsSourceImplTest {
public class TestReplicationMetricsSourceImpl {
@Test
public void testGetInstance() throws Exception {

View File

@ -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.rest.metrics;
import org.apache.hadoop.hbase.CompatibilitySingletonFactory;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
* Test for hadoop 2's version of RESTMetricsSource
*/
public class TestRESTMetricsSourceImpl {
@Test
public void ensureCompatRegistered() throws Exception {
assertNotNull(CompatibilitySingletonFactory.getInstance(RESTMetricsSource.class));
assertTrue(CompatibilitySingletonFactory.getInstance(RESTMetricsSource.class) instanceof RESTMetricsSourceImpl);
}
}

View File

@ -0,0 +1,233 @@
/**
* 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.test;
import org.apache.hadoop.hbase.metrics.BaseMetricsSource;
import org.apache.hadoop.hbase.metrics.BaseMetricsSourceImpl;
import org.apache.hadoop.metrics2.AbstractMetric;
import org.apache.hadoop.metrics2.MetricsCollector;
import org.apache.hadoop.metrics2.MetricsInfo;
import org.apache.hadoop.metrics2.MetricsRecordBuilder;
import org.apache.hadoop.metrics2.MetricsTag;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.*;
/**
* A helper class that will allow tests to get into hadoop2's metrics2 values.
*/
public class MetricsAssertHelperImpl implements MetricsAssertHelper {
private Map<String, String> tags = new HashMap<String, String>();
private Map<String, Number> gauges = new HashMap<String, Number>();
private Map<String, Long> counters = new HashMap<String, Long>();
public class MockMetricsBuilder implements MetricsCollector {
@Override
public MetricsRecordBuilder addRecord(String s) {
return new MockRecordBuilder(this);
}
@Override
public MetricsRecordBuilder addRecord(MetricsInfo metricsInfo) {
return new MockRecordBuilder(this);
}
}
public class MockRecordBuilder extends MetricsRecordBuilder {
private final MetricsCollector mockMetricsBuilder;
public MockRecordBuilder(MetricsCollector mockMetricsBuilder) {
this.mockMetricsBuilder = mockMetricsBuilder;
}
@Override
public MetricsRecordBuilder tag(MetricsInfo metricsInfo, String s) {
tags.put(metricsInfo.name(), s);
return this;
}
@Override
public MetricsRecordBuilder add(MetricsTag metricsTag) {
tags.put(canonicalizeMetricName(metricsTag.name()), metricsTag.value());
return this;
}
@Override
public MetricsRecordBuilder add(AbstractMetric abstractMetric) {
gauges.put(canonicalizeMetricName(abstractMetric.name()), abstractMetric.value());
return this;
}
@Override
public MetricsRecordBuilder setContext(String s) {
return this;
}
@Override
public MetricsRecordBuilder addCounter(MetricsInfo metricsInfo, int i) {
counters.put(canonicalizeMetricName(metricsInfo.name()), Long.valueOf(i));
return this;
}
@Override
public MetricsRecordBuilder addCounter(MetricsInfo metricsInfo, long l) {
counters.put(canonicalizeMetricName(metricsInfo.name()), Long.valueOf(l));
return this;
}
@Override
public MetricsRecordBuilder addGauge(MetricsInfo metricsInfo, int i) {
gauges.put(canonicalizeMetricName(metricsInfo.name()), Long.valueOf(i));
return this;
}
@Override
public MetricsRecordBuilder addGauge(MetricsInfo metricsInfo, long l) {
gauges.put(canonicalizeMetricName(metricsInfo.name()), Long.valueOf(l));
return this;
}
@Override
public MetricsRecordBuilder addGauge(MetricsInfo metricsInfo, float v) {
gauges.put(canonicalizeMetricName(metricsInfo.name()), Double.valueOf(v));
return this;
}
@Override
public MetricsRecordBuilder addGauge(MetricsInfo metricsInfo, double v) {
gauges.put(canonicalizeMetricName(metricsInfo.name()), Double.valueOf(v));
return this;
}
@Override
public MetricsCollector parent() {
return mockMetricsBuilder;
}
}
@Override
public void assertTag(String name, String expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertEquals("Tags should be equal", expected, tags.get(cName));
}
@Override
public void assertGauge(String name, long expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertEquals("Metrics Should be equal", Long.valueOf(expected), gauges.get(cName));
}
@Override
public void assertGaugeGt(String name, long expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertNotNull(gauges.get(cName));
long found = gauges.get(cName).longValue();
assertTrue(name + " (" + found + ") should be greater than " + expected, found > expected);
}
@Override
public void assertGaugeLt(String name, long expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertNotNull(gauges.get(cName));
long found = gauges.get(cName).longValue();
assertTrue(name + "(" + found + ") should be less than " + expected, found < expected);
}
@Override
public void assertGauge(String name, double expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertEquals("Metrics Should be equal", Double.valueOf(expected), gauges.get(cName));
}
@Override
public void assertGaugeGt(String name, double expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertNotNull(gauges.get(cName));
double found = gauges.get(cName).doubleValue();
assertTrue(name + "(" + found + ") should be greater than " + expected, found > expected);
}
@Override
public void assertGaugeLt(String name, double expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertNotNull(gauges.get(cName));
double found = gauges.get(cName).doubleValue();
assertTrue(name + "(" + found + ") should be less than " + expected, found < expected);
}
@Override
public void assertCounter(String name, long expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertEquals("Metrics Counters should be equal", Long.valueOf(expected), counters.get(cName));
}
@Override
public void assertCounterGt(String name, long expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertNotNull(counters.get(cName));
long found = gauges.get(cName).longValue();
assertTrue(name + " (" + found + ") should be greater than " + expected, found > expected);
}
@Override
public void assertCounterLt(String name, long expected, BaseMetricsSource source) {
getMetrics(source);
String cName = canonicalizeMetricName(name);
assertNotNull(counters.get(cName));
long found = gauges.get(cName).longValue();
assertTrue(name + "(" + found + ") should be less than " + expected, found < expected);
}
private void reset() {
tags.clear();
gauges.clear();
counters.clear();
}
private void getMetrics(BaseMetricsSource source) {
reset();
if (!(source instanceof BaseMetricsSourceImpl)) {
assertTrue(false);
}
BaseMetricsSourceImpl impl = (BaseMetricsSourceImpl) source;
impl.getMetrics(new MockMetricsBuilder(), true);
}
private String canonicalizeMetricName(String in) {
return in.toLowerCase().replaceAll("[^A-Za-z0-9 ]", "");
}
}

View File

@ -0,0 +1,53 @@
/**
* 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.thrift.metrics;
import org.apache.hadoop.hbase.CompatibilitySingletonFactory;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
/**
* Test for hadoop 2's version of ThriftServerMetricsSourceFactory
*/
public class TestThriftServerMetricsSourceFactoryImpl {
@Test
public void testCompatabilityRegistered() throws Exception {
assertNotNull(CompatibilitySingletonFactory.getInstance(ThriftServerMetricsSourceFactory.class));
assertTrue(CompatibilitySingletonFactory.getInstance(ThriftServerMetricsSourceFactory.class) instanceof ThriftServerMetricsSourceFactoryImpl);
}
@Test
public void testCreateThriftOneSource() throws Exception {
//Make sure that the factory gives back a singleton.
assertSame(new ThriftServerMetricsSourceFactoryImpl().createThriftOneSource(),
new ThriftServerMetricsSourceFactoryImpl().createThriftOneSource());
}
@Test
public void testCreateThriftTwoSource() throws Exception {
//Make sure that the factory gives back a singleton.
assertSame(new ThriftServerMetricsSourceFactoryImpl().createThriftTwoSource(),
new ThriftServerMetricsSourceFactoryImpl().createThriftTwoSource());
}
}

View File

@ -0,0 +1 @@
org.apache.hadoop.hbase.test.MetricsAssertHelperImpl

View File

@ -269,16 +269,19 @@
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-hadoop-compat</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>${compat.module}</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>${compat.module}</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>

View File

@ -20,6 +20,7 @@
package org.apache.hadoop.hbase.rest.metrics;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.hbase.CompatibilitySingletonFactory;
import org.apache.hadoop.hbase.metrics.MetricsRate;
import org.apache.hadoop.metrics.MetricsContext;
@ -30,162 +31,65 @@ import org.apache.hadoop.metrics.jvm.JvmMetrics;
import org.apache.hadoop.metrics.util.MetricsRegistry;
@InterfaceAudience.Private
public class RESTMetrics implements Updater {
private final MetricsRecord metricsRecord;
private final MetricsRegistry registry = new MetricsRegistry();
private final RESTStatistics restStatistics;
public class RESTMetrics {
private MetricsRate requests = new MetricsRate("requests", registry);
private MetricsRate sucessfulGetCount =
new MetricsRate("sucessful.get.count", registry);
private MetricsRate sucessfulPutCount =
new MetricsRate("sucessful.put.count", registry);
private MetricsRate sucessfulDeleteCount =
new MetricsRate("sucessful.delete.count", registry);
public RESTMetricsSource getSource() {
return source;
}
private MetricsRate failedGetCount =
new MetricsRate("failed.get.count", registry);
private MetricsRate failedPutCount =
new MetricsRate("failed.put.count", registry);
private MetricsRate failedDeleteCount =
new MetricsRate("failed.delete.count", registry);
private RESTMetricsSource source;
public RESTMetrics() {
MetricsContext context = MetricsUtil.getContext("rest");
metricsRecord = MetricsUtil.createRecord(context, "rest");
String name = Thread.currentThread().getName();
metricsRecord.setTag("REST", name);
context.registerUpdater(this);
JvmMetrics.init("rest", name);
// expose the MBean for metrics
restStatistics = new RESTStatistics(registry);
}
public void shutdown() {
if (restStatistics != null) {
restStatistics.shutdown();
}
}
/**
* 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) {
requests.pushMetric(metricsRecord);
sucessfulGetCount.pushMetric(metricsRecord);
sucessfulPutCount.pushMetric(metricsRecord);
sucessfulDeleteCount.pushMetric(metricsRecord);
failedGetCount.pushMetric(metricsRecord);
failedPutCount.pushMetric(metricsRecord);
failedDeleteCount.pushMetric(metricsRecord);
}
this.metricsRecord.update();
}
public void resetAllMinMax() {
// Nothing to do
}
/**
* @return Count of requests.
*/
public float getRequests() {
return requests.getPreviousIntervalValue();
source = CompatibilitySingletonFactory.getInstance(RESTMetricsSource.class);
}
/**
* @param inc How much to add to requests.
*/
public void incrementRequests(final int inc) {
requests.inc(inc);
}
/**
* @return Count of sucessfulGetCount.
*/
public float getSucessfulGetCount() {
return sucessfulGetCount.getPreviousIntervalValue();
source.incrementRequests(inc);
}
/**
* @param inc How much to add to sucessfulGetCount.
*/
public void incrementSucessfulGetRequests(final int inc) {
sucessfulGetCount.inc(inc);
}
/**
* @return Count of sucessfulGetCount.
*/
public float getSucessfulPutCount() {
return sucessfulPutCount.getPreviousIntervalValue();
source.incrementSucessfulGetRequests(inc);
}
/**
* @param inc How much to add to sucessfulPutCount.
*/
public void incrementSucessfulPutRequests(final int inc) {
sucessfulPutCount.inc(inc);
}
/**
* @return Count of failedPutCount.
*/
public float getFailedPutCount() {
return failedPutCount.getPreviousIntervalValue();
source.incrementSucessfulPutRequests(inc);
}
/**
* @param inc How much to add to failedPutCount.
*/
public void incrementFailedPutRequests(final int inc) {
failedPutCount.inc(inc);
}
/**
* @return Count of failedGetCount.
*/
public float getFailedGetCount() {
return failedGetCount.getPreviousIntervalValue();
source.incrementFailedPutRequests(inc);
}
/**
* @param inc How much to add to failedGetCount.
*/
public void incrementFailedGetRequests(final int inc) {
failedGetCount.inc(inc);
}
/**
* @return Count of sucessfulGetCount.
*/
public float getSucessfulDeleteCount() {
return sucessfulDeleteCount.getPreviousIntervalValue();
source.incrementFailedGetRequests(inc);
}
/**
* @param inc How much to add to sucessfulDeleteCount.
*/
public void incrementSucessfulDeleteRequests(final int inc) {
sucessfulDeleteCount.inc(inc);
}
/**
* @return Count of failedDeleteCount.
*/
public float getFailedDeleteCount() {
return failedDeleteCount.getPreviousIntervalValue();
source.incrementSucessfulDeleteRequests(inc);
}
/**
* @param inc How much to add to failedDeleteCount.
*/
public void incrementFailedDeleteRequests(final int inc) {
failedDeleteCount.inc(inc);
source.incrementFailedDeleteRequests(inc);
}
}

View File

@ -1,45 +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.rest.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;
@InterfaceAudience.Private
public class RESTStatistics extends MetricsMBeanBase {
private final ObjectName mbeanName;
public RESTStatistics(MetricsRegistry registry) {
super(registry, "restStatistics");
mbeanName = MBeanUtil.registerMBean("rest", "restStatistics", this);
}
public void shutdown() {
if (mbeanName != null) {
MBeanUtil.unregisterMBean(mbeanName);
}
}
}

View File

@ -19,128 +19,74 @@
package org.apache.hadoop.hbase.thrift;
import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.thrift.generated.Hbase;
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.util.MetricsBase;
import org.apache.hadoop.metrics.util.MetricsIntValue;
import org.apache.hadoop.metrics.util.MetricsRegistry;
import org.apache.hadoop.metrics.util.MetricsTimeVaryingInt;
import org.apache.hadoop.metrics.util.MetricsTimeVaryingLong;
import org.apache.hadoop.metrics.util.MetricsTimeVaryingRate;
import org.apache.hadoop.hbase.CompatibilitySingletonFactory;
import org.apache.hadoop.hbase.thrift.metrics.ThriftServerMetricsSource;
import org.apache.hadoop.hbase.thrift.metrics.ThriftServerMetricsSourceFactory;
/**
* This class is for maintaining the various statistics of thrift server
* and publishing them through the metrics interfaces.
*/
@InterfaceAudience.Private
public class ThriftMetrics implements Updater {
public final static Log LOG = LogFactory.getLog(ThriftMetrics.class);
public final static String CONTEXT_NAME = "thriftserver";
public class ThriftMetrics {
private final MetricsContext context;
private final MetricsRecord metricsRecord;
private final MetricsRegistry registry = new MetricsRegistry();
public enum ThriftServerType {
ONE,
TWO
}
public ThriftServerMetricsSource getSource() {
return source;
}
public void setSource(ThriftServerMetricsSource source) {
this.source = source;
}
private ThriftServerMetricsSource source;
private final long slowResponseTime;
public static final String SLOW_RESPONSE_NANO_SEC =
"hbase.thrift.slow.response.nano.second";
public static final long DEFAULT_SLOW_RESPONSE_NANO_SEC = 10 * 1000 * 1000;
private final MetricsIntValue callQueueLen =
new MetricsIntValue("callQueueLen", registry);
private final MetricsTimeVaryingRate numRowKeysInBatchGet =
new MetricsTimeVaryingRate("numRowKeysInBatchGet", registry);
private final MetricsTimeVaryingRate numRowKeysInBatchMutate =
new MetricsTimeVaryingRate("numRowKeysInBatchMutate", registry);
private final MetricsTimeVaryingRate timeInQueue =
new MetricsTimeVaryingRate("timeInQueue", registry);
private MetricsTimeVaryingRate thriftCall =
new MetricsTimeVaryingRate("thriftCall", registry);
private MetricsTimeVaryingRate slowThriftCall =
new MetricsTimeVaryingRate("slowThriftCall", registry);
public ThriftMetrics(int port, Configuration conf, Class<?> iface) {
slowResponseTime = conf.getLong(
SLOW_RESPONSE_NANO_SEC, DEFAULT_SLOW_RESPONSE_NANO_SEC);
context = MetricsUtil.getContext(CONTEXT_NAME);
metricsRecord = MetricsUtil.createRecord(context, CONTEXT_NAME);
public ThriftMetrics(Configuration conf, ThriftServerType t) {
slowResponseTime = conf.getLong( SLOW_RESPONSE_NANO_SEC, DEFAULT_SLOW_RESPONSE_NANO_SEC);
metricsRecord.setTag("port", port + "");
if (t == ThriftServerType.ONE) {
source = CompatibilitySingletonFactory.getInstance(ThriftServerMetricsSourceFactory.class).createThriftOneSource();
} else if (t == ThriftServerType.TWO) {
source = CompatibilitySingletonFactory.getInstance(ThriftServerMetricsSourceFactory.class).createThriftTwoSource();
}
LOG.info("Initializing RPC Metrics with port=" + port);
context.registerUpdater(this);
createMetricsForMethods(iface);
}
public void incTimeInQueue(long time) {
timeInQueue.inc(time);
source.incTimeInQueue(time);
}
public void setCallQueueLen(int len) {
callQueueLen.set(len);
source.setCallQueueLen(len);
}
public void incNumRowKeysInBatchGet(int diff) {
numRowKeysInBatchGet.inc(diff);
source.incNumRowKeysInBatchGet(diff);
}
public void incNumRowKeysInBatchMutate(int diff) {
numRowKeysInBatchMutate.inc(diff);
source.incNumRowKeysInBatchMutate(diff);
}
public void incMethodTime(String name, long time) {
MetricsTimeVaryingRate methodTimeMetric = getMethodTimeMetrics(name);
if (methodTimeMetric == null) {
LOG.warn(
"Got incMethodTime() request for method that doesnt exist: " + name);
return; // ignore methods that dont exist.
}
// inc method specific processTime
methodTimeMetric.inc(time);
source.incMethodTime(name, time);
// inc general processTime
thriftCall.inc(time);
source.incCall(time);
if (time > slowResponseTime) {
slowThriftCall.inc(time);
source.incSlowCall(time);
}
}
private void createMetricsForMethods(Class<?> iface) {
LOG.debug("Creating metrics for interface " + iface.toString());
for (Method m : iface.getDeclaredMethods()) {
if (getMethodTimeMetrics(m.getName()) == null)
LOG.debug("Creating metrics for method:" + m.getName());
createMethodTimeMetrics(m.getName());
}
}
private MetricsTimeVaryingRate getMethodTimeMetrics(String key) {
return (MetricsTimeVaryingRate) registry.get(key);
}
private MetricsTimeVaryingRate createMethodTimeMetrics(String key) {
return new MetricsTimeVaryingRate(key, this.registry);
}
/**
* Push the metrics to the monitoring subsystem on doUpdate() call.
*/
public void doUpdates(final MetricsContext context) {
// getMetricsList() and pushMetric() are thread safe methods
for (MetricsBase m : registry.getMetricsList()) {
m.pushMetric(metricsRecord);
}
metricsRecord.update();
}
}

View File

@ -235,7 +235,7 @@ public class ThriftServerRunner implements Runnable {
public ThriftServerRunner(Configuration conf, HBaseHandler handler) {
this.conf = HBaseConfiguration.create(conf);
this.listenPort = conf.getInt(PORT_CONF_KEY, DEFAULT_LISTEN_PORT);
this.metrics = new ThriftMetrics(listenPort, conf, Hbase.Iface.class);
this.metrics = new ThriftMetrics(conf, ThriftMetrics.ThriftServerType.ONE);
handler.initMetrics(metrics);
this.handler = HbaseHandlerMetricsProxy.newInstance(handler, metrics, conf);
}

View File

@ -223,8 +223,7 @@ public class ThriftServer {
boolean hsha = cmd.hasOption("hsha");
Configuration conf = HBaseConfiguration.create();
ThriftMetrics metrics = new ThriftMetrics(
listenPort, conf, THBaseService.Iface.class);
ThriftMetrics metrics = new ThriftMetrics(conf, ThriftMetrics.ThriftServerType.TWO);
// Construct correct ProtocolFactory
TProtocolFactory protocolFactory = getTProtocolFactory(cmd.hasOption("compact"));

View File

@ -30,6 +30,7 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Pattern;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@ -159,9 +160,13 @@ public class TestCheckTestClasses {
File[] files = baseDirectory.listFiles(TEST_CLASS_FILE_FILTER);
assertNotNull(files);
Pattern p = Pattern.compile("hbase-hadoop\\d?-compat");
for (File file : files) {
final String fileName = file.getName();
if (p.matcher(file.getAbsolutePath()).find()) {
continue;
}
if (file.isDirectory()) {
classes.addAll(findTestClasses(file, packageName + "." + fileName));
} else {

View File

@ -39,6 +39,7 @@ import org.apache.hadoop.hbase.rest.client.Response;
import org.apache.hadoop.hbase.rest.model.CellModel;
import org.apache.hadoop.hbase.rest.model.CellSetModel;
import org.apache.hadoop.hbase.rest.model.RowModel;
import org.apache.hadoop.hbase.test.MetricsAssertHelper;
import org.apache.hadoop.hbase.util.Bytes;
import static org.junit.Assert.*;
@ -67,6 +68,8 @@ public class TestRowResource {
private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
private static final HBaseRESTTestingUtility REST_TEST_UTIL =
new HBaseRESTTestingUtility();
private static final MetricsAssertHelper METRICS_ASSERT =
CompatibilityFactory.getInstance(MetricsAssertHelper.class);
private static Client client;
private static JAXBContext context;
private static Marshaller marshaller;
@ -525,6 +528,35 @@ public class TestRowResource {
assertEquals(response.getCode(), 200);
}
@Test
public void testMetrics() throws IOException, JAXBException {
final String path = "/" + TABLE + "/" + ROW_4 + "/" + COLUMN_1;
Response response = client.put(path, Constants.MIMETYPE_BINARY,
Bytes.toBytes(VALUE_4));
assertEquals(response.getCode(), 200);
Thread.yield();
response = client.get(path, Constants.MIMETYPE_JSON);
assertEquals(response.getCode(), 200);
response = deleteRow(TABLE, ROW_4);
assertEquals(response.getCode(), 200);
METRICS_ASSERT.assertCounterGt("requests",
2l,
RESTServlet.getInstance(conf).getMetrics().getSource());
METRICS_ASSERT.assertCounterGt("successfulGet",
0l,
RESTServlet.getInstance(conf).getMetrics().getSource());
METRICS_ASSERT.assertCounterGt("successfulPut",
0l,
RESTServlet.getInstance(conf).getMetrics().getSource());
METRICS_ASSERT.assertCounterGt("successfulDelete",
0l,
RESTServlet.getInstance(conf).getMetrics().getSource());
}
@Test
public void testURLEncodedKey() throws IOException, JAXBException {
String urlKey = "http://example.com/foo";

View File

@ -28,15 +28,11 @@ import java.util.concurrent.LinkedBlockingQueue;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.CompatibilitySingletonFactory;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.SmallTests;
import org.apache.hadoop.hbase.test.MetricsAssertHelper;
import org.apache.hadoop.hbase.thrift.CallQueue.Call;
import org.apache.hadoop.hbase.thrift.generated.Hbase;
import org.apache.hadoop.metrics.ContextFactory;
import org.apache.hadoop.metrics.MetricsContext;
import org.apache.hadoop.metrics.MetricsUtil;
import org.apache.hadoop.metrics.spi.NoEmitMetricsContext;
import org.apache.hadoop.metrics.spi.OutputRecord;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@ -54,6 +50,9 @@ public class TestCallQueue {
public static final Log LOG = LogFactory.getLog(TestCallQueue.class);
private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
private static final MetricsAssertHelper metricsHelper =
CompatibilitySingletonFactory.getInstance(MetricsAssertHelper.class);
private int elementsAdded;
private int elementsRemoved;
@ -74,6 +73,7 @@ public class TestCallQueue {
this.elementsRemoved = elementsRemoved;
LOG.debug("elementsAdded:" + elementsAdded +
" elementsRemoved:" + elementsRemoved);
}
@Test(timeout=3000)
@ -105,28 +105,16 @@ public class TestCallQueue {
}
private static ThriftMetrics createMetrics() throws Exception {
setupMetricsContext();
Configuration conf = UTIL.getConfiguration();
return new ThriftMetrics(
ThriftServerRunner.DEFAULT_LISTEN_PORT, conf, Hbase.Iface.class);
ThriftMetrics m = new ThriftMetrics(conf, ThriftMetrics.ThriftServerType.ONE);
m.getSource().init();
return m;
}
private static void setupMetricsContext() throws Exception {
ContextFactory factory = ContextFactory.getFactory();
factory.setAttribute(ThriftMetrics.CONTEXT_NAME + ".class",
NoEmitMetricsContext.class.getName());
MetricsUtil.getContext(ThriftMetrics.CONTEXT_NAME)
.createRecord(ThriftMetrics.CONTEXT_NAME).remove();
}
private static void verifyMetrics(ThriftMetrics metrics, String name, int expectValue)
throws Exception {
MetricsContext context = MetricsUtil.getContext(
ThriftMetrics.CONTEXT_NAME);
metrics.doUpdates(context);
OutputRecord record = context.getAllRecords().get(
ThriftMetrics.CONTEXT_NAME).iterator().next();
assertEquals(expectValue, record.getMetric(name).intValue());
metricsHelper.assertCounter(name, expectValue, metrics.getSource());
}
private static Runnable createDummyRunnable() {

View File

@ -31,11 +31,13 @@ import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.CompatibilityFactory;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.MediumTests;
import org.apache.hadoop.hbase.filter.ParseFilter;
import org.apache.hadoop.hbase.test.MetricsAssertHelper;
import org.apache.hadoop.hbase.thrift.ThriftServerRunner.HBaseHandler;
import org.apache.hadoop.hbase.thrift.generated.BatchMutation;
import org.apache.hadoop.hbase.thrift.generated.ColumnDescriptor;
@ -66,6 +68,8 @@ import org.junit.experimental.categories.Category;
public class TestThriftServer {
private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
private static final Log LOG = LogFactory.getLog(TestThriftServer.class);
private static final MetricsAssertHelper metricsHelper = CompatibilityFactory
.getInstance(MetricsAssertHelper.class);
protected static final int MAXVERSIONS = 3;
private static ByteBuffer asByteBuffer(String i) {
@ -164,14 +168,14 @@ public class TestThriftServer {
Hbase.Iface handler = getHandlerForMetricsTest(metrics, conf);
createTestTables(handler);
dropTestTables(handler);
verifyMetrics(metrics, "createTable_num_ops", 2);
verifyMetrics(metrics, "deleteTable_num_ops", 2);
verifyMetrics(metrics, "disableTable_num_ops", 2);
metricsHelper.assertCounter("createTable_num_ops", 2, metrics.getSource());
metricsHelper.assertCounter("deleteTable_num_ops", 2, metrics.getSource());
metricsHelper.assertCounter("disableTable_num_ops", 2, metrics.getSource());
handler.getTableNames(); // This will have an artificial delay.
// 3 to 6 seconds (to account for potential slowness), measured in nanoseconds.
verifyMetricRange(metrics, "getTableNames_avg_time", 3L * 1000 * 1000 * 1000,
6L * 1000 * 1000 * 1000);
// 3 to 6 seconds (to account for potential slowness), measured in nanoseconds
metricsHelper.assertGaugeGt("getTableNames_avg_time", 3L * 1000 * 1000 * 1000, metrics.getSource());
metricsHelper.assertGaugeLt("getTableNames_avg_time",6L * 1000 * 1000 * 1000, metrics.getSource());
}
private static Hbase.Iface getHandlerForMetricsTest(ThriftMetrics metrics, Configuration conf)
@ -181,17 +185,9 @@ public class TestThriftServer {
}
private static ThriftMetrics getMetrics(Configuration conf) throws Exception {
setupMetricsContext();
return new ThriftMetrics(ThriftServerRunner.DEFAULT_LISTEN_PORT, conf, Hbase.Iface.class);
return new ThriftMetrics( conf, ThriftMetrics.ThriftServerType.ONE);
}
private static void setupMetricsContext() throws IOException {
ContextFactory factory = ContextFactory.getFactory();
factory.setAttribute(ThriftMetrics.CONTEXT_NAME + ".class",
NoEmitMetricsContext.class.getName());
MetricsUtil.getContext(ThriftMetrics.CONTEXT_NAME)
.createRecord(ThriftMetrics.CONTEXT_NAME).remove();
}
public static void createTestTables(Hbase.Iface handler) throws Exception {
// Create/enable/disable/delete tables, ensure methods act correctly
@ -224,31 +220,6 @@ public class TestThriftServer {
assertEquals(handler.getTableNames().size(), 0);
}
private static void verifyMetrics(ThriftMetrics metrics, String name, long expectValue)
throws Exception {
long metricVal = getMetricValue(metrics, name);
assertEquals(expectValue, metricVal);
}
private static void verifyMetricRange(ThriftMetrics metrics, String name,
long minValue, long maxValue)
throws Exception {
long metricVal = getMetricValue(metrics, name);
if (metricVal < minValue || metricVal > maxValue) {
throw new AssertionError("Value of metric " + name + " is outside of the expected " +
"range [" + minValue + ", " + maxValue + "]: " + metricVal);
}
}
private static long getMetricValue(ThriftMetrics metrics, String name) {
MetricsContext context = MetricsUtil.getContext(
ThriftMetrics.CONTEXT_NAME);
metrics.doUpdates(context);
OutputRecord record = context.getAllRecords().get(
ThriftMetrics.CONTEXT_NAME).iterator().next();
return record.getMetric(name).longValue();
}
public void doTestIncrements() throws Exception {
ThriftServerRunner.HBaseHandler handler =
new ThriftServerRunner.HBaseHandler(UTIL.getConfiguration());

View File

@ -18,28 +18,16 @@
*/
package org.apache.hadoop.hbase.thrift2;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.CompatibilityFactory;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.MediumTests;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.test.MetricsAssertHelper;
import org.apache.hadoop.hbase.thrift.ThriftMetrics;
import org.apache.hadoop.hbase.thrift2.generated.TColumn;
import org.apache.hadoop.hbase.thrift2.generated.TColumnIncrement;
@ -55,11 +43,6 @@ import org.apache.hadoop.hbase.thrift2.generated.TPut;
import org.apache.hadoop.hbase.thrift2.generated.TResult;
import org.apache.hadoop.hbase.thrift2.generated.TScan;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.metrics.ContextFactory;
import org.apache.hadoop.metrics.MetricsContext;
import org.apache.hadoop.metrics.MetricsUtil;
import org.apache.hadoop.metrics.spi.NoEmitMetricsContext;
import org.apache.hadoop.metrics.spi.OutputRecord;
import org.apache.thrift.TException;
import org.junit.AfterClass;
import org.junit.Before;
@ -67,6 +50,14 @@ import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import static org.junit.Assert.*;
/**
* Unit testing for ThriftServer.HBaseHandler, a part of the org.apache.hadoop.hbase.thrift2 package.
*/
@ -90,6 +81,11 @@ public class TestThriftHBaseServiceHandler {
.setMaxVersions(2)
};
private static final MetricsAssertHelper metricsHelper =
CompatibilityFactory.getInstance(MetricsAssertHelper.class);
public void assertTColumnValuesEqual(List<TColumnValue> columnValuesA, List<TColumnValue> columnValuesB) {
assertEquals(columnValuesA.size(), columnValuesB.size());
Comparator<TColumnValue> comparator = new Comparator<TColumnValue>() {
@ -557,50 +553,14 @@ public class TestThriftHBaseServiceHandler {
handler.put(table, put);
assertTrue(handler.exists(table, get));
logMetrics(metrics);
verifyMetrics(metrics, "put_num_ops", 1);
verifyMetrics(metrics, "exists_num_ops", 2);
metricsHelper.assertCounter("put_num_ops", 1, metrics.getSource());
metricsHelper.assertCounter( "exists_num_ops", 2, metrics.getSource());
}
private static ThriftMetrics getMetrics(Configuration conf) throws Exception {
setupMetricsContext();
return new ThriftMetrics(Integer.parseInt(ThriftServer.DEFAULT_LISTEN_PORT),
conf, THBaseService.Iface.class);
}
private static void setupMetricsContext() throws IOException {
ContextFactory factory = ContextFactory.getFactory();
factory.setAttribute(ThriftMetrics.CONTEXT_NAME + ".class",
NoEmitMetricsContext.class.getName());
MetricsUtil.getContext(ThriftMetrics.CONTEXT_NAME)
.createRecord(ThriftMetrics.CONTEXT_NAME).remove();
}
private static void logMetrics(ThriftMetrics metrics) throws Exception {
if (LOG.isDebugEnabled()) {
return;
}
MetricsContext context = MetricsUtil.getContext(
ThriftMetrics.CONTEXT_NAME);
metrics.doUpdates(context);
for (String key : context.getAllRecords().keySet()) {
for (OutputRecord record : context.getAllRecords().get(key)) {
for (String name : record.getMetricNames()) {
LOG.debug("metrics:" + name + " value:" +
record.getMetric(name).intValue());
}
}
}
}
private static void verifyMetrics(ThriftMetrics metrics, String name, int expectValue)
throws Exception {
MetricsContext context = MetricsUtil.getContext(
ThriftMetrics.CONTEXT_NAME);
metrics.doUpdates(context);
OutputRecord record = context.getAllRecords().get(
ThriftMetrics.CONTEXT_NAME).iterator().next();
assertEquals(expectValue, record.getMetric(name).intValue());
ThriftMetrics m = new ThriftMetrics(conf, ThriftMetrics.ThriftServerType.TWO);
m.getSource().init(); //Clear all the metrics
return m;
}
@org.junit.Rule

View File

@ -128,13 +128,13 @@ Access restriction: The method getLong(Object, long) from the type Unsafe is not
<title>Building HBase</title>
<section xml:id="build.basic">
<title>Basic Compile</title>
<para>Thanks to maven, building HBase is easy. You can read about the various maven commands in <xref linkend="maven.build.commands"/>, but the simplest command to compile HBase from its java source code is:
<para>Thanks to maven, building HBase is pretty easy. You can read about the various maven commands in <xref linkend="maven.build.commands"/>, but the simplest command to compile HBase from its java source code is:
<programlisting>
mvn compile
mvn package -DskipTests
</programlisting>
Or, to clean up before compiling:
<programlisting>
mvn clean compile
mvn clean package -DskipTests
</programlisting>
With Eclipse set up as explained above in <xref linkend="eclipse"/>, you can also simply use the build command in Eclipse. To create the full installable HBase package takes a little bit more work, so read on.
</para>