You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by ab...@apache.org on 2019/09/09 08:40:36 UTC

[hive] branch master updated: HIVE-22149: Metastore: Unify codahale metrics.log json structure between hiveserver2 and metastore services (Laszlo Bodor reviewed by Zoltan Haindrich)

This is an automated email from the ASF dual-hosted git repository.

abstractdog pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git


The following commit(s) were added to refs/heads/master by this push:
     new 0b85aaf  HIVE-22149: Metastore: Unify codahale metrics.log json structure between hiveserver2 and metastore services (Laszlo Bodor reviewed by Zoltan Haindrich)
0b85aaf is described below

commit 0b85aaf115d701e6ec0158cabe59d56fd777594f
Author: Laszlo Bodor <bo...@gmail.com>
AuthorDate: Mon Sep 9 10:32:27 2019 +0200

    HIVE-22149: Metastore: Unify codahale metrics.log json structure between hiveserver2 and metastore services (Laszlo Bodor reviewed by Zoltan Haindrich)
    
    Signed-off-by: Laszlo Bodor <bo...@gmail.com>
---
 .../hive/metastore/TestMetaStoreMetrics.java       | 10 ++--
 .../hadoop/hive/metastore/HiveMetaStore.java       | 10 +---
 .../hadoop/hive/metastore/metrics/Metrics.java     | 31 ++++++++--
 .../hadoop/hive/metastore/metrics/TestMetrics.java | 70 +++++++++++++++++++---
 4 files changed, 93 insertions(+), 28 deletions(-)

diff --git a/itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/TestMetaStoreMetrics.java b/itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/TestMetaStoreMetrics.java
index 03028a4..694bad5 100644
--- a/itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/TestMetaStoreMetrics.java
+++ b/itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/TestMetaStoreMetrics.java
@@ -134,26 +134,26 @@ public class TestMetaStoreMetrics {
 
     Thread.sleep(2000);  // TODO Evil!  Need to figure out a way to remove this sleep.
     //initial state is one connection
-    int initialCount =
-        (Integer)Metrics.getRegistry().getGauges().get(MetricsConstants.OPEN_CONNECTIONS).getValue();
+    long initialCount =
+        Metrics.getRegistry().getCounters().get(MetricsConstants.OPEN_CONNECTIONS).getCount();
 
     //create two connections
     HiveMetaStoreClient msc = new HiveMetaStoreClient(hiveConf);
     HiveMetaStoreClient msc2 = new HiveMetaStoreClient(hiveConf);
 
     Assert.assertEquals(initialCount + 2,
-        Metrics.getRegistry().getGauges().get(MetricsConstants.OPEN_CONNECTIONS).getValue());
+        Metrics.getRegistry().getCounters().get(MetricsConstants.OPEN_CONNECTIONS).getCount());
 
     //close one connection, verify still two left
     msc.close();
     Thread.sleep(2000);  // TODO Evil!  Need to figure out a way to remove this sleep.
     Assert.assertEquals(initialCount + 1,
-        Metrics.getRegistry().getGauges().get(MetricsConstants.OPEN_CONNECTIONS).getValue());
+        Metrics.getRegistry().getCounters().get(MetricsConstants.OPEN_CONNECTIONS).getCount());
 
     //close one connection, verify still one left
     msc2.close();
     Thread.sleep(2000);  // TODO Evil!  Need to figure out a way to remove this sleep.
     Assert.assertEquals(initialCount,
-        Metrics.getRegistry().getGauges().get(MetricsConstants.OPEN_CONNECTIONS).getValue());
+        Metrics.getRegistry().getCounters().get(MetricsConstants.OPEN_CONNECTIONS).getCount());
   }
 }
diff --git a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java
index 8e99cf4..4749b56 100644
--- a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java
+++ b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java
@@ -9882,8 +9882,6 @@ public class HiveMetaStore extends ThriftHiveMetastore {
     }
   }
 
