You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bookkeeper.apache.org by ch...@apache.org on 2022/12/08 14:38:18 UTC

[bookkeeper] 01/08: Make `jvm_memory_direct_bytes_used` metrics compatible with jdk8. (#3677)

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

chenhang pushed a commit to branch branch-4.14
in repository https://gitbox.apache.org/repos/asf/bookkeeper.git

commit f73c7a1ee26d6875925afa639c433aa5f2430e54
Author: Yan Zhao <ho...@apache.org>
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      | 31 +++++++++++++++++++---
 .../prometheus/TestPrometheusMetricsProvider.java  |  7 ++---
 3 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/bookkeeper-stats-providers/prometheus-metrics-provider/pom.xml b/bookkeeper-stats-providers/prometheus-metrics-provider/pom.xml
index a7bae81bca..e8da4cdf54 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 74895084ea..f80fee92f7 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.commons.configuration.Configuration;
@@ -204,14 +207,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();
         }