This is an automated email from the ASF dual-hosted git repository. stoty pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/phoenix.git
The following commit(s) were added to refs/heads/master by this push: new 58b6935884 PHOENIX-6699 Phoenix metrics overwriting DefaultMetricsSystem in RegionServers 58b6935884 is described below commit 58b693588403a576334460f13612efd94d0c7e64 Author: Istvan Toth <st...@apache.org> AuthorDate: Thu Apr 28 07:21:33 2022 +0200 PHOENIX-6699 Phoenix metrics overwriting DefaultMetricsSystem in RegionServers --- .../monitoring/GlobalMetricRegistriesAdapter.java | 7 ++++++ .../org/apache/phoenix/monitoring/MetricUtil.java | 26 ++++++++++++++++++++++ .../apache/phoenix/monitoring/MetricUtilTest.java | 17 ++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/phoenix-core/src/main/java/org/apache/phoenix/monitoring/GlobalMetricRegistriesAdapter.java b/phoenix-core/src/main/java/org/apache/phoenix/monitoring/GlobalMetricRegistriesAdapter.java index 0f1c8c2744..4a9093511f 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/monitoring/GlobalMetricRegistriesAdapter.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/monitoring/GlobalMetricRegistriesAdapter.java @@ -53,6 +53,13 @@ public class GlobalMetricRegistriesAdapter { private static GlobalMetricRegistriesAdapter INSTANCE = new GlobalMetricRegistriesAdapter(); private GlobalMetricRegistriesAdapter() { + if (MetricUtil.isDefaultMetricsInitialized()) { + // Prevent clobbering the default metrics HBase has set up in + // RS or Master while JmxCacheBuster shuts the Metrics down + LOGGER.info("HBase metrics is already initialized. " + + "Skipping Phoenix metrics initialization."); + return; + } DefaultMetricsSystem.initialize("Phoenix"); JvmMetrics.initSingleton("Phoenix", ""); } diff --git a/phoenix-core/src/main/java/org/apache/phoenix/monitoring/MetricUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/monitoring/MetricUtil.java index 1974eb806e..bbe5f2a46e 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/monitoring/MetricUtil.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/monitoring/MetricUtil.java @@ -17,11 +17,19 @@ */ package org.apache.phoenix.monitoring; +import java.lang.reflect.Field; + +import org.apache.hadoop.metrics2.impl.MetricsSystemImpl; +import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; import org.apache.phoenix.log.LogLevel; import org.apache.phoenix.monitoring.CombinableMetric.NoOpRequestMetric; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class MetricUtil { + private static final Logger LOGGER = LoggerFactory.getLogger(MetricUtil.class); + public static CombinableMetric getCombinableMetric(boolean isRequestMetricsEnabled, LogLevel connectionLogLevel, MetricType type) { @@ -38,4 +46,22 @@ public class MetricUtil { return new MetricsStopWatch(true); } + // We need to cover the case when JmxCacheBuster has just stopped the HBase metrics + // system, and not accidentally overwrite the DefaultMetricsSystem singleton. + // See PHOENIX-6699 + public static boolean isDefaultMetricsInitialized() { + try { + MetricsSystemImpl metrics = (MetricsSystemImpl) DefaultMetricsSystem.instance(); + Field prefixField = MetricsSystemImpl.class.getDeclaredField("prefix"); + prefixField.setAccessible(true); + String prefix = (String) prefixField.get(metrics); + prefixField.setAccessible(false); + if (prefix != null) { + return true; + } + } catch (Exception e) { + LOGGER.error("Exception trying to determine if HBase metrics is initialized", e); + } + return false; + } } diff --git a/phoenix-core/src/test/java/org/apache/phoenix/monitoring/MetricUtilTest.java b/phoenix-core/src/test/java/org/apache/phoenix/monitoring/MetricUtilTest.java index 141ce724d1..3e44ecfceb 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/monitoring/MetricUtilTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/monitoring/MetricUtilTest.java @@ -17,6 +17,8 @@ */ package org.apache.phoenix.monitoring; +import org.apache.hadoop.metrics2.impl.MetricsSystemImpl; +import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; import org.apache.phoenix.log.LogLevel; import org.junit.Test; import org.junit.runner.RunWith; @@ -27,6 +29,8 @@ import static org.apache.phoenix.monitoring.MetricType.WALL_CLOCK_TIME_MS; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import java.lang.reflect.Field; + @RunWith(MockitoJUnitRunner.class) public class MetricUtilTest { @@ -48,4 +52,17 @@ public class MetricUtilTest { LogLevel.OFF, WALL_CLOCK_TIME_MS); assertFalse(metricsStopWatch.getMetricsEnabled()); } + + @Test + //Check that MetricsSystemImpl has a String "prefix" field in the Hadoop version we test with + public void testInternalMetricsField() throws NoSuchFieldException, + SecurityException, IllegalArgumentException, IllegalAccessException { + MetricsSystemImpl metrics = (MetricsSystemImpl) DefaultMetricsSystem.instance(); + Field prefixField = MetricsSystemImpl.class.getDeclaredField("prefix"); + prefixField.setAccessible(true); + String oldValue = (String)prefixField.get(metrics); + prefixField.set(metrics, "dummy"); + prefixField.set(metrics, oldValue); + prefixField.setAccessible(false); + } }