-  private static AtomicInteger openConnections;
-
   /**
    * Start Metastore based on a passed {@link HadoopThriftAuthBridge}
    *
@@ -10025,10 +10023,6 @@ public class HiveMetaStore extends ThriftHiveMetastore {
       serverSocket = new TServerSocketKeepAlive(serverSocket);
     }
 
-    // Metrics will have already been initialized if we're using them since HMSHandler
-    // initializes them.
-    openConnections = Metrics.getOrCreateGauge(MetricsConstants.OPEN_CONNECTIONS);
-
     TThreadPoolServer.Args args = new TThreadPoolServer.Args(serverSocket)
         .processor(processor)
         .transportFactory(transFactory)
@@ -10045,13 +10039,13 @@ public class HiveMetaStore extends ThriftHiveMetastore {
 
       @Override
       public ServerContext createContext(TProtocol tProtocol, TProtocol tProtocol1) {
-        openConnections.incrementAndGet();
+        Metrics.getOpenConnectionsCounter().inc();
         return null;
       }
 
       @Override
       public void deleteContext(ServerContext serverContext, TProtocol tProtocol, TProtocol tProtocol1) {
-        openConnections.decrementAndGet();
+        Metrics.getOpenConnectionsCounter().dec();
         // If the IMetaStoreClient#close was called, HMSHandler#shutdown would have already
         // cleaned up thread local RawStore. Otherwise, do it now.
         cleanupRawStore();
diff --git a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/metrics/Metrics.java b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/metrics/Metrics.java
index 53ee84a..4dc7aa6 100644
--- a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/metrics/Metrics.java
+++ b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/metrics/Metrics.java
@@ -29,7 +29,9 @@ import com.codahale.metrics.ConsoleReporter;
 import com.codahale.metrics.Counter;
 import com.codahale.metrics.Gauge;
 import com.codahale.metrics.JmxReporter;
+import com.codahale.metrics.Metric;
 import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.MetricSet;
 import com.codahale.metrics.Reporter;
 import com.codahale.metrics.ScheduledReporter;
 import com.codahale.metrics.Slf4jReporter;
@@ -53,6 +55,7 @@ public class Metrics {
 
   private static Metrics self;
   private static final AtomicInteger singletonAtomicInteger = new AtomicInteger();
+  private static final Counter dummyCounter = new Counter();
 
   private final MetricRegistry registry;
   private List<Reporter> reporters;
@@ -91,7 +94,7 @@ public class Metrics {
    * metrics have not been initialized.
    */
   public static Counter getOrCreateCounter(String name) {
-    if (self == null) return null;
+    if (self == null) return dummyCounter;
     Map<String, Counter> counters = self.registry.getCounters();
     Counter counter = counters.get(name);
     if (counter != null) return counter;
@@ -153,6 +156,10 @@ public class Metrics {
     }
   }
 
