diff --git a/common/src/java/org/apache/hadoop/hive/ql/log/PerfLogger.java b/common/src/java/org/apache/hadoop/hive/ql/log/PerfLogger.java index 8fa5cbf..3056af9 100644 --- a/common/src/java/org/apache/hadoop/hive/ql/log/PerfLogger.java +++ b/common/src/java/org/apache/hadoop/hive/ql/log/PerfLogger.java @@ -122,8 +122,8 @@ public void PerfLogBegin(String callerName, String method) { startTimes.put(method, new Long(startTime)); if (LOG.isDebugEnabled()) { LOG.debug(""); - beginMetrics(method); } + beginMetrics(method); } /** * Call this function in correspondence of PerfLogBegin to mark the end of the measurement. @@ -162,9 +162,8 @@ public long PerfLogEnd(String callerName, String method, String additionalInfo) } sb.append(">"); LOG.debug(sb.toString()); - - endMetrics(method); } + endMetrics(method); return duration; } @@ -231,4 +230,15 @@ private void endMetrics(String method) { public ImmutableMap getEndTimes() { return ImmutableMap.copyOf(endTimes); } + + /** + * Cleans up any dangling perfLog metric call scopes. + */ + public void cleanupPerfLogMetrics() { + for (String startKey : startTimes.keySet()) { + if (endTimes.get(startKey) == null) { + endMetrics(startKey); + } + } + } } diff --git a/itests/hive-unit/src/test/java/org/apache/hive/jdbc/miniHS2/TestHs2Metrics.java b/itests/hive-unit/src/test/java/org/apache/hive/jdbc/miniHS2/TestHs2Metrics.java index 6a98968..fa9043b 100644 --- a/itests/hive-unit/src/test/java/org/apache/hive/jdbc/miniHS2/TestHs2Metrics.java +++ b/itests/hive-unit/src/test/java/org/apache/hive/jdbc/miniHS2/TestHs2Metrics.java @@ -28,6 +28,8 @@ import org.apache.hadoop.hive.ql.parse.SemanticException; import org.apache.hive.service.cli.CLIServiceClient; import org.apache.hive.service.cli.SessionHandle; +import org.junit.Assert; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -43,7 +45,6 @@ private static MiniHS2 miniHS2; private static Map confOverlay; - private static CodahaleMetrics metrics; //Check metrics during semantic analysis. public static class MetricCheckingHook implements HiveSemanticAnalyzerHook { @@ -79,10 +80,14 @@ public static void setup() throws Exception { confOverlay.put(HiveConf.ConfVars.HIVE_SERVER2_METRICS_ENABLED.varname, "true"); confOverlay.put(HiveConf.ConfVars.HIVE_SUPPORT_CONCURRENCY.varname, "false"); miniHS2.start(confOverlay); - - HiveConf conf = new HiveConf(); + } + @Before + public void before() throws Exception { + HiveConf conf = new HiveConf(); + MetricsFactory.close(); + MetricsFactory.init(conf); metrics = (CodahaleMetrics) MetricsFactory.getInstance(); } @@ -112,6 +117,34 @@ public void testMetrics() throws Exception { MetricsTestUtils.verifyMetricsJson(json, MetricsTestUtils.COUNTER, "active_calls_api_compile", 0); MetricsTestUtils.verifyMetricsJson(json, MetricsTestUtils.COUNTER, "active_calls_api_hs2_operation_RUNNING", 0); MetricsTestUtils.verifyMetricsJson(json, MetricsTestUtils.COUNTER, "active_calls_api_hs2_sql_operation_RUNNING", 0); + + serviceClient.closeSession(sessHandle); + } + + @Test + public void testClosedScopes() throws Exception { + CLIServiceClient serviceClient = miniHS2.getServiceClient(); + SessionHandle sessHandle = serviceClient.openSession("foo", "bar"); + + //this should error at analyze scope, but not leave any parse dangling. + Exception expectedException = null; + try { + serviceClient.executeStatement(sessHandle, "select aaa", confOverlay); + } catch (Exception e) { + expectedException = e; + } + Assert.assertNotNull("Expected semantic exception", expectedException); + + //check that all scopes were recorded, but are not open. + CodahaleMetrics metrics = (CodahaleMetrics) MetricsFactory.getInstance(); + String json = metrics.dumpJson(); + + MetricsTestUtils.verifyMetricsJson(json, MetricsTestUtils.TIMER, "api_parse", 1); + MetricsTestUtils.verifyMetricsJson(json, MetricsTestUtils.TIMER, "api_semanticAnalyze", 1); + MetricsTestUtils.verifyMetricsJson(json, MetricsTestUtils.COUNTER, "active_calls_api_parse", 0); + MetricsTestUtils.verifyMetricsJson(json, MetricsTestUtils.COUNTER, "active_calls_api_semanticAnalyze", 0); + + serviceClient.closeSession(sessHandle); } } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/Driver.java b/ql/src/java/org/apache/hadoop/hive/ql/Driver.java index 10bd97b..f0e2200 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/Driver.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/Driver.java @@ -1437,6 +1437,7 @@ private boolean requiresLock() { } private CommandProcessorResponse createProcessorResponse(int ret) { + SessionState.getPerfLogger().cleanupPerfLogMetrics(); queryDisplay.setErrorMessage(errorMessage); return new CommandProcessorResponse(ret, errorMessage, SQLState, downstreamError); }