You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by jy...@apache.org on 2014/10/27 21:53:59 UTC

[1/3] PHOENIX-1286 Remove hadoop2 compat modules

Repository: phoenix
Updated Branches:
  refs/heads/master 4ed9ddb8f -> 842f8a8a8


http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop2-compat/src/test/java/org/apache/phoenix/trace/TraceMetricsSourceTest.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop2-compat/src/test/java/org/apache/phoenix/trace/TraceMetricsSourceTest.java b/phoenix-hadoop2-compat/src/test/java/org/apache/phoenix/trace/TraceMetricsSourceTest.java
deleted file mode 100644
index 3258e8a..0000000
--- a/phoenix-hadoop2-compat/src/test/java/org/apache/phoenix/trace/TraceMetricsSourceTest.java
+++ /dev/null
@@ -1,96 +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.phoenix.trace;
-
-import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.hadoop.metrics2.MetricsCollector;
-import org.apache.hadoop.metrics2.MetricsRecordBuilder;
-import org.apache.hadoop.metrics2.MetricsTag;
-import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
-import org.cloudera.htrace.Span;
-import org.cloudera.htrace.impl.MilliSpan;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Test that the @{link TraceMetricSource} correctly handles different kinds of traces
- */
-public class TraceMetricsSourceTest {
-
-  @BeforeClass
-  public static void setup() throws Exception{
-    DefaultMetricsSystem.setMiniClusterMode(true);
-  }
-
-  /**
-   * For PHOENIX-1126, Phoenix originally assumed all the annotation values were integers,
-   * but HBase writes some strings as well, so we need to be able to handle that too
-   */
-  @Test
-  public void testNonIntegerAnnotations(){
-    Span span = getSpan();
-    // make sure its less than the length of an integer
-    byte[] value = Bytes.toBytes("a");
-    byte[] someInt = Bytes.toBytes(1);
-    assertTrue(someInt.length >value.length);
-
-    // an annotation that is not an integer
-    span.addKVAnnotation(Bytes.toBytes("key"), value);
-
-    // Create the sink and write the span
-    TraceMetricSource source = new TraceMetricSource();
-    source.receiveSpan(span);
-  }
-
-  @Test
-  public void testIntegerAnnotations(){
-    Span span = getSpan();
-
-    // add annotation through the phoenix interfaces
-    TracingCompat.addAnnotation(span, "message", 10);
-
-    TraceMetricSource source = new TraceMetricSource();
-    source.receiveSpan(span);
-  }
-
-  /**
-   * If the source does not write any metrics when there are no spans, i.e. when initialized,
-   * then the metrics system will discard the source, so it needs to always emit some metrics.
-   */
-  @Test
-  public void testWritesInfoWhenNoSpans(){
-    TraceMetricSource source = new TraceMetricSource();
-    MetricsCollector collector = Mockito.mock(MetricsCollector.class);
-    MetricsRecordBuilder builder = Mockito.mock(MetricsRecordBuilder.class);
-    Mockito.when(collector.addRecord(Mockito.anyString())).thenReturn(builder);
-
-    source.getMetrics(collector, true);
-
-    // verify that we add a record and that the record has some info
-    Mockito.verify(collector).addRecord(Mockito.anyString());
-    Mockito.verify(builder).add(Mockito.any(MetricsTag.class));
-  }
-
-  private Span getSpan(){
-    return new MilliSpan("test span", 0, 1 , 2, "pid");
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop2-compat/src/test/java/org/apache/phoenix/trace/TracingTest.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop2-compat/src/test/java/org/apache/phoenix/trace/TracingTest.java b/phoenix-hadoop2-compat/src/test/java/org/apache/phoenix/trace/TracingTest.java
deleted file mode 100644
index ffe6c82..0000000
--- a/phoenix-hadoop2-compat/src/test/java/org/apache/phoenix/trace/TracingTest.java
+++ /dev/null
@@ -1,34 +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.phoenix.trace;
-
-import static org.junit.Assert.assertNotNull;
-
-import org.junit.Test;
-
-public class TracingTest {
-
-    /**
-     * Test that we can correctly load a class that will convert the tracing output to metrics
-     * @throws Exception on failure
-     */
-    @Test
-    public void testLoadTracingToMetrics() throws Exception{
-        assertNotNull("Didn't find a trace receiver", TracingCompat.newTraceMetricSource());
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index c7544f4..888f575 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,12 +24,9 @@
 
   <modules>
     <module>phoenix-core</module>
-    <module>phoenix-hadoop-compat</module>
     <module>phoenix-flume</module>
     <module>phoenix-pig</module>
     <module>phoenix-assembly</module>
-    <!--Temporary inclusion - to be removed in next patch, for ease of review -->
-    <module>phoenix-hadoop2-compat</module>
   </modules>
 
   <repositories>
@@ -410,25 +407,6 @@
       </dependency>
       <dependency>
         <groupId>org.apache.phoenix</groupId>
-        <artifactId>phoenix-hadoop-compat</artifactId>
-        <version>${project.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.phoenix</groupId>
-        <artifactId>phoenix-hadoop-compat</artifactId>
-        <version>${project.version}</version>
-        <classifier>tests</classifier>
-        <scope>test</scope>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.phoenix</groupId>
-        <artifactId>phoenix-hadoop2-compat</artifactId>
-        <version>${project.version}</version>
-        <classifier>tests</classifier>
-        <scope>test</scope>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.phoenix</groupId>
         <artifactId>phoenix-flume</artifactId>
         <version>${project.version}</version>
       </dependency>
@@ -437,11 +415,6 @@
         <artifactId>phoenix-pig</artifactId>
         <version>${project.version}</version>
       </dependency>
-      <dependency>
-        <groupId>org.apache.phoenix</groupId>
-        <artifactId>phoenix-hadoop2-compat</artifactId>
-        <version>${project.version}</version>
-      </dependency>
 
       <!-- HBase dependencies -->
       <dependency>


[2/3] PHOENIX-1286 Remove hadoop2 compat modules

Posted by jy...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/main/java/org/apache/phoenix/trace/TracingUtils.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/trace/TracingUtils.java b/phoenix-core/src/main/java/org/apache/phoenix/trace/TracingUtils.java
new file mode 100644
index 0000000..6ae52d8
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/trace/TracingUtils.java
@@ -0,0 +1,63 @@
+/**
+ * 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.phoenix.trace;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Pair;
+import org.cloudera.htrace.Span;
+
+/**
+ * Utilities for tracing
+ */
+public class TracingUtils {
+
+    private static final Log LOG = LogFactory.getLog(TracingUtils.class);
+
+    public static final String METRIC_SOURCE_KEY = "phoenix.";
+
+    /** Set context to enable filtering */
+    public static final String METRICS_CONTEXT = "tracing";
+
+    /** Marker metric to ensure that we register the tracing mbeans */
+    public static final String METRICS_MARKER_CONTEXT = "marker";
+
+    public static void addAnnotation(Span span, String message, int value) {
+        span.addKVAnnotation(message.getBytes(), Bytes.toBytes(Integer.toString(value)));
+    }
+
+    public static Pair<String, String> readAnnotation(byte[] key, byte[] value) {
+        return new Pair<String, String>(new String(key), Bytes.toString(value));
+    }
+
+    /**
+     * @see #getTraceMetricName(String)
+     */
+    public static final String getTraceMetricName(long traceId) {
+        return getTraceMetricName(Long.toString(traceId));
+    }
+
+    /**
+     * @param traceId unique id of the trace
+     * @return the name of the metric record that should be generated for a given trace
+     */
+    public static final String getTraceMetricName(String traceId) {
+        return METRIC_SOURCE_KEY + traceId;
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/main/java/org/apache/phoenix/trace/util/Tracing.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/trace/util/Tracing.java b/phoenix-core/src/main/java/org/apache/phoenix/trace/util/Tracing.java
index d0677cf..b093b9c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/trace/util/Tracing.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/trace/util/Tracing.java
@@ -36,8 +36,7 @@ import org.apache.phoenix.call.CallWrapper;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.query.QueryServicesOptions;
-import org.apache.phoenix.trace.TracingCompat;
-import org.apache.phoenix.util.StringUtil;
+import org.apache.phoenix.trace.TraceMetricSource;
 import org.cloudera.htrace.Sampler;
 import org.cloudera.htrace.Span;
 import org.cloudera.htrace.Trace;
@@ -313,7 +312,7 @@ public class Tracing {
     public synchronized static void addTraceMetricsSource() {
         try {
             if (!initialized) {
-                Trace.addReceiver(TracingCompat.newTraceMetricSource());
+                Trace.addReceiver(new TraceMetricSource());
             }
         } catch (RuntimeException e) {
             LOG.warn("Tracing will outputs will not be written to any metrics sink! No "

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/test/java/org/apache/hadoop/metrics2/impl/ExposedMetricCounterLong.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/hadoop/metrics2/impl/ExposedMetricCounterLong.java b/phoenix-core/src/test/java/org/apache/hadoop/metrics2/impl/ExposedMetricCounterLong.java
new file mode 100644
index 0000000..f4dfd74
--- /dev/null
+++ b/phoenix-core/src/test/java/org/apache/hadoop/metrics2/impl/ExposedMetricCounterLong.java
@@ -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.metrics2.impl;
+
+import org.apache.hadoop.metrics2.MetricsInfo;
+
+/**
+ *
+ */
+public class ExposedMetricCounterLong extends MetricCounterLong {
+
+
+
+  /**
+   * @param info
+   * @param value
+   */
+  public ExposedMetricCounterLong(MetricsInfo info, long value) {
+    super(info, value);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/test/java/org/apache/hadoop/metrics2/impl/ExposedMetricsRecordImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/hadoop/metrics2/impl/ExposedMetricsRecordImpl.java b/phoenix-core/src/test/java/org/apache/hadoop/metrics2/impl/ExposedMetricsRecordImpl.java
new file mode 100644
index 0000000..c5f54e6
--- /dev/null
+++ b/phoenix-core/src/test/java/org/apache/hadoop/metrics2/impl/ExposedMetricsRecordImpl.java
@@ -0,0 +1,42 @@
+/*
+ * 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.metrics2.impl;
+
+import java.util.List;
+
+import org.apache.hadoop.metrics2.AbstractMetric;
+import org.apache.hadoop.metrics2.MetricsInfo;
+import org.apache.hadoop.metrics2.MetricsTag;
+
+/**
+ * Helper class to access the package-private {@link MetricsRecordImpl}
+ */
+@SuppressWarnings("javadoc")
+public class ExposedMetricsRecordImpl extends MetricsRecordImpl {
+
+  /**
+   * @param info
+   * @param timestamp
+   * @param tags
+   * @param metrics
+   */
+  public ExposedMetricsRecordImpl(MetricsInfo info, long timestamp, List<MetricsTag> tags,
+      Iterable<AbstractMetric> metrics) {
+    super(info, timestamp, tags, metrics);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/test/java/org/apache/hadoop/metrics2/lib/ExposedMetricsInfoImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/hadoop/metrics2/lib/ExposedMetricsInfoImpl.java b/phoenix-core/src/test/java/org/apache/hadoop/metrics2/lib/ExposedMetricsInfoImpl.java
new file mode 100644
index 0000000..1ad1553
--- /dev/null
+++ b/phoenix-core/src/test/java/org/apache/hadoop/metrics2/lib/ExposedMetricsInfoImpl.java
@@ -0,0 +1,34 @@
+/**
+ * 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.metrics2.lib;
+
+import org.apache.hadoop.metrics2.lib.MetricsInfoImpl;
+
+/**
+ * Helper class to expose access to the {@link org.apache.hadoop.metrics2.lib.MetricsInfoImpl}
+ */
+public class ExposedMetricsInfoImpl extends MetricsInfoImpl {
+
+    /**
+     * @param name
+     * @param description
+     */
+    public ExposedMetricsInfoImpl(String name, String description) {
+        super(name, description);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/test/java/org/apache/phoenix/metrics/LoggingSink.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/metrics/LoggingSink.java b/phoenix-core/src/test/java/org/apache/phoenix/metrics/LoggingSink.java
new file mode 100644
index 0000000..2cea684
--- /dev/null
+++ b/phoenix-core/src/test/java/org/apache/phoenix/metrics/LoggingSink.java
@@ -0,0 +1,60 @@
+/**
+ * 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.phoenix.metrics;
+
+import org.apache.commons.configuration.SubsetConfiguration;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.metrics2.AbstractMetric;
+import org.apache.hadoop.metrics2.MetricsRecord;
+import org.apache.hadoop.metrics2.MetricsSink;
+import org.apache.phoenix.trace.TracingUtils;
+
+/**
+ * Simple sink that just logs the output of all the metrics that start with
+ * {@link org.apache.phoenix.trace.TracingUtils#METRIC_SOURCE_KEY}
+ */
+public class LoggingSink implements MetricsSink {
+
+    private static final Log LOG = LogFactory.getLog(LoggingSink.class);
+
+    @Override
+    public void init(SubsetConfiguration config) {
+    }
+
+    @Override
+    public void putMetrics(MetricsRecord record) {
+        // we could wait until flush, but this is a really lightweight process, so we just write
+        // them
+        // as soon as we get them
+        if (!LOG.isDebugEnabled()) {
+            return;
+        }
+        LOG.debug("Found record:" + record.name());
+        for (AbstractMetric metric : record.metrics()) {
+            // just print the metric we care about
+            if (metric.name().startsWith(TracingUtils.METRIC_SOURCE_KEY)) {
+                LOG.debug("\t metric:" + metric);
+            }
+        }
+    }
+
+    @Override
+    public void flush() {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/test/java/org/apache/phoenix/trace/TraceMetricsSourceTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/trace/TraceMetricsSourceTest.java b/phoenix-core/src/test/java/org/apache/phoenix/trace/TraceMetricsSourceTest.java
new file mode 100644
index 0000000..5cb34b8
--- /dev/null
+++ b/phoenix-core/src/test/java/org/apache/phoenix/trace/TraceMetricsSourceTest.java
@@ -0,0 +1,96 @@
+/**
+ * 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.phoenix.trace;
+
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.metrics2.MetricsCollector;
+import org.apache.hadoop.metrics2.MetricsRecordBuilder;
+import org.apache.hadoop.metrics2.MetricsTag;
+import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
+import org.cloudera.htrace.Span;
+import org.cloudera.htrace.impl.MilliSpan;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test that the @{link TraceMetricSource} correctly handles different kinds of traces
+ */
+public class TraceMetricsSourceTest {
+
+  @BeforeClass
+  public static void setup() throws Exception{
+    DefaultMetricsSystem.setMiniClusterMode(true);
+  }
+
+  /**
+   * For PHOENIX-1126, Phoenix originally assumed all the annotation values were integers,
+   * but HBase writes some strings as well, so we need to be able to handle that too
+   */
+  @Test
+  public void testNonIntegerAnnotations(){
+    Span span = getSpan();
+    // make sure its less than the length of an integer
+    byte[] value = Bytes.toBytes("a");
+    byte[] someInt = Bytes.toBytes(1);
+    assertTrue(someInt.length >value.length);
+
+    // an annotation that is not an integer
+    span.addKVAnnotation(Bytes.toBytes("key"), value);
+
+    // Create the sink and write the span
+    TraceMetricSource source = new TraceMetricSource();
+    source.receiveSpan(span);
+  }
+
+  @Test
+  public void testIntegerAnnotations(){
+    Span span = getSpan();
+
+    // add annotation through the phoenix interfaces
+    TracingUtils.addAnnotation(span, "message", 10);
+
+    TraceMetricSource source = new TraceMetricSource();
+    source.receiveSpan(span);
+  }
+
+  /**
+   * If the source does not write any metrics when there are no spans, i.e. when initialized,
+   * then the metrics system will discard the source, so it needs to always emit some metrics.
+   */
+  @Test
+  public void testWritesInfoWhenNoSpans(){
+    TraceMetricSource source = new TraceMetricSource();
+    MetricsCollector collector = Mockito.mock(MetricsCollector.class);
+    MetricsRecordBuilder builder = Mockito.mock(MetricsRecordBuilder.class);
+    Mockito.when(collector.addRecord(Mockito.anyString())).thenReturn(builder);
+
+    source.getMetrics(collector, true);
+
+    // verify that we add a record and that the record has some info
+    Mockito.verify(collector).addRecord(Mockito.anyString());
+    Mockito.verify(builder).add(Mockito.any(MetricsTag.class));
+  }
+
+  private Span getSpan(){
+    return new MilliSpan("test span", 0, 1 , 2, "pid");
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop-compat/pom.xml
----------------------------------------------------------------------
diff --git a/phoenix-hadoop-compat/pom.xml b/phoenix-hadoop-compat/pom.xml
deleted file mode 100644
index c2f810a..0000000
--- a/phoenix-hadoop-compat/pom.xml
+++ /dev/null
@@ -1,89 +0,0 @@
-<?xml version='1.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.
-
--->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.phoenix</groupId>
-    <artifactId>phoenix</artifactId>
-    <version>5.0.0-SNAPSHOT</version>
-  </parent>
-  <artifactId>phoenix-hadoop-compat</artifactId>
-  <name>Phoenix Hadoop Compatibility</name>
-  <description>Compatibility layer for Hadoop versions</description>
-  
-  <build>
-    <plugins>
-      <!-- Run with -Dmaven.test.skip.exec=true to build -tests.jar without running 
-        tests (this is needed for upstream projects whose tests need this jar simply for 
-        compilation) -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <version>2.4</version><!--$NO-MVN-MAN-VER$-->
-        <executions>
-          <execution>
-            <phase>prepare-package
-            </phase>
-            <goals>
-              <goal>test-jar</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <!--Make it so assembly:single does nothing in here -->
-        <artifactId>maven-assembly-plugin</artifactId>
-        <configuration>
-          <skipAssembly>true</skipAssembly>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.cloudera.htrace</groupId>
-      <artifactId>htrace-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hbase</groupId>
-      <artifactId>hbase-hadoop-compat</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>log4j</groupId>
-      <artifactId>log4j</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hbase</groupId>
-      <artifactId>hbase-common</artifactId>
-    </dependency>
-  </dependencies>
-</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/MetricInfo.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/MetricInfo.java b/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/MetricInfo.java
deleted file mode 100644
index e6ad976..0000000
--- a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/MetricInfo.java
+++ /dev/null
@@ -1,51 +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.phoenix.metrics;
-
-/**
- * Metrics and their conversion from the trace name to the name we store in the stats table
- */
-public enum MetricInfo {
-
-    TRACE("", "trace_id"),
-    SPAN("span_id", "span_id"),
-    PARENT("parent_id", "parent_id"),
-    START("start_time", "start_time"),
-    END("end_time", "end_time"),
-    TAG("phoenix.tag", "t"),
-    ANNOTATION("phoenix.annotation", "a"),
-    HOSTNAME("Hostname", "hostname"),
-    DESCRIPTION("", "description");
-
-    public final String traceName;
-    public final String columnName;
-
-    private MetricInfo(String traceName, String columnName) {
-        this.traceName = traceName;
-        this.columnName = columnName;
-    }
-
-    public static String getColumnName(String traceName) {
-        for (MetricInfo info : MetricInfo.values()) {
-            if (info.traceName.equals(traceName)) {
-                return info.columnName;
-            }
-        }
-        throw new IllegalArgumentException("Unknown tracename: " + traceName);
-    }
-}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/Metrics.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/Metrics.java b/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/Metrics.java
deleted file mode 100644
index 5bc8545..0000000
--- a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/Metrics.java
+++ /dev/null
@@ -1,80 +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.phoenix.metrics;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.hbase.CompatibilitySingletonFactory;
-
-public class Metrics {
-
-    private static final Log LOG = LogFactory.getLog(Metrics.class);
-
-  private static volatile MetricsManager manager;
-
-    private static boolean initialized;
-
-    /** This must match the prefix that we are using in the hadoop-metrics2 config on the client */
-    public static final String METRICS_SYSTEM_NAME = "phoenix";
-    public static MetricsManager initialize() {
-        MetricsManager manager = Metrics.getManager();
-        // if the jars aren't on the classpath, then we don't start the metrics system
-        if (manager == null) {
-            LOG.warn("Phoenix metrics could not be initialized - no MetricsManager found!");
-            return null;
-        }
-        // only initialize the metrics system once
-        synchronized (Metrics.class) {
-            if (!initialized) {
-                LOG.info("Initializing metrics system: " + Metrics.METRICS_SYSTEM_NAME);
-                manager.initialize(Metrics.METRICS_SYSTEM_NAME);
-                initialized = true;
-            }
-        }
-        return manager;
-    }
-
-  /**
-   * @return get the first {@link MetricsManager} on the classpath. Always returns the same object
-   */
-  public static MetricsManager getManager(){
-    if(manager == null){
-      synchronized(Metrics.class){
-        if(manager == null){
-          manager = CompatibilitySingletonFactory.getInstance(MetricsManager.class);
-        }
-      }
-    }
-    return manager;
-  }
-
-    private static volatile boolean sinkInitialized = false;
-
-    /**
-     * Mark that the metrics/tracing sink has been initialized
-     */
-    public static void markSinkInitialized() {
-        sinkInitialized = true;
-    }
-
-    public static void ensureConfigured() {
-        if (!sinkInitialized) {
-            LOG.warn("Phoenix metrics2/tracing sink was not started. Should be it be?");
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/MetricsManager.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/MetricsManager.java b/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/MetricsManager.java
deleted file mode 100644
index 13c9435..0000000
--- a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/MetricsManager.java
+++ /dev/null
@@ -1,58 +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.phoenix.metrics;
-
-/**
- * Metrics management system. Backed by the underlying hadoop metrics, depending on the project on
- * the classpath.
- * <p>
- * The underlying types passed to method must match the expected metrics type - this will vary for
- * the underlying metrics systems (hadoop1 vs hadoop2), but can't be specified at this layer because
- * we must be compatible with both systems.
- */
-public interface MetricsManager {
-
-    /**
-     * @param metricsSystemName the metrics prefix to initialize, if it hasn't already been
-     *            initialized. Not assumed to be thread-safe, unless otherwise noted in the
-     *            implementation.
-     */
-    public abstract void initialize(String metricsSystemName);
-
-    /**
-     * Register a metrics sink
-     * @param <T> the type of the sink
-     * @param sink to register
-     * @param name of the sink. Must be unique.
-     * @param desc the description of the sink
-     * @return the sink
-     */
-    public abstract <T> T register(String name, String desc, T sink);
-
-    /**
-     * Register a metrics source.
-     * @param name name of the source - must be unique
-     * @param description description of the source
-     * @param source to register.
-     * @param <T> the type of the source
-     * @return the source
-     */
-    public abstract <T> T registerSource(String name, String description, T source);
-
-    public void shutdown();
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/MetricsWriter.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/MetricsWriter.java b/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/MetricsWriter.java
deleted file mode 100644
index 0e8b9fe..0000000
--- a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/MetricsWriter.java
+++ /dev/null
@@ -1,31 +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.phoenix.metrics;
-
-
-/**
- * Generic writer for a phoenix metric
- */
-public interface MetricsWriter {
-
-    public void initialize();
-
-    public void flush();
-
-    public void addMetrics(PhoenixMetricsRecord record);
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/PhoenixAbstractMetric.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/PhoenixAbstractMetric.java b/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/PhoenixAbstractMetric.java
deleted file mode 100644
index 27ae6b8..0000000
--- a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/PhoenixAbstractMetric.java
+++ /dev/null
@@ -1,30 +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.phoenix.metrics;
-
-
-public interface PhoenixAbstractMetric {
-
-    public String getName();
-
-    /**
-     * Get the value of the metric
-     * @return the value of the metric
-     */
-    public Number value();
-}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/PhoenixMetricTag.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/PhoenixMetricTag.java b/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/PhoenixMetricTag.java
deleted file mode 100644
index 123cc1c..0000000
--- a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/PhoenixMetricTag.java
+++ /dev/null
@@ -1,27 +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.phoenix.metrics;
-
-public interface PhoenixMetricTag {
-
-    public String name();
-
-    public String description();
-
-    public String value();
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/PhoenixMetricsRecord.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/PhoenixMetricsRecord.java b/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/PhoenixMetricsRecord.java
deleted file mode 100644
index 68f7c46..0000000
--- a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/metrics/PhoenixMetricsRecord.java
+++ /dev/null
@@ -1,35 +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.phoenix.metrics;
-
-import java.util.Collection;
-
-
-/**
- *
- */
-public interface PhoenixMetricsRecord {
-
-    public String name();
-
-    public String description();
-
-    public Iterable<PhoenixAbstractMetric> metrics();
-
-    public Collection<PhoenixMetricTag> tags();
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/trace/PhoenixSpanReceiver.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/trace/PhoenixSpanReceiver.java b/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/trace/PhoenixSpanReceiver.java
deleted file mode 100644
index 7e4e09c..0000000
--- a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/trace/PhoenixSpanReceiver.java
+++ /dev/null
@@ -1,26 +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.phoenix.trace;
-
-import org.cloudera.htrace.SpanReceiver;
-
-/**
- * Marker interface for phoenix specific receivers.
- */
-public interface PhoenixSpanReceiver extends SpanReceiver {
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/trace/TestableMetricsWriter.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/trace/TestableMetricsWriter.java b/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/trace/TestableMetricsWriter.java
deleted file mode 100644
index b6bc75d..0000000
--- a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/trace/TestableMetricsWriter.java
+++ /dev/null
@@ -1,30 +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.phoenix.trace;
-
-import org.apache.phoenix.metrics.MetricsWriter;
-
-/**
- * Marker interface for a MetricsWriter that can be registered to the current metrics system. The
- * writer should convert from the metrics information it receives from the metrics system to Phoenix
- * records that the MetricsWriter can read (and subsequently write).
- */
-public interface TestableMetricsWriter {
-
-    public void setWriterForTesting(MetricsWriter writer);
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/trace/TracingCompat.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/trace/TracingCompat.java b/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/trace/TracingCompat.java
deleted file mode 100644
index e0a3410..0000000
--- a/phoenix-hadoop-compat/src/main/java/org/apache/phoenix/trace/TracingCompat.java
+++ /dev/null
@@ -1,89 +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.phoenix.trace;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.hbase.CompatibilityFactory;
-import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.hadoop.hbase.util.Pair;
-import org.apache.phoenix.metrics.MetricsWriter;
-import org.cloudera.htrace.Span;
-import org.cloudera.htrace.SpanReceiver;
-
-/**
- * Utilities for tracing that are common among the compatibility and core classes.
- */
-public class TracingCompat {
-
-    private static final Log LOG = LogFactory.getLog(TracingCompat.class);
-
-    /**
-     * @return a new SpanReceiver that will write to the correct metrics system
-     */
-    public static SpanReceiver newTraceMetricSource() {
-        return CompatibilityFactory.getInstance(PhoenixSpanReceiver.class);
-    }
-
-    public static final String METRIC_SOURCE_KEY = "phoenix.";
-
-    /** Set context to enable filtering */
-    public static final String METRICS_CONTEXT = "tracing";
-
-    /** Marker metric to ensure that we register the tracing mbeans */
-    public static final String METRICS_MARKER_CONTEXT = "marker";
-
-    public static void addAnnotation(Span span, String message, int value) {
-        span.addKVAnnotation(message.getBytes(), Bytes.toBytes(Integer.toString(value)));
-    }
-
-    public static Pair<String, String> readAnnotation(byte[] key, byte[] value) {
-        return new Pair<String, String>(new String(key), Bytes.toString(value));
-    }
-
-    public static MetricsWriter initializeWriter(String clazz) {
-        try {
-            MetricsWriter writer =
-                    Class.forName(clazz).asSubclass(MetricsWriter.class).newInstance();
-            writer.initialize();
-            return writer;
-        } catch (InstantiationException e) {
-            LOG.error("Failed to create metrics writer: " + clazz, e);
-        } catch (IllegalAccessException e) {
-            LOG.error("Failed to create metrics writer: " + clazz, e);
-        } catch (ClassNotFoundException e) {
-            LOG.error("Failed to create metrics writer: " + clazz, e);
-        }
-        return null;
-    }
-
-    /**
-     * @see #getTraceMetricName(String)
-     */
-    public static final String getTraceMetricName(long traceId) {
-        return getTraceMetricName(Long.toString(traceId));
-    }
-
-    /**
-     * @param traceId unique id of the trace
-     * @return the name of the metric record that should be generated for a given trace
-     */
-    public static final String getTraceMetricName(String traceId) {
-        return METRIC_SOURCE_KEY + traceId;
-    }
-}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop-compat/src/test/java/org/apache/phoenix/metrics/LoggingSink.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop-compat/src/test/java/org/apache/phoenix/metrics/LoggingSink.java b/phoenix-hadoop-compat/src/test/java/org/apache/phoenix/metrics/LoggingSink.java
deleted file mode 100644
index 97682b3..0000000
--- a/phoenix-hadoop-compat/src/test/java/org/apache/phoenix/metrics/LoggingSink.java
+++ /dev/null
@@ -1,56 +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.phoenix.metrics;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.phoenix.trace.TracingCompat;
-
-/**
- * Simple sink that just logs the output of all the metrics that start with
- * {@link TracingCompat#METRIC_SOURCE_KEY}
- */
-public class LoggingSink implements MetricsWriter {
-
-    private static final Log LOG = LogFactory.getLog(LoggingSink.class);
-
-    @Override
-    public void initialize() {
-    }
-
-    @Override
-    public void addMetrics(PhoenixMetricsRecord record) {
-        // we could wait until flush, but this is a really lightweight process, so we just write
-        // them
-        // as soon as we get them
-        if (!LOG.isDebugEnabled()) {
-            return;
-        }
-        LOG.debug("Found record:" + record.name());
-        for (PhoenixAbstractMetric metric : record.metrics()) {
-            // just print the metric we care about
-            if (metric.getName().startsWith(TracingCompat.METRIC_SOURCE_KEY)) {
-                LOG.debug("\t metric:" + metric);
-            }
-        }
-    }
-
-    @Override
-    public void flush() {
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop-compat/src/test/java/org/apache/phoenix/metrics/TracingTestCompat.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop-compat/src/test/java/org/apache/phoenix/metrics/TracingTestCompat.java b/phoenix-hadoop-compat/src/test/java/org/apache/phoenix/metrics/TracingTestCompat.java
deleted file mode 100644
index 8dd8a41..0000000
--- a/phoenix-hadoop-compat/src/test/java/org/apache/phoenix/metrics/TracingTestCompat.java
+++ /dev/null
@@ -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.phoenix.metrics;
-
-import org.apache.hadoop.hbase.CompatibilityFactory;
-import org.apache.phoenix.trace.TestableMetricsWriter;
-
-/**
- * Utility class for testing tracing
- */
-public class TracingTestCompat {
-
-    private TracingTestCompat() {
-        assert false;
-    }
-
-    public static TestableMetricsWriter newTraceMetricSink() {
-        return CompatibilityFactory.getInstance(TestableMetricsWriter.class);
-    }
-
-    /**
-     * Register the sink with the metrics system, so we don't need to specify it in the conf
-     * @param sink
-     */
-    public static void registerSink(MetricsWriter sink) {
-        TestableMetricsWriter writer = newTraceMetricSink();
-        writer.setWriterForTesting(sink);
-        Metrics.getManager().register("phoenix", "test sink gets logged", writer);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop2-compat/pom.xml
----------------------------------------------------------------------
diff --git a/phoenix-hadoop2-compat/pom.xml b/phoenix-hadoop2-compat/pom.xml
deleted file mode 100644
index 7944a51..0000000
--- a/phoenix-hadoop2-compat/pom.xml
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version='1.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.
-
--->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.phoenix</groupId>
-    <artifactId>phoenix</artifactId>
-    <version>5.0.0-SNAPSHOT</version>
-  </parent>
-  <artifactId>phoenix-hadoop2-compat</artifactId>
-  <name>Phoenix Hadoop2 Compatibility</name>
-
-  <dependencies>
-    <!-- Intra-project dependencies -->
-    <dependency>
-      <groupId>org.apache.phoenix</groupId>
-      <artifactId>phoenix-hadoop-compat</artifactId>
-    </dependency>
-    <!-- HBase -->
-    <dependency>
-    <groupId>org.apache.hbase</groupId>
-    <artifactId>hbase-common</artifactId>
-    <exclusions>
-      <exclusion>
-        <artifactId>hadoop-core</artifactId>
-        <groupId>org.apache.hadoop</groupId>
-      </exclusion>
-    </exclusions>
-    </dependency>
-    <!-- Hadoop -->
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-mapreduce-client-core</artifactId>
-      <version>${hadoop-two.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <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>
-    <!-- Other -->
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <!-- Test -->
-     <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
-    </dependency>
-  </dependencies>
-</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop2-compat/src/main/java/org/apache/phoenix/metrics/MetricsManagerImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop2-compat/src/main/java/org/apache/phoenix/metrics/MetricsManagerImpl.java b/phoenix-hadoop2-compat/src/main/java/org/apache/phoenix/metrics/MetricsManagerImpl.java
deleted file mode 100644
index 03e06a5..0000000
--- a/phoenix-hadoop2-compat/src/main/java/org/apache/phoenix/metrics/MetricsManagerImpl.java
+++ /dev/null
@@ -1,71 +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.phoenix.metrics;
-
-import java.util.Arrays;
-
-import org.apache.hadoop.metrics2.MetricsSink;
-import org.apache.hadoop.metrics2.MetricsSource;
-import org.apache.hadoop.metrics2.MetricsSystem;
-import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
-
-import com.google.common.base.Preconditions;
-
-/**
- *
- */
-public class MetricsManagerImpl implements MetricsManager {
-
-  private MetricsSystem system;
-
-  @Override
-  /**
-   * Register a metrics sink
-   * @param <T>   the type of the sink.
-   * @param sink  to register
-   * @param name  of the sink. Must be unique.
-   * @param desc  the description of the sink
-   * @return the sink
-   * @throws IllegalArgumentException if sink is not a MetricsSink
-   */
-  public <T> T register(String name, String desc, T sink) {
-    isA(sink, MetricsSink.class);
-    return (T) system.register(name, desc, (MetricsSink) sink);
-  }
-
-  public <T> T registerSource(String name, String desc, T source) {
-    isA(source, MetricsSource.class);
-    return (T) system.register(name, desc, (MetricsSource) source);
-  }
-
-  @Override
-  public void initialize(String prefix) {
-    this.system = DefaultMetricsSystem.initialize(prefix);
-  }
-
-  private <T> void isA(T object, Class<?>... classes) {
-    boolean match = false;
-    for (Class<?> clazz : classes) {
-      if (clazz.isAssignableFrom(object.getClass())) {
-        match = true;
-        break;
-      }
-    }
-    Preconditions.checkArgument(match, object + " is not one of " + Arrays.toString(classes));
-  }
-
-  @Override
-  public void shutdown() {
-    if (this.system != null) {
-      this.system.shutdown();
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop2-compat/src/main/java/org/apache/phoenix/trace/MetricsInfoImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop2-compat/src/main/java/org/apache/phoenix/trace/MetricsInfoImpl.java b/phoenix-hadoop2-compat/src/main/java/org/apache/phoenix/trace/MetricsInfoImpl.java
deleted file mode 100644
index 47c1dda..0000000
--- a/phoenix-hadoop2-compat/src/main/java/org/apache/phoenix/trace/MetricsInfoImpl.java
+++ /dev/null
@@ -1,63 +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.phoenix.trace;
-
-import com.google.common.base.Objects;
-import static com.google.common.base.Preconditions.*;
-import org.apache.hadoop.metrics2.MetricsInfo;
-
-/**
- * Making implementing metric info a little easier
- * <p>
- * Just a copy of the same from Hadoop, but exposed for usage.
- */
-public class MetricsInfoImpl implements MetricsInfo {
-  private final String name, description;
-
-  MetricsInfoImpl(String name, String description) {
-    this.name = checkNotNull(name, "name");
-    this.description = checkNotNull(description, "description");
-  }
-
-  @Override public String name() {
-    return name;
-  }
-
-  @Override public String description() {
-    return description;
-  }
-
-  @Override public boolean equals(Object obj) {
-    if (obj instanceof MetricsInfo) {
-      MetricsInfo other = (MetricsInfo) obj;
-      return Objects.equal(name, other.name()) &&
-             Objects.equal(description, other.description());
-    }
-    return false;
-  }
-
-  @Override public int hashCode() {
-    return Objects.hashCode(name, description);
-  }
-
-  @Override public String toString() {
-    return Objects.toStringHelper(this)
-        .add("name", name).add("description", description)
-        .toString();
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop2-compat/src/main/java/org/apache/phoenix/trace/PhoenixMetricsSink.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop2-compat/src/main/java/org/apache/phoenix/trace/PhoenixMetricsSink.java b/phoenix-hadoop2-compat/src/main/java/org/apache/phoenix/trace/PhoenixMetricsSink.java
deleted file mode 100644
index 3de7da3..0000000
--- a/phoenix-hadoop2-compat/src/main/java/org/apache/phoenix/trace/PhoenixMetricsSink.java
+++ /dev/null
@@ -1,191 +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.phoenix.trace;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-
-import javax.annotation.Nullable;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.SubsetConfiguration;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.metrics2.AbstractMetric;
-import org.apache.hadoop.metrics2.MetricsRecord;
-import org.apache.hadoop.metrics2.MetricsSink;
-import org.apache.hadoop.metrics2.MetricsTag;
-import org.apache.phoenix.metrics.Metrics;
-import org.apache.phoenix.metrics.MetricsWriter;
-import org.apache.phoenix.metrics.PhoenixAbstractMetric;
-import org.apache.phoenix.metrics.PhoenixMetricTag;
-import org.apache.phoenix.metrics.PhoenixMetricsRecord;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterators;
-
-/**
- * Translate metrics from a Hadoop2 metrics2 metric to a generic PhoenixMetric that a
- * {@link MetricsWriter} can then write out.
- * <p>
- * This class becomes unnecessary once we drop Hadoop1 support.
- */
-public class PhoenixMetricsSink implements MetricsSink, TestableMetricsWriter {
-
-  private static final Log LOG = LogFactory.getLog(PhoenixMetricsSink.class);
-  /**
-   * Metrics configuration key for the class that should be used for writing the output.
-   * <p>
-   * This would actually be set as: <code>
-   * phoenix.sink.&ltsome instance name&gt.writer-class
-   * </code> Where <tt>some instance name</tt> is just any unique name, so properties can be
-   * differentiated
-   */
-  public static final String PHOENIX_METRICS_WRITER_CLASS = "writer-class";
-
-  public static void setWriterClass(MetricsWriter writer, Configuration conf) {
-    conf.setProperty(PHOENIX_METRICS_WRITER_CLASS, writer.getClass().getName());
-  }
-
-  private MetricsWriter writer;
-
-  public PhoenixMetricsSink() {
-    LOG.info("Writing tracing metrics to phoenix table");
-    Metrics.markSinkInitialized();
-  }
-
-  @Override
-  public void init(SubsetConfiguration config) {
-    // instantiate the configured writer class
-    String clazz = config.getString(PHOENIX_METRICS_WRITER_CLASS);
-    LOG.info("Instantiating writer class: " + clazz);
-    this.writer = TracingCompat.initializeWriter(clazz);
-    Preconditions.checkNotNull(writer, "Could not correctly initialize metrics writer!");
-  }
-
-  @Override
-  @VisibleForTesting
-  public void setWriterForTesting(MetricsWriter writer) {
-    this.writer = writer;
-  }
-
-  @Override
-  public void putMetrics(MetricsRecord record) {
-    writer.addMetrics(wrap(record));
-  }
-
-  @Override
-  public void flush() {
-    writer.flush();
-  }
-
-  /**
-   * Convert the passed record to a {@link PhoenixMetricsRecord}
-   * @param record to convert
-   * @return a generic {@link PhoenixMetricsRecord} that delegates to the record in all things
-   */
-  private PhoenixMetricsRecord wrap(final MetricsRecord record) {
-    return new PhoenixMetricsRecord() {
-
-      @Override
-      public String name() {
-        return record.name();
-      }
-
-      @Override
-      public String description() {
-        return record.description();
-      }
-
-      @Override
-      public Iterable<PhoenixAbstractMetric> metrics() {
-        final Iterable<AbstractMetric> iterable = record.metrics();
-        return new Iterable<PhoenixAbstractMetric>(){
-
-          @Override
-          public Iterator<PhoenixAbstractMetric> iterator() {
-            final Iterator<AbstractMetric> iter = iterable.iterator();
-            return Iterators.transform(iter, new Function<AbstractMetric, PhoenixAbstractMetric>() {
-
-              @Override
-              @Nullable
-              public PhoenixAbstractMetric apply(@Nullable final AbstractMetric input) {
-                if (input == null) {
-                  return null;
-                }
-                return new PhoenixAbstractMetric() {
-
-                  @Override
-                  public Number value() {
-                    return input.value();
-                  }
-
-                  @Override
-                  public String getName() {
-                    return input.name();
-                  }
-
-                  @Override
-                  public String toString() {
-                    return input.toString();
-                  }
-                };
-              }
-            });
-          }
-        };
-      }
-
-      @Override
-      public Collection<PhoenixMetricTag> tags() {
-        Collection<PhoenixMetricTag> tags = new ArrayList<PhoenixMetricTag>();
-        Collection<MetricsTag> origTags = record.tags();
-        for (final MetricsTag tag : origTags) {
-          tags.add(new PhoenixMetricTag() {
-
-            @Override
-            public String name() {
-              return tag.name();
-            }
-
-            @Override
-            public String description() {
-              return tag.description();
-            }
-
-            @Override
-            public String value() {
-              return tag.value();
-            }
-
-            @Override
-            public String toString() {
-              return tag.toString();
-            }
-
-          });
-        }
-        return tags;
-      }
-
-    };
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop2-compat/src/main/java/org/apache/phoenix/trace/TraceMetricSource.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop2-compat/src/main/java/org/apache/phoenix/trace/TraceMetricSource.java b/phoenix-hadoop2-compat/src/main/java/org/apache/phoenix/trace/TraceMetricSource.java
deleted file mode 100644
index 1114a95..0000000
--- a/phoenix-hadoop2-compat/src/main/java/org/apache/phoenix/trace/TraceMetricSource.java
+++ /dev/null
@@ -1,197 +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.phoenix.trace;
-
-import static org.apache.phoenix.metrics.MetricInfo.ANNOTATION;
-import static org.apache.phoenix.metrics.MetricInfo.END;
-import static org.apache.phoenix.metrics.MetricInfo.PARENT;
-import static org.apache.phoenix.metrics.MetricInfo.SPAN;
-import static org.apache.phoenix.metrics.MetricInfo.START;
-import static org.apache.phoenix.metrics.MetricInfo.TAG;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.hadoop.hbase.util.Pair;
-import org.apache.hadoop.metrics2.MetricsCollector;
-import org.apache.hadoop.metrics2.MetricsInfo;
-import org.apache.hadoop.metrics2.MetricsRecordBuilder;
-import org.apache.hadoop.metrics2.MetricsSource;
-import org.apache.hadoop.metrics2.MetricsTag;
-import org.apache.hadoop.metrics2.lib.Interns;
-import org.apache.phoenix.metrics.MetricInfo;
-import org.apache.phoenix.metrics.Metrics;
-import org.apache.phoenix.metrics.MetricsManager;
-import org.cloudera.htrace.HTraceConfiguration;
-import org.cloudera.htrace.Span;
-import org.cloudera.htrace.SpanReceiver;
-import org.cloudera.htrace.TimelineAnnotation;
-import org.cloudera.htrace.impl.MilliSpan;
-
-/**
- * Sink for request traces ({@link SpanReceiver}) that pushes writes to {@link MetricsSource} in a
- * format that we can more easily consume.
- * <p>
- * <p>
- * Rather than write directly to a phoenix table, we drop it into the metrics queue so we can more
- * cleanly handle it asyncrhonously.Currently, {@link MilliSpan} submits the span in a synchronized
- * block to all the receivers, which could have a lot of overhead if we are submitting to multiple
- * receivers.
- * <p>
- * The format of the generated metrics is this:
- * <ol>
- *   <li>All Metrics from the same span have the same name (allowing correlation in the sink)</li>
- *   <li>The description of the metric describes what it contains. For instance,
- *   <ul>
- *     <li>{@link MetricInfo#PARENT} is the id of the parent of this span. (Root span is
- *     {@link Span#ROOT_SPAN_ID}).</li>
- *     <li>{@value MetricInfo#START} is the start time of the span</li>
- *     <li>{@value MetricInfo#END} is the end time of the span</li>
- *   </ul></li>
- *   <li>Each span's messages are contained in a {@link MetricsTag} with the same name as above and a
- *   generic counter for the number of messages (to differentiate messages and provide timeline
- *   ordering).</li>
- * </ol>
- * <p>
- * <i>So why even submit to metrics2 framework if we only have a single source?</i>
- * <p>
- * This allows us to make the updates in batches. We might have spans that finish before other spans
- * (for instance in the same parent). By batching the updates we can lessen the overhead on the
- * client, which is also busy doing 'real' work. <br>
- * We could make our own queue and manage batching and filtering and dropping extra metrics, but
- * that starts to get complicated fast (its not as easy as it sounds) so we use metrics2 to abstract
- * out that pipeline and also provides us flexibility to dump metrics to other sources.
- * <p>
- * This is a somewhat rough implementation - we do excessive locking for correctness,
- * rather than trying to make it fast, for the moment.
- */
-public class TraceMetricSource implements PhoenixSpanReceiver, MetricsSource {
-
-  private static final String EMPTY_STRING = "";
-
-  private static final String CONTEXT = "tracing";
-
-  private List<Metric> spans = new ArrayList<Metric>();
-
-  public TraceMetricSource() {
-    MetricsManager manager = Metrics.initialize();
-
-    // Register this instance.
-    // For right now, we ignore the MBean registration issues that show up in DEBUG logs. Basically,
-    // we need a Jmx MBean compliant name. We'll get to a better name when we want that later
-    manager.registerSource(CONTEXT, "Phoenix call tracing", this);
-  }
-
-  @Override
-  public void receiveSpan(Span span) {
-    Metric builder = new Metric(span);
-    // add all the metrics for the span
-    builder.addCounter(Interns.info(SPAN.traceName, EMPTY_STRING), span.getSpanId());
-    builder.addCounter(Interns.info(PARENT.traceName, EMPTY_STRING), span.getParentId());
-    builder.addCounter(Interns.info(START.traceName, EMPTY_STRING), span.getStartTimeMillis());
-    builder.addCounter(Interns.info(END.traceName, EMPTY_STRING), span.getStopTimeMillis());
-    // add the tags to the span. They were written in order received so we mark them as such
-    for (TimelineAnnotation ta : span.getTimelineAnnotations()) {
-      builder.add(new MetricsTag(Interns.info(TAG.traceName, Long.toString(ta.getTime())), ta
-          .getMessage()));
-    }
-
-    // add the annotations. We assume they are serialized as strings and integers, but that can
-    // change in the future
-    Map<byte[], byte[]> annotations = span.getKVAnnotations();
-    for (Entry<byte[], byte[]> annotation : annotations.entrySet()) {
-      Pair<String, String> val =
-          TracingCompat.readAnnotation(annotation.getKey(), annotation.getValue());
-      builder.add(new MetricsTag(Interns.info(ANNOTATION.traceName, val.getFirst()), val
-          .getSecond()));
-    }
-
-    // add the span to the list we care about
-    synchronized (this) {
-      spans.add(builder);
-    }
-  }
-
-  @Override
-  public void getMetrics(MetricsCollector collector, boolean all) {
-    // add a marker record so we know how many spans are used
-    // this is also necessary to ensure that we register the metrics source as an MBean (avoiding a
-    // runtime warning)
-    MetricsRecordBuilder marker = collector.addRecord(TracingCompat.METRICS_MARKER_CONTEXT);
-    marker.add(new MetricsTag(new MetricsInfoImpl("stat", "num spans"), Integer
-        .toString(spans.size())));
-
-    // actually convert the known spans into metric records as well
-    synchronized (this) {
-      for (Metric span : spans) {
-        MetricsRecordBuilder builder = collector.addRecord(new MetricsInfoImpl(TracingCompat
-            .getTraceMetricName(span.id), span.desc));
-        builder.setContext(TracingCompat.METRICS_CONTEXT);
-        for (Pair<MetricsInfo, Long> metric : span.counters) {
-          builder.addCounter(metric.getFirst(), metric.getSecond());
-        }
-        for (MetricsTag tag : span.tags) {
-          builder.add(tag);
-        }
-      }
-      // reset the spans so we don't keep a big chunk of memory around
-      spans = new ArrayList<Metric>();
-    }
-  }
-
-  @Override
-  public void close() throws IOException {
-    // noop
-  }
-
-  @Override
-  public void configure(HTraceConfiguration conf) {
-    // noop
-  }
-
-  private static class Metric {
-
-    List<Pair<MetricsInfo, Long>> counters = new ArrayList<Pair<MetricsInfo, Long>>();
-    List<MetricsTag> tags = new ArrayList<MetricsTag>();
-    private String id;
-    private String desc;
-
-    public Metric(Span span) {
-      this.id = Long.toString(span.getTraceId());
-      this.desc = span.getDescription();
-    }
-
-    /**
-     * @param metricsInfoImpl
-     * @param startTimeMillis
-     */
-    public void addCounter(MetricsInfo metricsInfoImpl, long startTimeMillis) {
-      counters.add(new Pair<MetricsInfo, Long>(metricsInfoImpl, startTimeMillis));
-    }
-
-    /**
-     * @param metricsTag
-     */
-    public void add(MetricsTag metricsTag) {
-      tags.add(metricsTag);
-    }
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop2-compat/src/main/resources/META-INF/services/org.apache.phoenix.metrics.MetricsManager
----------------------------------------------------------------------
diff --git a/phoenix-hadoop2-compat/src/main/resources/META-INF/services/org.apache.phoenix.metrics.MetricsManager b/phoenix-hadoop2-compat/src/main/resources/META-INF/services/org.apache.phoenix.metrics.MetricsManager
deleted file mode 100644
index 8430a48..0000000
--- a/phoenix-hadoop2-compat/src/main/resources/META-INF/services/org.apache.phoenix.metrics.MetricsManager
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.phoenix.metrics.MetricsManagerImpl
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop2-compat/src/main/resources/META-INF/services/org.apache.phoenix.trace.PhoenixSpanReceiver
----------------------------------------------------------------------
diff --git a/phoenix-hadoop2-compat/src/main/resources/META-INF/services/org.apache.phoenix.trace.PhoenixSpanReceiver b/phoenix-hadoop2-compat/src/main/resources/META-INF/services/org.apache.phoenix.trace.PhoenixSpanReceiver
deleted file mode 100644
index 3694093..0000000
--- a/phoenix-hadoop2-compat/src/main/resources/META-INF/services/org.apache.phoenix.trace.PhoenixSpanReceiver
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.phoenix.trace.TraceMetricSource
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop2-compat/src/main/resources/META-INF/services/org.apache.phoenix.trace.TestableMetricsWriter
----------------------------------------------------------------------
diff --git a/phoenix-hadoop2-compat/src/main/resources/META-INF/services/org.apache.phoenix.trace.TestableMetricsWriter b/phoenix-hadoop2-compat/src/main/resources/META-INF/services/org.apache.phoenix.trace.TestableMetricsWriter
deleted file mode 100644
index 7c9e107..0000000
--- a/phoenix-hadoop2-compat/src/main/resources/META-INF/services/org.apache.phoenix.trace.TestableMetricsWriter
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.phoenix.trace.PhoenixMetricsSink
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop2-compat/src/test/java/org/apache/hadoop/metrics2/impl/ExposedMetricCounterLong.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop2-compat/src/test/java/org/apache/hadoop/metrics2/impl/ExposedMetricCounterLong.java b/phoenix-hadoop2-compat/src/test/java/org/apache/hadoop/metrics2/impl/ExposedMetricCounterLong.java
deleted file mode 100644
index 33ca738..0000000
--- a/phoenix-hadoop2-compat/src/test/java/org/apache/hadoop/metrics2/impl/ExposedMetricCounterLong.java
+++ /dev/null
@@ -1,35 +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.metrics2.impl;
-
-import org.apache.hadoop.metrics2.MetricsInfo;
-import org.apache.hadoop.metrics2.impl.MetricCounterLong;
-
-/**
- *
- */
-public class ExposedMetricCounterLong extends MetricCounterLong {
-
-  /**
-   * @param info
-   * @param value
-   */
-  public ExposedMetricCounterLong(MetricsInfo info, long value) {
-    super(info, value);
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop2-compat/src/test/java/org/apache/hadoop/metrics2/impl/ExposedMetricsRecordImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop2-compat/src/test/java/org/apache/hadoop/metrics2/impl/ExposedMetricsRecordImpl.java b/phoenix-hadoop2-compat/src/test/java/org/apache/hadoop/metrics2/impl/ExposedMetricsRecordImpl.java
deleted file mode 100644
index bcb8b43..0000000
--- a/phoenix-hadoop2-compat/src/test/java/org/apache/hadoop/metrics2/impl/ExposedMetricsRecordImpl.java
+++ /dev/null
@@ -1,43 +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.metrics2.impl;
-
-import java.util.List;
-
-import org.apache.hadoop.metrics2.AbstractMetric;
-import org.apache.hadoop.metrics2.MetricsInfo;
-import org.apache.hadoop.metrics2.MetricsTag;
-import org.apache.hadoop.metrics2.impl.MetricsRecordImpl;
-
-/**
- * Helper class to access the package-private {@link MetricsRecordImpl}
- */
-@SuppressWarnings("javadoc")
-public class ExposedMetricsRecordImpl extends MetricsRecordImpl {
-
-  /**
-   * @param info
-   * @param timestamp
-   * @param tags
-   * @param metrics
-   */
-  public ExposedMetricsRecordImpl(MetricsInfo info, long timestamp, List<MetricsTag> tags,
-      Iterable<AbstractMetric> metrics) {
-    super(info, timestamp, tags, metrics);
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop2-compat/src/test/java/org/apache/hadoop/metrics2/lib/ExposedMetricsInfoImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop2-compat/src/test/java/org/apache/hadoop/metrics2/lib/ExposedMetricsInfoImpl.java b/phoenix-hadoop2-compat/src/test/java/org/apache/hadoop/metrics2/lib/ExposedMetricsInfoImpl.java
deleted file mode 100644
index 6daf604..0000000
--- a/phoenix-hadoop2-compat/src/test/java/org/apache/hadoop/metrics2/lib/ExposedMetricsInfoImpl.java
+++ /dev/null
@@ -1,32 +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.metrics2.lib;
-
-/**
- * Helper class to expose access to the {@link MetricsInfoImpl}
- */
-public class ExposedMetricsInfoImpl extends MetricsInfoImpl {
-
-    /**
-     * @param name
-     * @param description
-     */
-    public ExposedMetricsInfoImpl(String name, String description) {
-        super(name, description);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-hadoop2-compat/src/test/java/org/apache/phoenix/trace/PhoenixMetricsWriterTest.java
----------------------------------------------------------------------
diff --git a/phoenix-hadoop2-compat/src/test/java/org/apache/phoenix/trace/PhoenixMetricsWriterTest.java b/phoenix-hadoop2-compat/src/test/java/org/apache/phoenix/trace/PhoenixMetricsWriterTest.java
deleted file mode 100644
index f865723..0000000
--- a/phoenix-hadoop2-compat/src/test/java/org/apache/phoenix/trace/PhoenixMetricsWriterTest.java
+++ /dev/null
@@ -1,142 +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.phoenix.trace;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.List;
-
-import org.apache.hadoop.metrics2.AbstractMetric;
-import org.apache.hadoop.metrics2.MetricsInfo;
-import org.apache.hadoop.metrics2.MetricsRecord;
-import org.apache.hadoop.metrics2.MetricsTag;
-import org.apache.hadoop.metrics2.impl.ExposedMetricCounterLong;
-import org.apache.hadoop.metrics2.impl.ExposedMetricsRecordImpl;
-import org.apache.hadoop.metrics2.lib.ExposedMetricsInfoImpl;
-import org.apache.phoenix.metrics.MetricInfo;
-import org.apache.phoenix.metrics.MetricsWriter;
-import org.apache.phoenix.metrics.PhoenixAbstractMetric;
-import org.apache.phoenix.metrics.PhoenixMetricTag;
-import org.apache.phoenix.metrics.PhoenixMetricsRecord;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import com.google.common.collect.Lists;
-
-/**
- * Test that we correctly convert between hadoop2 metrics2 and generic phoenix metrics.
- */
-public class PhoenixMetricsWriterTest {
-
-  @Test
-  public void testTranslation() throws Exception {
-    // hook up a sink we can test
-    MetricsWriter mockSink = Mockito.mock(MetricsWriter.class);
-
-    // writer that will translate to the sink (specific to hadoop version used)
-    PhoenixMetricsSink writer = new PhoenixMetricsSink();
-    writer.setWriterForTesting(mockSink);
-
-    // create a simple metrics record
-    final long traceid = 987654;
-    MetricsInfo info = new ExposedMetricsInfoImpl(TracingCompat.getTraceMetricName(traceid),
-        "Some generic trace");
-    // setup some metrics for the span
-    long spanid = 10;
-    AbstractMetric span = new ExposedMetricCounterLong(new ExposedMetricsInfoImpl(
-        MetricInfo.SPAN.traceName, ""), spanid);
-    long parentid = 11;
-    AbstractMetric parent = new ExposedMetricCounterLong(new ExposedMetricsInfoImpl(
-        MetricInfo.PARENT.traceName, ""), parentid);
-    long startTime = 12;
-    AbstractMetric start = new ExposedMetricCounterLong(new ExposedMetricsInfoImpl(
-        MetricInfo.START.traceName, ""), startTime);
-    long endTime = 13;
-    AbstractMetric end = new ExposedMetricCounterLong(new ExposedMetricsInfoImpl(
-        MetricInfo.END.traceName, ""), endTime);
-    final List<AbstractMetric> metrics = Lists.newArrayList(span, parent, start, end);
-
-    // create an annotation as well
-    String annotation = "test annotation for a span";
-    MetricsTag tag = new MetricsTag(
-        new ExposedMetricsInfoImpl(MetricInfo.ANNOTATION.traceName, "0"), annotation);
-    String hostnameValue = "host-name.value";
-    MetricsTag hostname = new MetricsTag(new ExposedMetricsInfoImpl(MetricInfo.HOSTNAME.traceName,
-        ""), hostnameValue);
-    final List<MetricsTag> tags = Lists.newArrayList(hostname, tag);
-
-    MetricsRecord record = new ExposedMetricsRecordImpl(info, System.currentTimeMillis(), tags,
-        metrics);
-
-    // setup the mocking/validation for the sink
-    Mockito.doAnswer(new Answer<Void>() {
-
-      @Override
-      public Void answer(InvocationOnMock invocation) throws Throwable {
-        PhoenixMetricsRecord record = (PhoenixMetricsRecord) invocation.getArguments()[0];
-        //validate that we got the right fields in the record
-        assertEquals("phoenix.987654", record.name());
-        assertEquals("Some generic trace", record.description());
-        int count = 0;
-        for (PhoenixAbstractMetric metric : record.metrics()) {
-          count++;
-          //find the matching metric in the list
-          boolean found = false;
-          for(AbstractMetric expected : metrics){
-            if(expected.name().equals(metric.getName())){
-              found = true;
-              // make sure the rest of the info matches
-              assertEquals("Metric value mismatch", expected.value(), metric.value());
-            }
-          }
-          assertTrue("Didn't find an expected metric to match "+metric, found);
-        }
-        assertEquals("Number of metrics is received is wrong", metrics.size(), count);
-
-        count = 0;
-        for (PhoenixMetricTag tag : record.tags()) {
-          count++;
-          // find the matching metric in the list
-          boolean found = false;
-          for (MetricsTag expected : tags) {
-            if (expected.name().equals(tag.name())) {
-              found = true;
-              // make sure the rest of the info matches
-              assertEquals("Tag value mismatch", expected.value(), tag.value());
-              assertEquals("Tag description mismatch", expected.description(), tag.description());
-            }
-          }
-          assertTrue("Didn't find an expected metric to match " + tag, found);
-        }
-        assertEquals("Number of tags is received is wrong", tags.size(), count);
-        return null;
-      }
-
-    }).when(mockSink).addMetrics(Mockito.any(PhoenixMetricsRecord.class));
-
-    // actually do the update
-    writer.putMetrics(record);
-    writer.flush();
-
-    Mockito.verify(mockSink).addMetrics(Mockito.any(PhoenixMetricsRecord.class));
-    Mockito.verify(mockSink).flush();
-  }
-}
\ No newline at end of file


[3/3] git commit: PHOENIX-1286 Remove hadoop2 compat modules

Posted by jy...@apache.org.
PHOENIX-1286 Remove hadoop2 compat modules

There was some reflection and wrapping done in the metrics/tracing tools
to support working with Hadoop1/2 (though hadoop1 support was never completed).
Removing this extra code now that we don't want to support hadoop1 anymore


Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/842f8a8a
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/842f8a8a
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/842f8a8a

Branch: refs/heads/master
Commit: 842f8a8a8b84790ef11cf0dfd8f64b19de800bea
Parents: 4ed9ddb
Author: Jesse Yates <jy...@apache.org>
Authored: Mon Sep 22 15:00:00 2014 -0700
Committer: Jesse Yates <jy...@apache.org>
Committed: Mon Oct 27 13:54:58 2014 -0700

----------------------------------------------------------------------
 phoenix-assembly/pom.xml                        |  10 +-
 phoenix-core/pom.xml                            |  23 +-
 .../apache/phoenix/trace/BaseTracingTestIT.java | 112 ++++---
 .../phoenix/trace/DisableableMetricsWriter.java |  27 +-
 .../trace/Hadoop1TracingTestEnabler.java        |  84 ------
 .../apache/phoenix/trace/PhoenixMetricImpl.java |  44 ---
 .../phoenix/trace/PhoenixMetricRecordImpl.java  |  71 -----
 .../trace/PhoenixTableMetricsWriterIT.java      |  28 +-
 .../apache/phoenix/trace/PhoenixTagImpl.java    |  22 +-
 .../phoenix/trace/PhoenixTraceReaderIT.java     |  61 ++--
 .../phoenix/trace/PhoenixTracingEndToEndIT.java |  59 ++--
 .../apache/phoenix/trace/TracingTestUtil.java   |  14 +
 .../org/apache/phoenix/hbase/index/Indexer.java |   4 +-
 .../org/apache/phoenix/metrics/MetricInfo.java  |  51 ++++
 .../org/apache/phoenix/metrics/Metrics.java     |  66 ++++
 .../apache/phoenix/trace/MetricsInfoImpl.java   |  63 ++++
 .../phoenix/trace/PhoenixMetricsSink.java       | 298 +++++++++++++++++++
 .../trace/PhoenixTableMetricsWriter.java        | 278 -----------------
 .../apache/phoenix/trace/TraceMetricSource.java | 188 ++++++++++++
 .../org/apache/phoenix/trace/TraceReader.java   |  12 +-
 .../org/apache/phoenix/trace/TracingUtils.java  |  63 ++++
 .../org/apache/phoenix/trace/util/Tracing.java  |   5 +-
 .../metrics2/impl/ExposedMetricCounterLong.java |  36 +++
 .../metrics2/impl/ExposedMetricsRecordImpl.java |  42 +++
 .../metrics2/lib/ExposedMetricsInfoImpl.java    |  34 +++
 .../org/apache/phoenix/metrics/LoggingSink.java |  60 ++++
 .../phoenix/trace/TraceMetricsSourceTest.java   |  96 ++++++
 phoenix-hadoop-compat/pom.xml                   |  89 ------
 .../org/apache/phoenix/metrics/MetricInfo.java  |  51 ----
 .../org/apache/phoenix/metrics/Metrics.java     |  80 -----
 .../apache/phoenix/metrics/MetricsManager.java  |  58 ----
 .../apache/phoenix/metrics/MetricsWriter.java   |  31 --
 .../phoenix/metrics/PhoenixAbstractMetric.java  |  30 --
 .../phoenix/metrics/PhoenixMetricTag.java       |  27 --
 .../phoenix/metrics/PhoenixMetricsRecord.java   |  35 ---
 .../phoenix/trace/PhoenixSpanReceiver.java      |  26 --
 .../phoenix/trace/TestableMetricsWriter.java    |  30 --
 .../org/apache/phoenix/trace/TracingCompat.java |  89 ------
 .../org/apache/phoenix/metrics/LoggingSink.java |  56 ----
 .../phoenix/metrics/TracingTestCompat.java      |  45 ---
 phoenix-hadoop2-compat/pom.xml                  |  77 -----
 .../phoenix/metrics/MetricsManagerImpl.java     |  71 -----
 .../apache/phoenix/trace/MetricsInfoImpl.java   |  63 ----
 .../phoenix/trace/PhoenixMetricsSink.java       | 191 ------------
 .../apache/phoenix/trace/TraceMetricSource.java | 197 ------------
 .../org.apache.phoenix.metrics.MetricsManager   |   1 -
 ...org.apache.phoenix.trace.PhoenixSpanReceiver |   1 -
 ...g.apache.phoenix.trace.TestableMetricsWriter |   1 -
 .../metrics2/impl/ExposedMetricCounterLong.java |  35 ---
 .../metrics2/impl/ExposedMetricsRecordImpl.java |  43 ---
 .../metrics2/lib/ExposedMetricsInfoImpl.java    |  32 --
 .../phoenix/trace/PhoenixMetricsWriterTest.java | 142 ---------
 .../phoenix/trace/TraceMetricsSourceTest.java   |  96 ------
 .../org/apache/phoenix/trace/TracingTest.java   |  34 ---
 pom.xml                                         |  27 --
 55 files changed, 1156 insertions(+), 2353 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-assembly/pom.xml
----------------------------------------------------------------------
diff --git a/phoenix-assembly/pom.xml b/phoenix-assembly/pom.xml
index ea2bdb1..6c29f32 100644
--- a/phoenix-assembly/pom.xml
+++ b/phoenix-assembly/pom.xml
@@ -138,14 +138,6 @@
     </dependency>
     <dependency>
       <groupId>org.apache.phoenix</groupId>
-      <artifactId>phoenix-hadoop-compat</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.phoenix</groupId>
-      <artifactId>phoenix-hadoop2-compat</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.phoenix</groupId>
       <artifactId>phoenix-flume</artifactId>
     </dependency>
         <dependency>
@@ -153,4 +145,4 @@
       <artifactId>phoenix-pig</artifactId>
     </dependency>
   </dependencies>
-</project>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/pom.xml
----------------------------------------------------------------------
diff --git a/phoenix-core/pom.xml b/phoenix-core/pom.xml
index bbd262b..90a7142 100644
--- a/phoenix-core/pom.xml
+++ b/phoenix-core/pom.xml
@@ -205,17 +205,6 @@
   </build>
 
   <dependencies>
-    <!-- Intra project dependencies -->
-    <dependency>
-      <groupId>org.apache.phoenix</groupId>
-      <artifactId>phoenix-hadoop-compat</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.phoenix</groupId>
-      <artifactId>phoenix-hadoop-compat</artifactId>
-      <classifier>tests</classifier>
-      <scope>test</scope>
-    </dependency>
     <!-- Make sure we have all the antlr dependencies -->
     <dependency>
       <groupId>org.antlr</groupId>
@@ -409,15 +398,5 @@
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-minicluster</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.apache.phoenix</groupId>
-      <artifactId>phoenix-hadoop2-compat</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.phoenix</groupId>
-      <artifactId>phoenix-hadoop2-compat</artifactId>
-      <classifier>tests</classifier>
-      <scope>test</scope>
-    </dependency>
   </dependencies>
-</project>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/it/java/org/apache/phoenix/trace/BaseTracingTestIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/trace/BaseTracingTestIT.java b/phoenix-core/src/it/java/org/apache/phoenix/trace/BaseTracingTestIT.java
index 0f8a666..f504d12 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/trace/BaseTracingTestIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/trace/BaseTracingTestIT.java
@@ -17,25 +17,18 @@
  */
 package org.apache.phoenix.trace;
 
-import static org.apache.phoenix.util.PhoenixRuntime.ANNOTATION_ATTRIB_PREFIX;
-import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Properties;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.metrics2.AbstractMetric;
+import org.apache.hadoop.metrics2.MetricsInfo;
+import org.apache.hadoop.metrics2.MetricsRecord;
+import org.apache.hadoop.metrics2.MetricsTag;
+import org.apache.hadoop.metrics2.impl.ExposedMetricCounterLong;
+import org.apache.hadoop.metrics2.impl.ExposedMetricsRecordImpl;
+import org.apache.hadoop.metrics2.lib.ExposedMetricsInfoImpl;
 import org.apache.phoenix.end2end.BaseHBaseManagedTimeIT;
 import org.apache.phoenix.end2end.HBaseManagedTimeTest;
 import org.apache.phoenix.metrics.MetricInfo;
-import org.apache.phoenix.metrics.Metrics;
-import org.apache.phoenix.metrics.PhoenixAbstractMetric;
-import org.apache.phoenix.metrics.PhoenixMetricTag;
-import org.apache.phoenix.metrics.PhoenixMetricsRecord;
 import org.apache.phoenix.query.QueryServicesOptions;
 import org.apache.phoenix.schema.TableNotFoundException;
 import org.apache.phoenix.trace.util.Tracing;
@@ -45,6 +38,14 @@ import org.apache.phoenix.util.PropertiesUtil;
 import org.junit.Before;
 import org.junit.experimental.categories.Category;
 
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.*;
+
+import static org.apache.phoenix.util.PhoenixRuntime.ANNOTATION_ATTRIB_PREFIX;
+import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
+
 /**
  * Base test for tracing tests - helps manage getting tracing/non-tracing
  * connections, as well as any supporting utils.
@@ -53,36 +54,17 @@ import org.junit.experimental.categories.Category;
 public class BaseTracingTestIT extends BaseHBaseManagedTimeIT {
     private static final Log LOG = LogFactory.getLog(BaseTracingTestIT.class);
 
-    /**
-     * Hadoop1 doesn't yet support tracing (need metrics library support) so we just skip those
-     * tests for the moment
-     * @return <tt>true</tt> if the test should exit because some necessary classes are missing, or
-     *         <tt>false</tt> if the tests can continue normally
-     */
-    static boolean shouldEarlyExitForHadoop1Test() {
-        try {
-            // get a receiver for the spans
-            TracingCompat.newTraceMetricSource();
-            // which also needs to a source for the metrics system
-            Metrics.getManager();
-            return false;
-        } catch (RuntimeException e) {
-            LOG.error("Shouldn't run test because can't instantiate necessary metrics/tracing classes!");
-        }
-
-        return true;
-    }
-
     @Before
     public void resetTracingTableIfExists() throws Exception {
         Connection conn = getConnectionWithoutTracing();
         conn.setAutoCommit(true);
         try {
-            conn.createStatement().executeUpdate("DELETE FROM " + QueryServicesOptions.DEFAULT_TRACING_STATS_TABLE_NAME);
+            conn.createStatement().executeUpdate(
+                    "DELETE FROM " + QueryServicesOptions.DEFAULT_TRACING_STATS_TABLE_NAME);
         } catch (TableNotFoundException ignore) {
         }
     }
-    
+
     public static Connection getConnectionWithoutTracing() throws SQLException {
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         return getConnectionWithoutTracing(props);
@@ -93,18 +75,19 @@ public class BaseTracingTestIT extends BaseHBaseManagedTimeIT {
         conn.setAutoCommit(false);
         return conn;
     }
-    
-    public static Connection getTracingConnection() throws Exception { 
-    	return getTracingConnection(Collections.<String, String>emptyMap(), null);
+
+    public static Connection getTracingConnection() throws Exception {
+        return getTracingConnection(Collections.<String, String>emptyMap(), null);
     }
 
-    public static Connection getTracingConnection(Map<String, String> customAnnotations, String tenantId) throws Exception {
+    public static Connection getTracingConnection(Map<String, String> customAnnotations,
+            String tenantId) throws Exception {
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         for (Map.Entry<String, String> annot : customAnnotations.entrySet()) {
-        	props.put(ANNOTATION_ATTRIB_PREFIX + annot.getKey(), annot.getValue());
+            props.put(ANNOTATION_ATTRIB_PREFIX + annot.getKey(), annot.getValue());
         }
         if (tenantId != null) {
-        	props.put(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId);
+            props.put(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId);
         }
         return getConnectionWithTracingFrequency(props, Tracing.Frequency.ALWAYS);
     }
@@ -115,34 +98,49 @@ public class BaseTracingTestIT extends BaseHBaseManagedTimeIT {
         return DriverManager.getConnection(getUrl(), props);
     }
 
-    public static PhoenixMetricsRecord createRecord(long traceid, long parentid, long spanid,
+    public static MetricsRecord createRecord(long traceid, long parentid, long spanid,
             String desc, long startTime, long endTime, String hostname, String... tags) {
-        PhoenixMetricRecordImpl record =
-                new PhoenixMetricRecordImpl(TracingCompat.getTraceMetricName(traceid), desc);
-        PhoenixAbstractMetric span = new PhoenixMetricImpl(MetricInfo.SPAN.traceName, spanid);
-        record.addMetric(span);
 
-        PhoenixAbstractMetric parent = new PhoenixMetricImpl(MetricInfo.PARENT.traceName, parentid);
-        record.addMetric(parent);
+        List<AbstractMetric> metrics = new ArrayList<AbstractMetric>();
+        AbstractMetric span = new ExposedMetricCounterLong(asInfo(MetricInfo
+                .SPAN.traceName),
+                spanid);
+        metrics.add(span);
 
-        PhoenixAbstractMetric start = new PhoenixMetricImpl(MetricInfo.START.traceName, startTime);
-        record.addMetric(start);
+        AbstractMetric parent = new ExposedMetricCounterLong(asInfo(MetricInfo.PARENT.traceName),
+                parentid);
+        metrics.add(parent);
 
-        PhoenixAbstractMetric end = new PhoenixMetricImpl(MetricInfo.END.traceName, endTime);
-        record.addMetric(end);
+        AbstractMetric start = new ExposedMetricCounterLong(asInfo(MetricInfo.START.traceName),
+                startTime);
+        metrics.add(start);
 
+        AbstractMetric
+                end =
+                new ExposedMetricCounterLong(asInfo(MetricInfo.END.traceName), endTime);
+        metrics.add(end);
+
+        List<MetricsTag> tagsList = new ArrayList<MetricsTag>();
         int tagCount = 0;
         for (String annotation : tags) {
-            PhoenixMetricTag tag =
+            MetricsTag tag =
                     new PhoenixTagImpl(MetricInfo.ANNOTATION.traceName,
                             Integer.toString(tagCount++), annotation);
-            record.addTag(tag);
+            tagsList.add(tag);
         }
         String hostnameValue = "host-name.value";
-        PhoenixMetricTag hostnameTag =
+        MetricsTag hostnameTag =
                 new PhoenixTagImpl(MetricInfo.HOSTNAME.traceName, "", hostnameValue);
-        record.addTag(hostnameTag);
+        tagsList.add(hostnameTag);
 
+        MetricsRecord record =
+                new ExposedMetricsRecordImpl(new ExposedMetricsInfoImpl(TracingUtils
+                        .getTraceMetricName(traceid), desc), System.currentTimeMillis(),
+                        tagsList, metrics);
         return record;
     }
+
+    private static MetricsInfo asInfo(String name) {
+        return new ExposedMetricsInfoImpl(name, "");
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/it/java/org/apache/phoenix/trace/DisableableMetricsWriter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/trace/DisableableMetricsWriter.java b/phoenix-core/src/it/java/org/apache/phoenix/trace/DisableableMetricsWriter.java
index a054bf2..875717c 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/trace/DisableableMetricsWriter.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/trace/DisableableMetricsWriter.java
@@ -17,31 +17,32 @@
  */
 package org.apache.phoenix.trace;
 
-import java.sql.SQLException;
-import java.util.concurrent.atomic.AtomicBoolean;
-
+import org.apache.commons.configuration.SubsetConfiguration;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.phoenix.metrics.MetricsWriter;
-import org.apache.phoenix.metrics.PhoenixMetricsRecord;
+import org.apache.hadoop.metrics2.MetricsRecord;
+import org.apache.hadoop.metrics2.MetricsSink;
+
+import java.sql.SQLException;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  *
  */
-public class DisableableMetricsWriter implements MetricsWriter {
+public class DisableableMetricsWriter implements MetricsSink {
 
     private static final Log LOG = LogFactory.getLog(DisableableMetricsWriter.class);
-    private PhoenixTableMetricsWriter writer;
+    private PhoenixMetricsSink writer;
     private AtomicBoolean disabled = new AtomicBoolean(false);
 
-    public DisableableMetricsWriter(PhoenixTableMetricsWriter writer) {
+    public DisableableMetricsWriter(PhoenixMetricsSink writer) {
         this.writer = writer;
     }
 
     @Override
-    public void initialize() {
+    public void init(SubsetConfiguration config) {
         if (this.disabled.get()) return;
-        writer.initialize();
+        writer.init(config);
     }
 
     @Override
@@ -55,9 +56,9 @@ public class DisableableMetricsWriter implements MetricsWriter {
     }
 
     @Override
-    public void addMetrics(PhoenixMetricsRecord record) {
+    public void putMetrics(MetricsRecord record) {
         if (this.disabled.get()) return;
-        writer.addMetrics(record);
+        writer.putMetrics(record);
     }
 
     public void disable() {
@@ -77,7 +78,7 @@ public class DisableableMetricsWriter implements MetricsWriter {
         }
     }
 
-    public PhoenixTableMetricsWriter getDelegate() {
+    public PhoenixMetricsSink getDelegate() {
         return this.writer;
     }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/it/java/org/apache/phoenix/trace/Hadoop1TracingTestEnabler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/trace/Hadoop1TracingTestEnabler.java b/phoenix-core/src/it/java/org/apache/phoenix/trace/Hadoop1TracingTestEnabler.java
deleted file mode 100644
index 9a592d3..0000000
--- a/phoenix-core/src/it/java/org/apache/phoenix/trace/Hadoop1TracingTestEnabler.java
+++ /dev/null
@@ -1,84 +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.phoenix.trace;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import org.junit.runner.notification.RunNotifier;
-import org.junit.runners.BlockJUnit4ClassRunner;
-import org.junit.runners.model.FrameworkMethod;
-import org.junit.runners.model.InitializationError;
-
-/**
- * Test runner to run classes that depend on Hadoop1 compatibility that may not be present for the
- * feature
- */
-public class Hadoop1TracingTestEnabler extends BlockJUnit4ClassRunner {
-
-    public Hadoop1TracingTestEnabler(Class<?> klass) throws InitializationError {
-        super(klass);
-    }
-
-    @Override
-    public void runChild(FrameworkMethod method, RunNotifier notifier) {
-        // if the class is already disabled, then we can disable on the class level, otherwise we
-        // just check the per-method
-        Hadoop1Disabled condition =
-                getTestClass().getJavaClass().getAnnotation(Hadoop1Disabled.class);
-        if (condition == null) {
-            condition = method
-                        .getAnnotation(Hadoop1Disabled.class);
-        }
-
-        // if this has the flag, then we want to disable it if hadoop1 is not enabled for that
-        // feature
-        if (condition != null && getEnabled(condition.value())) {
-            super.runChild(method, notifier);
-        } else {
-            notifier.fireTestIgnored(describeChild(method));
-        }
-    }
-
-    /**
-     * Simple check that just uses if-else logic. We can move to something more complex, policy
-     * based later when this gets more complex.
-     * @param feature name of the feature to check
-     * @return <tt>true</tt> if the test method is enabled for the given feature, <tt>false</tt>
-     *         otherwise
-     */
-    private boolean getEnabled(String feature) {
-        if (feature.equals("tracing")) {
-            return !BaseTracingTestIT.shouldEarlyExitForHadoop1Test();
-        }
-        return true;
-    }
-
-    /**
-     * Marker that a class/method should be disabled if hadoop1 features are not enabled. It takes a
-     * value for the Hadoop1 feature on which this class/method depends, for instance "tracing" is
-     * not supported in Hadoop1 (yet).
-     */
-    @Target({ ElementType.TYPE, ElementType.METHOD })
-    @Retention(RetentionPolicy.RUNTIME)
-    public static @interface Hadoop1Disabled {
-        String value();
-    }
-}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixMetricImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixMetricImpl.java b/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixMetricImpl.java
deleted file mode 100644
index 985504f..0000000
--- a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixMetricImpl.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.phoenix.trace;
-
-import org.apache.phoenix.metrics.PhoenixAbstractMetric;
-
-/**
- * Simple metric implementation for testing
- */
-public class PhoenixMetricImpl implements PhoenixAbstractMetric {
-
-    private String name;
-    private Number value;
-
-    public PhoenixMetricImpl(String name, Number value) {
-        this.name = name;
-        this.value = value;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public Number value() {
-        return value;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixMetricRecordImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixMetricRecordImpl.java b/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixMetricRecordImpl.java
deleted file mode 100644
index 45cabf0..0000000
--- a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixMetricRecordImpl.java
+++ /dev/null
@@ -1,71 +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.phoenix.trace;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.phoenix.metrics.PhoenixAbstractMetric;
-import org.apache.phoenix.metrics.PhoenixMetricTag;
-import org.apache.phoenix.metrics.PhoenixMetricsRecord;
-
-import com.google.common.collect.Lists;
-
-/**
- *
- */
-public class PhoenixMetricRecordImpl implements PhoenixMetricsRecord {
-
-    private String name;
-    private String description;
-    private final List<PhoenixAbstractMetric> metrics = Lists.newArrayList();
-    private final List<PhoenixMetricTag> tags = Lists.newArrayList();
-
-    public PhoenixMetricRecordImpl(String name, String description) {
-        this.name = name;
-        this.description = description;
-    }
-
-    public void addMetric(PhoenixAbstractMetric metric) {
-        this.metrics.add(metric);
-    }
-
-    public void addTag(PhoenixMetricTag tag) {
-        this.tags.add(tag);
-    }
-
-    @Override
-    public String name() {
-        return this.name;
-    }
-
-    @Override
-    public String description() {
-        return this.description;
-    }
-
-    @Override
-    public Iterable<PhoenixAbstractMetric> metrics() {
-        return metrics;
-    }
-
-    @Override
-    public Collection<PhoenixMetricTag> tags() {
-        return tags;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTableMetricsWriterIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTableMetricsWriterIT.java b/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTableMetricsWriterIT.java
index ecac21b..533b6f8 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTableMetricsWriterIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTableMetricsWriterIT.java
@@ -17,25 +17,21 @@
  */
 package org.apache.phoenix.trace;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import java.sql.Connection;
-import java.util.Collection;
-
-import org.apache.phoenix.metrics.PhoenixMetricsRecord;
+import org.apache.hadoop.metrics2.MetricsRecord;
 import org.apache.phoenix.query.QueryServicesOptions;
-import org.apache.phoenix.trace.Hadoop1TracingTestEnabler.Hadoop1Disabled;
 import org.apache.phoenix.trace.TraceReader.SpanInfo;
 import org.apache.phoenix.trace.TraceReader.TraceHolder;
 import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import java.sql.Connection;
+import java.util.Collection;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 
 /**
  * Test that the logging sink stores the expected metrics/stats
  */
-@RunWith(Hadoop1TracingTestEnabler.class)
-@Hadoop1Disabled("tracing")
 public class PhoenixTableMetricsWriterIT extends BaseTracingTestIT {
 
     /**
@@ -45,7 +41,7 @@ public class PhoenixTableMetricsWriterIT extends BaseTracingTestIT {
      */
     @Test
     public void testCreatesTable() throws Exception {
-        PhoenixTableMetricsWriter sink = new PhoenixTableMetricsWriter();
+        PhoenixMetricsSink sink = new PhoenixMetricsSink();
         Connection conn = getConnectionWithoutTracing();
         sink.initForTesting(conn);
 
@@ -69,13 +65,13 @@ public class PhoenixTableMetricsWriterIT extends BaseTracingTestIT {
 
     /**
      * Simple metrics writing and reading check, that uses the standard wrapping in the
-     * {@link PhoenixMetricsWriter}
+     * {@link PhoenixMetricsSink}
      * @throws Exception on failure
      */
     @Test
     public void writeMetrics() throws Exception {
         // hook up a phoenix sink
-        PhoenixTableMetricsWriter sink = new PhoenixTableMetricsWriter();
+        PhoenixMetricsSink sink = new PhoenixMetricsSink();
         Connection conn = getConnectionWithoutTracing();
         sink.initForTesting(conn);
 
@@ -88,12 +84,12 @@ public class PhoenixTableMetricsWriterIT extends BaseTracingTestIT {
         long endTime = 13;
         String annotation = "test annotation for a span";
         String hostnameValue = "host-name.value";
-        PhoenixMetricsRecord record =
+       MetricsRecord record =
                 createRecord(traceid, parentid, spanid, description, startTime, endTime,
                     hostnameValue, annotation);
 
         // actually write the record to the table
-        sink.addMetrics(record);
+        sink.putMetrics(record);
         sink.flush();
 
         // make sure we only get expected stat entry (matcing the trace id), otherwise we could the

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTagImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTagImpl.java b/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTagImpl.java
index c8e2219..a911a2c 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTagImpl.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTagImpl.java
@@ -17,36 +17,22 @@
  */
 package org.apache.phoenix.trace;
 
-import org.apache.phoenix.metrics.PhoenixMetricTag;
+import org.apache.hadoop.metrics2.MetricsInfo;
+import org.apache.hadoop.metrics2.MetricsTag;
 
 /**
  * Simple Tag implementation for testing
  */
-public class PhoenixTagImpl implements PhoenixMetricTag {
+public class PhoenixTagImpl extends MetricsTag {
 
     private final String name;
     private final String description;
     private final String value;
 
     public PhoenixTagImpl(String name, String description, String value) {
-        super();
+        super(new MetricsInfoImpl(name, description), value);
         this.name = name;
         this.description = description;
         this.value = value;
     }
-
-    @Override
-    public String name() {
-        return name;
-    }
-
-    @Override
-    public String description() {
-        return description;
-    }
-
-    @Override
-    public String value() {
-        return value;
-    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTraceReaderIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTraceReaderIT.java b/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTraceReaderIT.java
index f0a47bb..d75e281 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTraceReaderIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTraceReaderIT.java
@@ -17,40 +17,31 @@
  */
 package org.apache.phoenix.trace;
 
-import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Properties;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.metrics2.AbstractMetric;
+import org.apache.hadoop.metrics2.MetricsRecord;
+import org.apache.hadoop.metrics2.MetricsTag;
 import org.apache.phoenix.end2end.HBaseManagedTimeTest;
 import org.apache.phoenix.metrics.MetricInfo;
-import org.apache.phoenix.metrics.PhoenixAbstractMetric;
-import org.apache.phoenix.metrics.PhoenixMetricTag;
-import org.apache.phoenix.metrics.PhoenixMetricsRecord;
-import org.apache.phoenix.trace.Hadoop1TracingTestEnabler.Hadoop1Disabled;
 import org.apache.phoenix.trace.TraceReader.SpanInfo;
 import org.apache.phoenix.trace.TraceReader.TraceHolder;
 import org.cloudera.htrace.Span;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.util.*;
+
+import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 
 /**
  * Test that the {@link TraceReader} will correctly read traces written by the
- * {@link PhoenixTableMetricsWriter}
+ * {@link org.apache.phoenix.trace.PhoenixMetricsSink}
  */
-@RunWith(Hadoop1TracingTestEnabler.class)
-@Hadoop1Disabled("tracing")
 @Category(HBaseManagedTimeTest.class)
 public class PhoenixTraceReaderIT extends BaseTracingTestIT {
 
@@ -58,14 +49,14 @@ public class PhoenixTraceReaderIT extends BaseTracingTestIT {
 
     @Test
     public void singleSpan() throws Exception {
-        PhoenixTableMetricsWriter sink = new PhoenixTableMetricsWriter();
+        PhoenixMetricsSink sink = new PhoenixMetricsSink();
         Properties props = new Properties(TEST_PROPERTIES);
         Connection conn = DriverManager.getConnection(getUrl(), props);
         sink.initForTesting(conn);
 
         // create a simple metrics record
         long traceid = 987654;
-        PhoenixMetricsRecord record =
+        MetricsRecord record =
                 createAndFlush(sink, traceid, Span.ROOT_SPAN_ID, 10, "root", 12, 13,
                     "host-name.value", "test annotation for a span");
 
@@ -73,12 +64,12 @@ public class PhoenixTraceReaderIT extends BaseTracingTestIT {
         validateTraces(Collections.singletonList(record), conn, traceid);
     }
 
-    private PhoenixMetricsRecord createAndFlush(PhoenixTableMetricsWriter sink, long traceid,
+    private MetricsRecord createAndFlush(PhoenixMetricsSink sink, long traceid,
             long parentid, long spanid, String desc, long startTime, long endTime, String hostname,
             String... tags) {
-        PhoenixMetricsRecord record =
+        MetricsRecord record =
                 createRecord(traceid, parentid, spanid, desc, startTime, endTime, hostname, tags);
-        sink.addMetrics(record);
+        sink.putMetrics(record);
         sink.flush();
         return record;
     }
@@ -91,14 +82,14 @@ public class PhoenixTraceReaderIT extends BaseTracingTestIT {
     @Test
     public void testMultipleSpans() throws Exception {
         // hook up a phoenix sink
-        PhoenixTableMetricsWriter sink = new PhoenixTableMetricsWriter();
+        PhoenixMetricsSink sink = new PhoenixMetricsSink();
         Connection conn = getConnectionWithoutTracing();
         sink.initForTesting(conn);
 
         // create a simple metrics record
         long traceid = 12345;
-        List<PhoenixMetricsRecord> records = new ArrayList<PhoenixMetricsRecord>();
-        PhoenixMetricsRecord record =
+        List<MetricsRecord> records = new ArrayList<MetricsRecord>();
+        MetricsRecord record =
                 createAndFlush(sink, traceid, Span.ROOT_SPAN_ID, 7777, "root", 10, 30,
                     "hostname.value", "root-span tag");
         records.add(record);
@@ -128,7 +119,7 @@ public class PhoenixTraceReaderIT extends BaseTracingTestIT {
         validateTraces(records, conn, traceid);
     }
 
-    private void validateTraces(List<PhoenixMetricsRecord> records, Connection conn, long traceid)
+    private void validateTraces(List<MetricsRecord> records, Connection conn, long traceid)
             throws Exception {
         TraceReader reader = new TraceReader(conn);
         Collection<TraceHolder> traces = reader.readAll(1);
@@ -145,13 +136,13 @@ public class PhoenixTraceReaderIT extends BaseTracingTestIT {
      * @param records
      * @param trace
      */
-    private void validateTrace(List<PhoenixMetricsRecord> records, TraceHolder trace) {
+    private void validateTrace(List<MetricsRecord> records, TraceHolder trace) {
         // drop each span into a sorted list so we get the expected ordering
         Iterator<SpanInfo> spanIter = trace.spans.iterator();
-        for (PhoenixMetricsRecord record : records) {
+        for (MetricsRecord record : records) {
             SpanInfo spanInfo = spanIter.next();
             LOG.info("Checking span:\n" + spanInfo);
-            Iterator<PhoenixAbstractMetric> metricIter = record.metrics().iterator();
+            Iterator<AbstractMetric> metricIter = record.metrics().iterator();
             assertEquals("Got an unexpected span id", metricIter.next().value(), spanInfo.id);
             long parentId = (Long) metricIter.next().value();
             if (parentId == Span.ROOT_SPAN_ID) {
@@ -162,12 +153,12 @@ public class PhoenixTraceReaderIT extends BaseTracingTestIT {
             assertEquals("Got an unexpected start time", metricIter.next().value(), spanInfo.start);
             assertEquals("Got an unexpected end time", metricIter.next().value(), spanInfo.end);
 
-            Iterator<PhoenixMetricTag> tags = record.tags().iterator();
+            Iterator<MetricsTag> tags = record.tags().iterator();
 
             int annotationCount = 0;
             while (tags.hasNext()) {
                 // hostname is a tag, so we differentiate it
-                PhoenixMetricTag tag = tags.next();
+                MetricsTag tag = tags.next();
                 if (tag.name().equals(MetricInfo.HOSTNAME.traceName)) {
                     assertEquals("Didn't store correct hostname value", tag.value(),
                         spanInfo.hostname);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTracingEndToEndIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTracingEndToEndIT.java b/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTracingEndToEndIT.java
index 87d80da..f4cf0d1 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTracingEndToEndIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTracingEndToEndIT.java
@@ -17,46 +17,37 @@
  */
 package org.apache.phoenix.trace;
 
-import static org.apache.phoenix.util.PhoenixRuntime.TENANT_ID_ATTRIB;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Collection;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
+import com.google.common.collect.ImmutableMap;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.metrics2.MetricsSource;
 import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
 import org.apache.phoenix.end2end.HBaseManagedTimeTest;
 import org.apache.phoenix.metrics.Metrics;
-import org.apache.phoenix.metrics.TracingTestCompat;
 import org.apache.phoenix.query.QueryServicesOptions;
-import org.apache.phoenix.trace.Hadoop1TracingTestEnabler.Hadoop1Disabled;
 import org.apache.phoenix.trace.TraceReader.SpanInfo;
 import org.apache.phoenix.trace.TraceReader.TraceHolder;
-import org.cloudera.htrace.Sampler;
-import org.cloudera.htrace.Span;
-import org.cloudera.htrace.SpanReceiver;
-import org.cloudera.htrace.Trace;
-import org.cloudera.htrace.TraceScope;
+import org.cloudera.htrace.*;
 import org.junit.After;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
 
-import com.google.common.collect.ImmutableMap;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import static org.apache.phoenix.util.PhoenixRuntime.TENANT_ID_ATTRIB;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Test that the logging sink stores the expected metrics/stats
  */
-@RunWith(Hadoop1TracingTestEnabler.class)
-@Hadoop1Disabled("tracing")
 @Category(HBaseManagedTimeTest.class)
 public class PhoenixTracingEndToEndIT extends BaseTracingTestIT {
 
@@ -69,15 +60,12 @@ public class PhoenixTracingEndToEndIT extends BaseTracingTestIT {
 
     @BeforeClass
     public static void setupMetrics() throws Exception {
-        if (shouldEarlyExitForHadoop1Test()) {
-            return;
-        }
-        PhoenixTableMetricsWriter pWriter = new PhoenixTableMetricsWriter();
+        PhoenixMetricsSink pWriter = new PhoenixMetricsSink();
         Connection conn = getConnectionWithoutTracing();
         pWriter.initForTesting(conn);
         sink = new DisableableMetricsWriter(pWriter);
 
-        TracingTestCompat.registerSink(sink);
+        TracingTestUtil.registerSink(sink);
     }
 
     @After
@@ -112,10 +100,10 @@ public class PhoenixTracingEndToEndIT extends BaseTracingTestIT {
     @Test
     public void testWriteSpans() throws Exception {
         // get a receiver for the spans
-        SpanReceiver receiver = TracingCompat.newTraceMetricSource();
+        SpanReceiver receiver = new TraceMetricSource();
         // which also needs to a source for the metrics system
-        Metrics.getManager().registerSource("testWriteSpans-source", "source for testWriteSpans",
-            receiver);
+        Metrics.initialize().register("testWriteSpans-source", "source for testWriteSpans",
+                (MetricsSource) receiver);
 
         // watch our sink so we know when commits happen
         CountDownLatch latch = new CountDownLatch(1);
@@ -128,7 +116,7 @@ public class PhoenixTracingEndToEndIT extends BaseTracingTestIT {
         // add a child with some annotations
         Span child = span.child("child 1");
         child.addTimelineAnnotation("timeline annotation");
-        TracingCompat.addAnnotation(child, "test annotation", 10);
+        TracingUtils.addAnnotation(child, "test annotation", 10);
         child.stop();
 
         // sleep a little bit to get some time difference
@@ -230,10 +218,7 @@ public class PhoenixTracingEndToEndIT extends BaseTracingTestIT {
                 if (traceInfo.contains(QueryServicesOptions.DEFAULT_TRACING_STATS_TABLE_NAME)) {
                     return false;
                 }
-                if (traceInfo.contains("Completing index")) {
-                    return true;
-                }
-                return false;
+                return traceInfo.contains("Completing index");
             }
         });
 
@@ -467,4 +452,4 @@ public class PhoenixTracingEndToEndIT extends BaseTracingTestIT {
         }
 
     }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/it/java/org/apache/phoenix/trace/TracingTestUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/trace/TracingTestUtil.java b/phoenix-core/src/it/java/org/apache/phoenix/trace/TracingTestUtil.java
new file mode 100644
index 0000000..d502175
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/trace/TracingTestUtil.java
@@ -0,0 +1,14 @@
+package org.apache.phoenix.trace;
+
+import org.apache.hadoop.metrics2.MetricsSink;
+import org.apache.phoenix.metrics.Metrics;
+
+/**
+ *
+ */
+public class TracingTestUtil {
+
+    public static void registerSink(MetricsSink sink){
+        Metrics.initialize().register("phoenix", "test sink gets logged", sink);
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/Indexer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/Indexer.java b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/Indexer.java
index d55dfbf..9c48a8d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/Indexer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/Indexer.java
@@ -64,7 +64,7 @@ import org.apache.phoenix.hbase.index.write.IndexWriter;
 import org.apache.phoenix.hbase.index.write.recovery.PerRegionIndexWriteCache;
 import org.apache.phoenix.hbase.index.write.recovery.StoreFailuresInCachePolicy;
 import org.apache.phoenix.hbase.index.write.recovery.TrackingParallelWriterIndexCommitter;
-import org.apache.phoenix.trace.TracingCompat;
+import org.apache.phoenix.trace.TracingUtils;
 import org.apache.phoenix.trace.util.NullSpan;
 import org.cloudera.htrace.Span;
 import org.cloudera.htrace.Trace;
@@ -276,7 +276,7 @@ public class Indexer extends BaseRegionObserver {
         this.builder.getIndexUpdate(miniBatchOp, mutations.values());
 
         current.addTimelineAnnotation("Built index updates, doing preStep");
-        TracingCompat.addAnnotation(current, "index update count", indexUpdates.size());
+        TracingUtils.addAnnotation(current, "index update count", indexUpdates.size());
 
     // write them, either to WAL or the index tables
     doPre(indexUpdates, edit, durability);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/main/java/org/apache/phoenix/metrics/MetricInfo.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/metrics/MetricInfo.java b/phoenix-core/src/main/java/org/apache/phoenix/metrics/MetricInfo.java
new file mode 100644
index 0000000..e6ad976
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/metrics/MetricInfo.java
@@ -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.phoenix.metrics;
+
+/**
+ * Metrics and their conversion from the trace name to the name we store in the stats table
+ */
+public enum MetricInfo {
+
+    TRACE("", "trace_id"),
+    SPAN("span_id", "span_id"),
+    PARENT("parent_id", "parent_id"),
+    START("start_time", "start_time"),
+    END("end_time", "end_time"),
+    TAG("phoenix.tag", "t"),
+    ANNOTATION("phoenix.annotation", "a"),
+    HOSTNAME("Hostname", "hostname"),
+    DESCRIPTION("", "description");
+
+    public final String traceName;
+    public final String columnName;
+
+    private MetricInfo(String traceName, String columnName) {
+        this.traceName = traceName;
+        this.columnName = columnName;
+    }
+
+    public static String getColumnName(String traceName) {
+        for (MetricInfo info : MetricInfo.values()) {
+            if (info.traceName.equals(traceName)) {
+                return info.columnName;
+            }
+        }
+        throw new IllegalArgumentException("Unknown tracename: " + traceName);
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/main/java/org/apache/phoenix/metrics/Metrics.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/metrics/Metrics.java b/phoenix-core/src/main/java/org/apache/phoenix/metrics/Metrics.java
new file mode 100644
index 0000000..24950c4
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/metrics/Metrics.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.phoenix.metrics;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.metrics2.MetricsSystem;
+import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
+
+public class Metrics {
+
+    private static final Log LOG = LogFactory.getLog(Metrics.class);
+
+  private static volatile MetricsSystem manager = DefaultMetricsSystem.instance();
+
+    private static boolean initialized;
+
+    /** This must match the prefix that we are using in the hadoop-metrics2 config on the client */
+    public static final String METRICS_SYSTEM_NAME = "phoenix";
+    public static MetricsSystem initialize() {
+        // if the jars aren't on the classpath, then we don't start the metrics system
+        if (manager == null) {
+            LOG.warn("Phoenix metrics could not be initialized - no MetricsManager found!");
+            return null;
+        }
+        // only initialize the metrics system once
+        synchronized (Metrics.class) {
+            if (!initialized) {
+                LOG.info("Initializing metrics system: " + Metrics.METRICS_SYSTEM_NAME);
+                manager.init(Metrics.METRICS_SYSTEM_NAME);
+                initialized = true;
+            }
+        }
+        return manager;
+    }
+
+    private static volatile boolean sinkInitialized = false;
+
+    /**
+     * Mark that the metrics/tracing sink has been initialized
+     */
+    public static void markSinkInitialized() {
+        sinkInitialized = true;
+    }
+
+    public static void ensureConfigured() {
+        if (!sinkInitialized) {
+            LOG.warn("Phoenix metrics2/tracing sink was not started. Should be it be?");
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/main/java/org/apache/phoenix/trace/MetricsInfoImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/trace/MetricsInfoImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/trace/MetricsInfoImpl.java
new file mode 100644
index 0000000..47c1dda
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/trace/MetricsInfoImpl.java
@@ -0,0 +1,63 @@
+/**
+ * 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.phoenix.trace;
+
+import com.google.common.base.Objects;
+import static com.google.common.base.Preconditions.*;
+import org.apache.hadoop.metrics2.MetricsInfo;
+
+/**
+ * Making implementing metric info a little easier
+ * <p>
+ * Just a copy of the same from Hadoop, but exposed for usage.
+ */
+public class MetricsInfoImpl implements MetricsInfo {
+  private final String name, description;
+
+  MetricsInfoImpl(String name, String description) {
+    this.name = checkNotNull(name, "name");
+    this.description = checkNotNull(description, "description");
+  }
+
+  @Override public String name() {
+    return name;
+  }
+
+  @Override public String description() {
+    return description;
+  }
+
+  @Override public boolean equals(Object obj) {
+    if (obj instanceof MetricsInfo) {
+      MetricsInfo other = (MetricsInfo) obj;
+      return Objects.equal(name, other.name()) &&
+             Objects.equal(description, other.description());
+    }
+    return false;
+  }
+
+  @Override public int hashCode() {
+    return Objects.hashCode(name, description);
+  }
+
+  @Override public String toString() {
+    return Objects.toStringHelper(this)
+        .add("name", name).add("description", description)
+        .toString();
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/main/java/org/apache/phoenix/trace/PhoenixMetricsSink.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/trace/PhoenixMetricsSink.java b/phoenix-core/src/main/java/org/apache/phoenix/trace/PhoenixMetricsSink.java
new file mode 100644
index 0000000..265fc78
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/trace/PhoenixMetricsSink.java
@@ -0,0 +1,298 @@
+/**
+ * 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.phoenix.trace;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterators;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.SubsetConfiguration;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.apache.hadoop.metrics2.AbstractMetric;
+import org.apache.hadoop.metrics2.MetricsRecord;
+import org.apache.hadoop.metrics2.MetricsSink;
+import org.apache.hadoop.metrics2.MetricsTag;
+import org.apache.phoenix.metrics.*;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.query.QueryServicesOptions;
+import org.apache.phoenix.trace.util.Tracing;
+import org.apache.phoenix.util.QueryUtil;
+
+import javax.annotation.Nullable;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.*;
+
+import static org.apache.phoenix.metrics.MetricInfo.*;
+import static org.apache.phoenix.metrics.MetricInfo.HOSTNAME;
+
+/**
+ * Write the metrics to a phoenix table.
+ * Generally, this class is instantiated via hadoop-metrics2 property files.
+ * Specifically, you would create this class by adding the following to
+ * by
+ * This would actually be set as: <code>
+ * [prefix].sink.[some instance name].class=org.apache.phoenix.trace.PhoenixMetricsSink
+ * </code>, where <tt>prefix</tt> is either:
+ * <ol>
+ * <li>"phoenix", for the client</li>
+ * <li>"hbase", for the server</li>
+ * </ol>
+ * and
+ * <tt>some instance name</tt> is just any unique name, so properties can be differentiated if
+ * there are multiple sinks of the same type created
+ */
+public class PhoenixMetricsSink implements MetricsSink {
+
+    private static final Log LOG = LogFactory.getLog(PhoenixMetricsSink.class);
+
+    private static final String VARIABLE_VALUE = "?";
+
+    private static final Joiner COLUMN_JOIN = Joiner.on(".");
+    static final String TAG_FAMILY = "tags";
+    /**
+     * Count of the number of tags we are storing for this row
+     */
+    static final String TAG_COUNT = COLUMN_JOIN.join(TAG_FAMILY, "count");
+
+    static final String ANNOTATION_FAMILY = "annotations";
+    static final String ANNOTATION_COUNT = COLUMN_JOIN.join(ANNOTATION_FAMILY, "count");
+
+    /**
+     * Join strings on a comma
+     */
+    private static final Joiner COMMAS = Joiner.on(',');
+
+    private Connection conn;
+
+    private String table;
+
+    public PhoenixMetricsSink() {
+        LOG.info("Writing tracing metrics to phoenix table");
+
+    }
+
+    @Override
+    public void init(SubsetConfiguration config) {
+        Metrics.markSinkInitialized();
+        LOG.info("Phoenix tracing writer started");
+    }
+
+    /**
+     * Initialize <tt>this</tt> only when we need it
+     */
+    private void lazyInitialize() {
+        synchronized (this) {
+            if (this.conn != null) {
+                return;
+            }
+            try {
+                // create the phoenix connection
+                Properties props = new Properties();
+                props.setProperty(QueryServices.TRACING_FREQ_ATTRIB,
+                        Tracing.Frequency.NEVER.getKey());
+                org.apache.hadoop.conf.Configuration conf = HBaseConfiguration.create();
+                Connection conn = QueryUtil.getConnection(props, conf);
+                // enable bulk loading when we have enough data
+                conn.setAutoCommit(true);
+
+                String tableName =
+                        conf.get(QueryServices.TRACING_STATS_TABLE_NAME_ATTRIB,
+                                QueryServicesOptions.DEFAULT_TRACING_STATS_TABLE_NAME);
+
+                initializeInternal(conn, tableName);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private void initializeInternal(Connection conn, String tableName) throws SQLException {
+        this.conn = conn;
+
+        // ensure that the target table already exists
+        createTable(conn, tableName);
+    }
+
+    /**
+     * Used for <b>TESTING ONLY</b>
+     * Initialize the connection and setup the table to use the
+     * {@link org.apache.phoenix.query.QueryServicesOptions#DEFAULT_TRACING_STATS_TABLE_NAME}
+     *
+     * @param conn to store for upserts and to create the table (if necessary)
+     * @throws SQLException if any phoenix operation fails
+     */
+    @VisibleForTesting
+    public void initForTesting(Connection conn) throws SQLException {
+        initializeInternal(conn, QueryServicesOptions.DEFAULT_TRACING_STATS_TABLE_NAME);
+    }
+
+    /**
+     * Create a stats table with the given name. Stores the name for use later when creating upsert
+     * statements
+     *
+     * @param conn  connection to use when creating the table
+     * @param table name of the table to create
+     * @throws SQLException if any phoenix operations fails
+     */
+    private void createTable(Connection conn, String table) throws SQLException {
+        // only primary-key columns can be marked non-null
+        String ddl =
+                "create table if not exists " + table + "( " +
+                        TRACE.columnName + " bigint not null, " +
+                        PARENT.columnName + " bigint not null, " +
+                        SPAN.columnName + " bigint not null, " +
+                        DESCRIPTION.columnName + " varchar, " +
+                        START.columnName + " bigint, " +
+                        END.columnName + " bigint, " +
+                        HOSTNAME.columnName + " varchar, " +
+                        TAG_COUNT + " smallint, " +
+                        ANNOTATION_COUNT + " smallint" +
+                        "  CONSTRAINT pk PRIMARY KEY (" + TRACE.columnName + ", "
+                        + PARENT.columnName + ", " + SPAN.columnName + "))\n";
+        PreparedStatement stmt = conn.prepareStatement(ddl);
+        stmt.execute();
+        this.table = table;
+    }
+
+    @Override
+    public void flush() {
+        try {
+            this.conn.commit();
+            this.conn.rollback();
+        } catch (SQLException e) {
+            LOG.error("Failed to commit changes to table", e);
+        }
+    }
+
+    /**
+     * Add a new metric record to be written.
+     *
+     * @param record
+     */
+    @Override
+    public void putMetrics(MetricsRecord record) {
+        // its not a tracing record, we are done. This could also be handled by filters, but safer
+        // to do it here, in case it gets misconfigured
+        if (!record.name().startsWith(TracingUtils.METRIC_SOURCE_KEY)) {
+            return;
+        }
+
+        // don't initialize until we actually have something to write
+        lazyInitialize();
+
+        String stmt = "UPSERT INTO " + table + " (";
+        // drop it into the queue of things that should be written
+        List<String> keys = new ArrayList<String>();
+        List<Object> values = new ArrayList<Object>();
+        // we need to keep variable values in a separate set since they may have spaces, which
+        // causes the parser to barf. Instead, we need to add them after the statement is prepared
+        List<String> variableValues = new ArrayList<String>(record.tags().size());
+        keys.add(TRACE.columnName);
+        values.add(
+                Long.parseLong(record.name().substring(TracingUtils.METRIC_SOURCE_KEY.length())));
+
+        keys.add(DESCRIPTION.columnName);
+        values.add(VARIABLE_VALUE);
+        variableValues.add(record.description());
+
+        // add each of the metrics
+        for (AbstractMetric metric : record.metrics()) {
+            // name of the metric is also the column name to which we write
+            keys.add(MetricInfo.getColumnName(metric.name()));
+            values.add(metric.value());
+        }
+
+        // get the tags out so we can set them later (otherwise, need to be a single value)
+        int annotationCount = 0;
+        int tagCount = 0;
+        for (MetricsTag tag : record.tags()) {
+            if (tag.name().equals(ANNOTATION.traceName)) {
+                addDynamicEntry(keys, values, variableValues, ANNOTATION_FAMILY, tag, ANNOTATION,
+                        annotationCount);
+                annotationCount++;
+            } else if (tag.name().equals(TAG.traceName)) {
+                addDynamicEntry(keys, values, variableValues, TAG_FAMILY, tag, TAG, tagCount);
+                tagCount++;
+            } else if (tag.name().equals(HOSTNAME.traceName)) {
+                keys.add(HOSTNAME.columnName);
+                values.add(VARIABLE_VALUE);
+                variableValues.add(tag.value());
+            } else if (tag.name().equals("Context")) {
+                // ignored
+            } else {
+                LOG.error("Got an unexpected tag: " + tag);
+            }
+        }
+
+        // add the tag count, now that we know it
+        keys.add(TAG_COUNT);
+        // ignore the hostname in the tags, if we know it
+        values.add(tagCount);
+
+        keys.add(ANNOTATION_COUNT);
+        values.add(annotationCount);
+
+        // compile the statement together
+        stmt += COMMAS.join(keys);
+        stmt += ") VALUES (" + COMMAS.join(values) + ")";
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Logging metrics to phoenix table via: " + stmt);
+            LOG.trace("With tags: " + variableValues);
+        }
+        try {
+            PreparedStatement ps = conn.prepareStatement(stmt);
+            // add everything that wouldn't/may not parse
+            int index = 1;
+            for (String tag : variableValues) {
+                ps.setString(index++, tag);
+            }
+            ps.execute();
+        } catch (SQLException e) {
+            LOG.error("Could not write metric: \n" + record + " to prepared statement:\n" + stmt,
+                    e);
+        }
+    }
+
+    public static String getDynamicColumnName(String family, String column, int count) {
+        return COLUMN_JOIN.join(family, column) + count;
+    }
+
+    private void addDynamicEntry(List<String> keys, List<Object> values,
+            List<String> variableValues, String family, MetricsTag tag,
+            MetricInfo metric, int count) {
+        // <family><.dynColumn><count> <VARCHAR>
+        keys.add(getDynamicColumnName(family, metric.columnName, count) + " VARCHAR");
+
+        // build the annotation value
+        String val = tag.description() + " - " + tag.value();
+        values.add(VARIABLE_VALUE);
+        variableValues.add(val);
+    }
+
+    @VisibleForTesting
+    public void clearForTesting() throws SQLException {
+        this.conn.rollback();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/main/java/org/apache/phoenix/trace/PhoenixTableMetricsWriter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/trace/PhoenixTableMetricsWriter.java b/phoenix-core/src/main/java/org/apache/phoenix/trace/PhoenixTableMetricsWriter.java
deleted file mode 100644
index 7fcb92d..0000000
--- a/phoenix-core/src/main/java/org/apache/phoenix/trace/PhoenixTableMetricsWriter.java
+++ /dev/null
@@ -1,278 +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.phoenix.trace;
-
-import static org.apache.phoenix.metrics.MetricInfo.ANNOTATION;
-import static org.apache.phoenix.metrics.MetricInfo.DESCRIPTION;
-import static org.apache.phoenix.metrics.MetricInfo.END;
-import static org.apache.phoenix.metrics.MetricInfo.HOSTNAME;
-import static org.apache.phoenix.metrics.MetricInfo.PARENT;
-import static org.apache.phoenix.metrics.MetricInfo.SPAN;
-import static org.apache.phoenix.metrics.MetricInfo.START;
-import static org.apache.phoenix.metrics.MetricInfo.TAG;
-import static org.apache.phoenix.metrics.MetricInfo.TRACE;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseConfiguration;
-import org.apache.phoenix.metrics.MetricInfo;
-import org.apache.phoenix.metrics.MetricsWriter;
-import org.apache.phoenix.metrics.PhoenixAbstractMetric;
-import org.apache.phoenix.metrics.PhoenixMetricTag;
-import org.apache.phoenix.metrics.PhoenixMetricsRecord;
-import org.apache.phoenix.query.QueryServices;
-import org.apache.phoenix.query.QueryServicesOptions;
-import org.apache.phoenix.trace.util.Tracing;
-import org.apache.phoenix.util.QueryUtil;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Joiner;
-
-/**
- * Sink that writes phoenix metrics to a phoenix table
- * <p>
- * Each metric record should only correspond to a single completed span. Each span is only updated
- * in the phoenix table <i>once</i>
- */
-public class PhoenixTableMetricsWriter implements MetricsWriter {
-
-    private static final String VARIABLE_VALUE = "?";
-
-    public static final Log LOG = LogFactory.getLog(PhoenixTableMetricsWriter.class);
-
-    private static final Joiner COLUMN_JOIN = Joiner.on(".");
-    static final String TAG_FAMILY = "tags";
-    /** Count of the number of tags we are storing for this row */
-    static final String TAG_COUNT = COLUMN_JOIN.join(TAG_FAMILY, "count");
-
-    static final String ANNOTATION_FAMILY = "annotations";
-    static final String ANNOTATION_COUNT = COLUMN_JOIN.join(ANNOTATION_FAMILY, "count");
-
-    /** Join strings on a comma */
-    private static final Joiner COMMAS = Joiner.on(',');
-
-    private Connection conn;
-
-    private String table;
-
-    @Override
-    public void initialize() {
-        LOG.info("Phoenix tracing writer started");
-    }
-
-    /**
-     * Initialize <tt>this</tt> only when we need it
-     */
-    private void lazyInitialize() {
-        synchronized (this) {
-            if (this.conn != null) {
-                return;
-            }
-            try {
-                // create the phoenix connection
-                Properties props = new Properties();
-                props.setProperty(QueryServices.TRACING_FREQ_ATTRIB,
-                    Tracing.Frequency.NEVER.getKey());
-                Configuration conf = HBaseConfiguration.create();
-                Connection conn = QueryUtil.getConnection(props, conf);
-                // enable bulk loading when we have enough data
-                conn.setAutoCommit(true);
-
-                String tableName =
-                        conf.get(QueryServices.TRACING_STATS_TABLE_NAME_ATTRIB,
-                            QueryServicesOptions.DEFAULT_TRACING_STATS_TABLE_NAME);
-
-                initializeInternal(conn, tableName);
-            } catch (Exception e) {
-                throw new RuntimeException(e);
-            }
-        }
-    }
-
-    private void initializeInternal(Connection conn, String tableName) throws SQLException {
-        this.conn = conn;
-
-        // ensure that the target table already exists
-        createTable(conn, tableName);
-    }
-
-    /**
-     * Used for <b>TESTING ONLY</b>
-     * <p>
-     * Initialize the connection and setup the table to use the
-     * {@link TracingCompat#DEFAULT_TRACING_STATS_TABLE_NAME}
-     * @param conn to store for upserts and to create the table (if necessary)
-     * @throws SQLException if any phoenix operation fails
-     */
-    @VisibleForTesting
-    public void initForTesting(Connection conn) throws SQLException {
-        initializeInternal(conn, QueryServicesOptions.DEFAULT_TRACING_STATS_TABLE_NAME);
-    }
-
-    /**
-     * Create a stats table with the given name. Stores the name for use later when creating upsert
-     * statements
-     * @param conn connection to use when creating the table
-     * @param table name of the table to create
-     * @throws SQLException if any phoenix operations fails
-     */
-    private void createTable(Connection conn, String table) throws SQLException {
-        // only primary-key columns can be marked non-null
-        String ddl =
-                "create table if not exists " + table + "( " + 
-                        TRACE.columnName + " bigint not null, " +
-                        PARENT.columnName + " bigint not null, " +
-                        SPAN.columnName + " bigint not null, " +
-                        DESCRIPTION.columnName + " varchar, " +
-                        START.columnName + " bigint, " +
-                        END.columnName + " bigint, " +
-                        HOSTNAME.columnName + " varchar, " +
-                        TAG_COUNT + " smallint, " +
-                        ANNOTATION_COUNT + " smallint" +
-                        "  CONSTRAINT pk PRIMARY KEY (" + TRACE.columnName + ", "
-                            + PARENT.columnName + ", " + SPAN.columnName + "))\n";
-        PreparedStatement stmt = conn.prepareStatement(ddl);
-        stmt.execute();
-        this.table = table;
-    }
-
-    @Override
-    public void flush() {
-        try {
-            this.conn.commit();
-            this.conn.rollback();
-        } catch (SQLException e) {
-            LOG.error("Failed to commit changes to table", e);
-        }
-    }
-
-    /**
-     * Add a new metric record to be written.
-     * @param record
-     */
-    @Override
-    public void addMetrics(PhoenixMetricsRecord record) {
-        // its not a tracing record, we are done. This could also be handled by filters, but safer
-        // to do it here, in case it gets misconfigured
-        if (!record.name().startsWith(TracingCompat.METRIC_SOURCE_KEY)) {
-            return;
-        }
-
-        // don't initialize until we actually have something to write
-        lazyInitialize();
-
-        String stmt = "UPSERT INTO " + table + " (";
-        // drop it into the queue of things that should be written
-        List<String> keys = new ArrayList<String>();
-        List<Object> values = new ArrayList<Object>();
-        // we need to keep variable values in a separate set since they may have spaces, which
-        // causes the parser to barf. Instead, we need to add them after the statement is prepared
-        List<String> variableValues = new ArrayList<String>(record.tags().size());
-        keys.add(TRACE.columnName);
-        values.add(Long.parseLong(record.name().substring(TracingCompat.METRIC_SOURCE_KEY.length())));
-
-        keys.add(DESCRIPTION.columnName);
-        values.add(VARIABLE_VALUE);
-        variableValues.add(record.description());
-
-        // add each of the metrics
-        for (PhoenixAbstractMetric metric : record.metrics()) {
-            // name of the metric is also the column name to which we write
-            keys.add(MetricInfo.getColumnName(metric.getName()));
-            values.add(metric.value());
-        }
-
-        // get the tags out so we can set them later (otherwise, need to be a single value)
-        int annotationCount = 0;
-        int tagCount = 0;
-        for (PhoenixMetricTag tag : record.tags()) {
-            if (tag.name().equals(ANNOTATION.traceName)) {
-                addDynamicEntry(keys, values, variableValues, ANNOTATION_FAMILY, tag, ANNOTATION,
-                    annotationCount);
-                annotationCount++;
-            } else if (tag.name().equals(TAG.traceName)) {
-                addDynamicEntry(keys, values, variableValues, TAG_FAMILY, tag, TAG, tagCount);
-                tagCount++;
-            } else if (tag.name().equals(HOSTNAME.traceName)) {
-                keys.add(HOSTNAME.columnName);
-                values.add(VARIABLE_VALUE);
-                variableValues.add(tag.value());
-            } else if (tag.name().equals("Context")) {
-                // ignored
-            } else {
-                LOG.error("Got an unexpected tag: " + tag);
-            }
-        }
-
-        // add the tag count, now that we know it
-        keys.add(TAG_COUNT);
-        // ignore the hostname in the tags, if we know it
-        values.add(tagCount);
-
-        keys.add(ANNOTATION_COUNT);
-        values.add(annotationCount);
-
-        // compile the statement together
-        stmt += COMMAS.join(keys);
-        stmt += ") VALUES (" + COMMAS.join(values) + ")";
-
-        if (LOG.isTraceEnabled()) {
-            LOG.trace("Logging metrics to phoenix table via: " + stmt);
-            LOG.trace("With tags: " + variableValues);
-        }
-        try {
-            PreparedStatement ps = conn.prepareStatement(stmt);
-            // add everything that wouldn't/may not parse
-            int index = 1;
-            for (String tag : variableValues) {
-                ps.setString(index++, tag);
-            }
-            ps.execute();
-        } catch (SQLException e) {
-            LOG.error("Could not write metric: \n" + record + " to prepared statement:\n" + stmt, e);
-        }
-    }
-
-    public static String getDynamicColumnName(String family, String column, int count) {
-        return COLUMN_JOIN.join(family, column) + count;
-    }
-
-    private void addDynamicEntry(List<String> keys, List<Object> values,
-            List<String> variableValues, String family, PhoenixMetricTag tag,
-            MetricInfo metric, int count) {
-        // <family><.dynColumn><count> <VARCHAR>
-        keys.add(getDynamicColumnName(family, metric.columnName, count) + " VARCHAR");
-
-        // build the annotation value
-        String val = tag.description() + " - " + tag.value();
-        values.add(VARIABLE_VALUE);
-        variableValues.add(val);
-    }
-
-    public void clearForTesting() throws SQLException {
-        this.conn.rollback();
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/main/java/org/apache/phoenix/trace/TraceMetricSource.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/trace/TraceMetricSource.java b/phoenix-core/src/main/java/org/apache/phoenix/trace/TraceMetricSource.java
new file mode 100644
index 0000000..1b9e31a
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/trace/TraceMetricSource.java
@@ -0,0 +1,188 @@
+/**
+ * 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.phoenix.trace;
+
+import org.apache.hadoop.hbase.util.Pair;
+import org.apache.hadoop.metrics2.*;
+import org.apache.hadoop.metrics2.lib.Interns;
+import org.apache.phoenix.metrics.MetricInfo;
+import org.apache.phoenix.metrics.Metrics;
+import org.cloudera.htrace.HTraceConfiguration;
+import org.cloudera.htrace.Span;
+import org.cloudera.htrace.SpanReceiver;
+import org.cloudera.htrace.TimelineAnnotation;
+import org.cloudera.htrace.impl.MilliSpan;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import static org.apache.phoenix.metrics.MetricInfo.*;
+
+/**
+ * Sink for request traces ({@link SpanReceiver}) that pushes writes to {@link MetricsSource} in a
+ * format that we can more easily consume.
+ * <p>
+ * <p>
+ * Rather than write directly to a phoenix table, we drop it into the metrics queue so we can more
+ * cleanly handle it asyncrhonously.Currently, {@link MilliSpan} submits the span in a synchronized
+ * block to all the receivers, which could have a lot of overhead if we are submitting to multiple
+ * receivers.
+ * <p>
+ * The format of the generated metrics is this:
+ * <ol>
+ *   <li>All Metrics from the same span have the same name (allowing correlation in the sink)</li>
+ *   <li>The description of the metric describes what it contains. For instance,
+ *   <ul>
+ *     <li>{@link MetricInfo#PARENT} is the id of the parent of this span. (Root span is
+ *     {@link Span#ROOT_SPAN_ID}).</li>
+ *     <li>{@value MetricInfo#START} is the start time of the span</li>
+ *     <li>{@value MetricInfo#END} is the end time of the span</li>
+ *   </ul></li>
+ *   <li>Each span's messages are contained in a {@link MetricsTag} with the same name as above and a
+ *   generic counter for the number of messages (to differentiate messages and provide timeline
+ *   ordering).</li>
+ * </ol>
+ * <p>
+ * <i>So why even submit to metrics2 framework if we only have a single source?</i>
+ * <p>
+ * This allows us to make the updates in batches. We might have spans that finish before other spans
+ * (for instance in the same parent). By batching the updates we can lessen the overhead on the
+ * client, which is also busy doing 'real' work. <br>
+ * We could make our own queue and manage batching and filtering and dropping extra metrics, but
+ * that starts to get complicated fast (its not as easy as it sounds) so we use metrics2 to abstract
+ * out that pipeline and also provides us flexibility to dump metrics to other sources.
+ * <p>
+ * This is a somewhat rough implementation - we do excessive locking for correctness,
+ * rather than trying to make it fast, for the moment.
+ */
+public class TraceMetricSource implements SpanReceiver, MetricsSource {
+
+  private static final String EMPTY_STRING = "";
+
+  private static final String CONTEXT = "tracing";
+
+  private List<Metric> spans = new ArrayList<Metric>();
+
+  public TraceMetricSource() {
+
+    MetricsSystem manager = Metrics.initialize();
+
+    // Register this instance.
+    // For right now, we ignore the MBean registration issues that show up in DEBUG logs. Basically,
+    // we need a Jmx MBean compliant name. We'll get to a better name when we want that later
+    manager.register(CONTEXT, "Phoenix call tracing", this);
+  }
+
+  @Override
+  public void receiveSpan(Span span) {
+    Metric builder = new Metric(span);
+    // add all the metrics for the span
+    builder.addCounter(Interns.info(SPAN.traceName, EMPTY_STRING), span.getSpanId());
+    builder.addCounter(Interns.info(PARENT.traceName, EMPTY_STRING), span.getParentId());
+    builder.addCounter(Interns.info(START.traceName, EMPTY_STRING), span.getStartTimeMillis());
+    builder.addCounter(Interns.info(END.traceName, EMPTY_STRING), span.getStopTimeMillis());
+    // add the tags to the span. They were written in order received so we mark them as such
+    for (TimelineAnnotation ta : span.getTimelineAnnotations()) {
+      builder.add(new MetricsTag(Interns.info(TAG.traceName, Long.toString(ta.getTime())), ta
+          .getMessage()));
+    }
+
+    // add the annotations. We assume they are serialized as strings and integers, but that can
+    // change in the future
+    Map<byte[], byte[]> annotations = span.getKVAnnotations();
+    for (Entry<byte[], byte[]> annotation : annotations.entrySet()) {
+      Pair<String, String> val =
+          TracingUtils.readAnnotation(annotation.getKey(), annotation.getValue());
+      builder.add(new MetricsTag(Interns.info(ANNOTATION.traceName, val.getFirst()), val
+          .getSecond()));
+    }
+
+    // add the span to the list we care about
+    synchronized (this) {
+      spans.add(builder);
+    }
+  }
+
+  @Override
+  public void getMetrics(MetricsCollector collector, boolean all) {
+    // add a marker record so we know how many spans are used
+    // this is also necessary to ensure that we register the metrics source as an MBean (avoiding a
+    // runtime warning)
+    MetricsRecordBuilder marker = collector.addRecord(TracingUtils.METRICS_MARKER_CONTEXT);
+    marker.add(new MetricsTag(new MetricsInfoImpl("stat", "num spans"), Integer
+        .toString(spans.size())));
+
+    // actually convert the known spans into metric records as well
+    synchronized (this) {
+      for (Metric span : spans) {
+        MetricsRecordBuilder builder = collector.addRecord(new MetricsInfoImpl(TracingUtils
+            .getTraceMetricName(span.id), span.desc));
+        builder.setContext(TracingUtils.METRICS_CONTEXT);
+        for (Pair<MetricsInfo, Long> metric : span.counters) {
+          builder.addCounter(metric.getFirst(), metric.getSecond());
+        }
+        for (MetricsTag tag : span.tags) {
+          builder.add(tag);
+        }
+      }
+      // reset the spans so we don't keep a big chunk of memory around
+      spans = new ArrayList<Metric>();
+    }
+  }
+
+  @Override
+  public void close() throws IOException {
+    // noop
+  }
+
+  @Override
+  public void configure(HTraceConfiguration conf) {
+    // noop
+  }
+
+  private static class Metric {
+
+    List<Pair<MetricsInfo, Long>> counters = new ArrayList<Pair<MetricsInfo, Long>>();
+    List<MetricsTag> tags = new ArrayList<MetricsTag>();
+    private String id;
+    private String desc;
+
+    public Metric(Span span) {
+      this.id = Long.toString(span.getTraceId());
+      this.desc = span.getDescription();
+    }
+
+    /**
+     * @param metricsInfoImpl
+     * @param startTimeMillis
+     */
+    public void addCounter(MetricsInfo metricsInfoImpl, long startTimeMillis) {
+      counters.add(new Pair<MetricsInfo, Long>(metricsInfoImpl, startTimeMillis));
+    }
+
+    /**
+     * @param metricsTag
+     */
+    public void add(MetricsTag metricsTag) {
+      tags.add(metricsTag);
+    }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/842f8a8a/phoenix-core/src/main/java/org/apache/phoenix/trace/TraceReader.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/trace/TraceReader.java b/phoenix-core/src/main/java/org/apache/phoenix/trace/TraceReader.java
index 3d6eb9b..f3fc81d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/trace/TraceReader.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/trace/TraceReader.java
@@ -40,7 +40,7 @@ import com.google.common.base.Joiner;
 import com.google.common.primitives.Longs;
 
 /**
- * Read the traces written to phoenix tables by the {@link PhoenixTableMetricsWriter}.
+ * Read the traces written to phoenix tables by the {@link PhoenixMetricsSink}.
  */
 public class TraceReader {
 
@@ -54,8 +54,8 @@ public class TraceReader {
                 comma.join(MetricInfo.TRACE.columnName, MetricInfo.PARENT.columnName,
                     MetricInfo.SPAN.columnName, MetricInfo.DESCRIPTION.columnName,
                     MetricInfo.START.columnName, MetricInfo.END.columnName,
-                    MetricInfo.HOSTNAME.columnName, PhoenixTableMetricsWriter.TAG_COUNT,
-                    PhoenixTableMetricsWriter.ANNOTATION_COUNT);
+                    MetricInfo.HOSTNAME.columnName, PhoenixMetricsSink.TAG_COUNT,
+                        PhoenixMetricsSink.ANNOTATION_COUNT);
     }
 
     private Connection conn;
@@ -181,13 +181,13 @@ public class TraceReader {
     private Collection<? extends String> getTags(long traceid, long parent, long span, int count)
             throws SQLException {
         return getDynamicCountColumns(traceid, parent, span, count,
-            PhoenixTableMetricsWriter.TAG_FAMILY, MetricInfo.TAG.columnName);
+                PhoenixMetricsSink.TAG_FAMILY, MetricInfo.TAG.columnName);
     }
 
     private Collection<? extends String> getAnnotations(long traceid, long parent, long span,
             int count) throws SQLException {
         return getDynamicCountColumns(traceid, parent, span, count,
-            PhoenixTableMetricsWriter.ANNOTATION_FAMILY, MetricInfo.ANNOTATION.columnName);
+                PhoenixMetricsSink.ANNOTATION_FAMILY, MetricInfo.ANNOTATION.columnName);
     }
 
     private Collection<? extends String> getDynamicCountColumns(long traceid, long parent,
@@ -199,7 +199,7 @@ public class TraceReader {
         // build the column strings, family.column<index>
         String[] parts = new String[count];
         for (int i = 0; i < count; i++) {
-            parts[i] = PhoenixTableMetricsWriter.getDynamicColumnName(family, columnName, i);
+            parts[i] = PhoenixMetricsSink.getDynamicColumnName(family, columnName, i);
         }
         // join the columns together
         String columns = comma.join(parts);