+  public static Counter getOpenConnectionsCounter() {
+    return getOrCreateCounter(MetricsConstants.OPEN_CONNECTIONS);
+  }
+
   @VisibleForTesting
   static List<Reporter> getReporters() {
     return self.reporters;
@@ -161,11 +168,13 @@ public class Metrics {
   private Metrics(Configuration conf) {
     registry = new MetricRegistry();
 
-    registry.registerAll(new GarbageCollectorMetricSet());
-    registry.registerAll(new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer()));
-    registry.registerAll(new MemoryUsageGaugeSet());
-    registry.registerAll(new ThreadStatesGaugeSet());
-    registry.registerAll(new ClassLoadingGaugeSet());
+    // this is the same logic as implemented in CodahaleMetrics in hive-common package,
+    // but standalone-metastore project doesn't depend on that
+    registerAll("gc", new GarbageCollectorMetricSet());
+    registerAll("buffers", new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer()));
+    registerAll("memory", new MemoryUsageGaugeSet());
+    registerAll("threads", new ThreadStatesGaugeSet());
+    registerAll("classLoading", new ClassLoadingGaugeSet());
 
     /*
      * This is little complicated.  First we look for our own config values on this.  If those
@@ -255,4 +264,14 @@ public class Metrics {
     // Create map for tracking gauges
     gaugeAtomics = new HashMap<>();
   }
+
+  private void registerAll(String prefix, MetricSet metricSet) {
+    for (Map.Entry<String, Metric> entry : metricSet.getMetrics().entrySet()) {
+      if (entry.getValue() instanceof MetricSet) {
+        registerAll(prefix + "." + entry.getKey(), (MetricSet) entry.getValue());
+      } else {
+        registry.register(prefix + "." + entry.getKey(), entry.getValue());
+      }
+    }
+  }
 }
diff --git a/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/metrics/TestMetrics.java b/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/metrics/TestMetrics.java
index 40a5175..29d051a 100644
--- a/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/metrics/TestMetrics.java
+++ b/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/metrics/TestMetrics.java
@@ -18,6 +18,8 @@
 package org.apache.hadoop.hive.metastore.metrics;
 
 import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.util.List;
@@ -53,6 +55,7 @@ public class TestMetrics {
         MetastoreConf.ConfVars.METRICS_SLF4J_LOG_FREQUENCY_MINS, REPORT_INTERVAL, TimeUnit.SECONDS);
 
     // 1. Verify the default level (INFO)
+    MetastoreConf.setVar(conf, MetastoreConf.ConfVars.METRICS_SLF4J_LOG_LEVEL, "INFO");
     validateSlf4jReporter(conf, Level.INFO);
 
     // 2. Verify an overridden level (DEBUG)
@@ -60,8 +63,8 @@ public class TestMetrics {
     validateSlf4jReporter(conf, Level.DEBUG);
   }
 
-  private void validateSlf4jReporter(Configuration conf, Level level) throws InterruptedException {
-    Metrics.initialize(conf);
+  private void validateSlf4jReporter(Configuration conf, Level level) throws Exception {
+    initializeMetrics(conf);
     Counter counter = Metrics.getOrCreateCounter("my-counter");
     counter.inc(5);
     // Make sure it has a chance to dump it.
@@ -87,7 +90,7 @@ public class TestMetrics {
     MetastoreConf.setTimeVar(conf, MetastoreConf.ConfVars.METRICS_JSON_FILE_INTERVAL, REPORT_INTERVAL,
         TimeUnit.SECONDS);
 
-    Metrics.initialize(conf);
+    initializeMetrics(conf);
     Counter counter = Metrics.getOrCreateCounter("my-counter");
 
     for (int i = 0; i < 5; i++) {
@@ -101,6 +104,35 @@ public class TestMetrics {
   }
 
   @Test
+  public void testJsonStructure() throws Exception {
+    File jsonReportFile = File.createTempFile("TestMetrics", ".json");
+    String jsonFile = jsonReportFile.getAbsolutePath();
+
+    Configuration conf = MetastoreConf.newMetastoreConf();
+    MetastoreConf.setVar(conf, MetastoreConf.ConfVars.METRICS_REPORTERS, "json");
+    MetastoreConf.setVar(conf, MetastoreConf.ConfVars.METRICS_JSON_FILE_LOCATION, jsonFile);
+    MetastoreConf.setTimeVar(conf, MetastoreConf.ConfVars.METRICS_JSON_FILE_INTERVAL,
+        REPORT_INTERVAL, TimeUnit.SECONDS);
+
+    initializeMetrics(conf);
+
+    Counter openConnections = Metrics.getOpenConnectionsCounter();
+    openConnections.inc();
+
+    Thread.sleep(REPORT_INTERVAL * 1000 + REPORT_INTERVAL * 1000 / 2);
+
+    String json = new String(MetricsTestUtils.getFileData(jsonFile, 200, 10));
+
+    MetricsTestUtils.verifyMetricsJson(json, MetricsTestUtils.GAUGE, "buffers.direct.capacity");
+    MetricsTestUtils.verifyMetricsJson(json, MetricsTestUtils.GAUGE, "memory.heap.used");
+    MetricsTestUtils.verifyMetricsJson(json, MetricsTestUtils.GAUGE, "threads.count");
+    MetricsTestUtils.verifyMetricsJson(json, MetricsTestUtils.GAUGE, "classLoading.loaded");
+
+    MetricsTestUtils.verifyMetricsJson(json, MetricsTestUtils.COUNTER,
+        MetricsConstants.OPEN_CONNECTIONS, 1);
+  }
+
+  @Test
   public void allReporters() throws Exception {
     String jsonFile = System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") +
         "TestMetricsOutput.json";
@@ -108,7 +140,7 @@ public class TestMetrics {
     MetastoreConf.setVar(conf, MetastoreConf.ConfVars.METRICS_REPORTERS, "json,jmx,console,hadoop");
     MetastoreConf.setVar(conf, MetastoreConf.ConfVars.METRICS_JSON_FILE_LOCATION, jsonFile);
 
-    Metrics.initialize(conf);
+    initializeMetrics(conf);
 
     Assert.assertEquals(4, Metrics.getReporters().size());
   }
@@ -125,7 +157,7 @@ public class TestMetrics {
             "org.apache.hadoop.hive.common.metrics.metrics2.Metrics2Reporter");
     MetastoreConf.setVar(conf, MetastoreConf.ConfVars.METRICS_JSON_FILE_LOCATION, jsonFile);
 
-    Metrics.initialize(conf);
+    initializeMetrics(conf);
 
     Assert.assertEquals(4, Metrics.getReporters().size());
   }
@@ -139,7 +171,7 @@ public class TestMetrics {
         "JSON_FILE,JMX,CONSOLE,HADOOP2");
     MetastoreConf.setVar(conf, MetastoreConf.ConfVars.METRICS_JSON_FILE_LOCATION, jsonFile);
 
-    Metrics.initialize(conf);
+    initializeMetrics(conf);
 
     Assert.assertEquals(4, Metrics.getReporters().size());
   }
@@ -150,7 +182,7 @@ public class TestMetrics {
         "TestMetricsOutput.json";
     Configuration conf = MetastoreConf.newMetastoreConf();
     MetastoreConf.setVar(conf, MetastoreConf.ConfVars.METRICS_JSON_FILE_LOCATION, jsonFile);
-    Metrics.initialize(conf);
+    initializeMetrics(conf);
 
     Assert.assertEquals(2, Metrics.getReporters().size());
   }
@@ -173,9 +205,19 @@ public class TestMetrics {
     }
 
     static void verifyMetricsJson(String json, MetricsCategory category, String metricsName,
-                                         Object expectedValue) throws Exception {
+        Object expectedValue) throws Exception {
       JsonNode jsonNode = getJsonNode(json, category, metricsName);
-      Assert.assertEquals(expectedValue.toString(), jsonNode.asText());
+      Assert.assertTrue(String.format("%s.%s.%s should not be empty", category.category,
+          metricsName, category.metricsHandle), !jsonNode.asText().isEmpty());
+
+      if (expectedValue != null) {
+        Assert.assertEquals(expectedValue.toString(), jsonNode.asText());
+      }
+    }
+
+    static void verifyMetricsJson(String json, MetricsCategory category, String metricsName)
+        throws Exception {
+      verifyMetricsJson(json, category, metricsName, null);
     }
 
     static JsonNode getJsonNode(String json, MetricsCategory category, String metricsName) throws Exception {
@@ -195,4 +237,14 @@ public class TestMetrics {
       return Files.readAllBytes(Paths.get(path));
     }
   }
+
+  private void initializeMetrics(Configuration conf) throws Exception {
+    Field field = Metrics.class.getDeclaredField("self");
+    field.setAccessible(true);
+
+    Constructor<?> cons = Metrics.class.getDeclaredConstructor(Configuration.class);
+    cons.setAccessible(true);
+
+    field.set(null, cons.newInstance(conf));
+  }
 }