This is an automated email from the ASF dual-hosted git repository. yong pushed a commit to branch branch-4.15 in repository https://gitbox.apache.org/repos/asf/bookkeeper.git
commit 5df5d56e979397fe036baf656a5d312183bbff8e Author: Yan Zhao <[email protected]> AuthorDate: Wed Dec 7 15:52:08 2022 +0800 Make `jvm_memory_direct_bytes_used` metrics compatible with jdk8. (#3677) (cherry picked from commit 5a38080ccfd4be051d5c276283e0f24c21ef938d) --- .../prometheus-metrics-provider/pom.xml | 6 +++- .../prometheus/PrometheusMetricsProvider.java | 33 ++++++++++++++++++---- .../prometheus/TestPrometheusMetricsProvider.java | 7 +++-- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/bookkeeper-stats-providers/prometheus-metrics-provider/pom.xml b/bookkeeper-stats-providers/prometheus-metrics-provider/pom.xml index a39d48791c..6768847c44 100644 --- a/bookkeeper-stats-providers/prometheus-metrics-provider/pom.xml +++ b/bookkeeper-stats-providers/prometheus-metrics-provider/pom.xml @@ -52,7 +52,11 @@ <groupId>io.netty</groupId> <artifactId>netty-common</artifactId> </dependency> - + <dependency> + <groupId>io.netty</groupId> + <artifactId>netty-buffer</artifactId> + <scope>test</scope> + </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-servlet</artifactId> diff --git a/bookkeeper-stats-providers/prometheus-metrics-provider/src/main/java/org/apache/bookkeeper/stats/prometheus/PrometheusMetricsProvider.java b/bookkeeper-stats-providers/prometheus-metrics-provider/src/main/java/org/apache/bookkeeper/stats/prometheus/PrometheusMetricsProvider.java index ab81992531..607b16aae6 100644 --- a/bookkeeper-stats-providers/prometheus-metrics-provider/src/main/java/org/apache/bookkeeper/stats/prometheus/PrometheusMetricsProvider.java +++ b/bookkeeper-stats-providers/prometheus-metrics-provider/src/main/java/org/apache/bookkeeper/stats/prometheus/PrometheusMetricsProvider.java @@ -34,6 +34,7 @@ import java.io.IOException; import java.io.Writer; import java.lang.management.BufferPoolMXBean; import java.lang.management.ManagementFactory; +import java.lang.reflect.Field; import java.net.InetSocketAddress; import java.util.Collections; import java.util.List; @@ -43,6 +44,8 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Supplier; import org.apache.bookkeeper.stats.StatsLogger; import org.apache.bookkeeper.stats.StatsProvider; import org.apache.bookkeeper.stats.ThreadRegistry; @@ -130,7 +133,7 @@ public class PrometheusMetricsProvider implements StatsProvider { registerMetrics(Gauge.build("jvm_memory_direct_bytes_used", "-").create().setChild(new Child() { @Override public double get() { - return poolMxBeanOp.isPresent() ? poolMxBeanOp.get().getMemoryUsed() : Double.NaN; + return getDirectMemoryUsage.get(); } })); @@ -212,14 +215,34 @@ public class PrometheusMetricsProvider implements StatsProvider { } } - private static final Logger log = LoggerFactory.getLogger(PrometheusMetricsProvider.class); + /* + * Try to get Netty counter of used direct memory. This will be correct, unlike the JVM values. + */ + private static final AtomicLong directMemoryUsage; private static final Optional<BufferPoolMXBean> poolMxBeanOp; + private static final Supplier<Double> getDirectMemoryUsage; static { - List<BufferPoolMXBean> platformMXBeans = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class); - poolMxBeanOp = platformMXBeans.stream() - .filter(bufferPoolMXBean -> bufferPoolMXBean.getName().equals("direct")).findAny(); + if (PlatformDependent.useDirectBufferNoCleaner()) { + poolMxBeanOp = Optional.empty(); + AtomicLong tmpDirectMemoryUsage = null; + try { + Field field = PlatformDependent.class.getDeclaredField("DIRECT_MEMORY_COUNTER"); + field.setAccessible(true); + tmpDirectMemoryUsage = (AtomicLong) field.get(null); + } catch (Throwable t) { + log.warn("Failed to access netty DIRECT_MEMORY_COUNTER field {}", t.getMessage()); + } + directMemoryUsage = tmpDirectMemoryUsage; + getDirectMemoryUsage = () -> directMemoryUsage != null ? directMemoryUsage.get() : Double.NaN; + } else { + directMemoryUsage = null; + List<BufferPoolMXBean> platformMXBeans = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class); + poolMxBeanOp = platformMXBeans.stream() + .filter(bufferPoolMXBean -> bufferPoolMXBean.getName().equals("direct")).findAny(); + getDirectMemoryUsage = () -> poolMxBeanOp.isPresent() ? poolMxBeanOp.get().getMemoryUsed() : Double.NaN; + } } } diff --git a/bookkeeper-stats-providers/prometheus-metrics-provider/src/test/java/org/apache/bookkeeper/stats/prometheus/TestPrometheusMetricsProvider.java b/bookkeeper-stats-providers/prometheus-metrics-provider/src/test/java/org/apache/bookkeeper/stats/prometheus/TestPrometheusMetricsProvider.java index 999be26cbb..850f8b57b3 100644 --- a/bookkeeper-stats-providers/prometheus-metrics-provider/src/test/java/org/apache/bookkeeper/stats/prometheus/TestPrometheusMetricsProvider.java +++ b/bookkeeper-stats-providers/prometheus-metrics-provider/src/test/java/org/apache/bookkeeper/stats/prometheus/TestPrometheusMetricsProvider.java @@ -21,8 +21,9 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import java.io.StringWriter; -import java.nio.ByteBuffer; import java.util.Collections; import java.util.HashMap; @@ -122,7 +123,7 @@ public class TestPrometheusMetricsProvider { config.setProperty(PrometheusMetricsProvider.PROMETHEUS_STATS_HTTP_ENABLE, true); config.setProperty(PrometheusMetricsProvider.PROMETHEUS_STATS_HTTP_PORT, 0); config.setProperty(PrometheusMetricsProvider.PROMETHEUS_STATS_HTTP_ADDRESS, "127.0.0.1"); - ByteBuffer byteBuffer = ByteBuffer.allocateDirect(25); + ByteBuf byteBuf = ByteBufAllocator.DEFAULT.directBuffer(25); PrometheusMetricsProvider provider = new PrometheusMetricsProvider(); try { provider.start(config); @@ -145,7 +146,7 @@ public class TestPrometheusMetricsProvider { Assert.assertNotEquals("Nan", directBytesUsed); Assert.assertTrue(Double.parseDouble(directBytesUsed) > 25); // ensure byteBuffer doesn't gc - byteBuffer.clear(); + byteBuf.release(); } finally { provider.stop(); }
