github-actions[bot] commented on code in PR #35023:
URL: https://github.com/apache/doris/pull/35023#discussion_r1604799241


##########
be/src/util/doris_metrics.h:
##########
@@ -17,11 +17,14 @@
 
 #pragma once
 
+#include <jni.h>

Review Comment:
   warning: 'jni.h' file not found [clang-diagnostic-error]
   ```cpp
   #include <jni.h>
            ^
   ```
   



##########
be/src/util/jvm_metrics.cpp:
##########
@@ -0,0 +1,423 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "jvm_metrics.h"
+
+#include <functional>
+
+#include "util/metrics.h"
+
+namespace doris {
+
+#define DEFINE_JVM_SIZE_BYTES_METRIC(name, type)                               
      \
+    DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(name##_##type, MetricUnit::BYTES, "", 
name, \
+                                         Labels({{"type", #type}}));
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, max);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, committed);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, used);
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_non_heap_size_bytes, used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_non_heap_size_bytes, committed);
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, peak_used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, max);
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, peak_used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, max);
+
+#define DEFINE_JVM_THREAD_METRIC(type)                                         
                 \
+    DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_thread_##type, 
MetricUnit::NOUNIT, "", jvm_thread, \
+                                         Labels({{"type", #type}}));
+
+DEFINE_JVM_THREAD_METRIC(count);
+DEFINE_JVM_THREAD_METRIC(peak_count);
+DEFINE_JVM_THREAD_METRIC(new_count);
+DEFINE_JVM_THREAD_METRIC(runnable_count);
+DEFINE_JVM_THREAD_METRIC(blocked_count);
+DEFINE_JVM_THREAD_METRIC(waiting_count);
+DEFINE_JVM_THREAD_METRIC(timed_waiting_count);
+DEFINE_JVM_THREAD_METRIC(terminated_count);
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_young_generation_count, 
MetricUnit::NOUNIT, "",
+                                     jvm_gc,
+                                     Labels({{"name", "G1 Young generation 
Count"},
+                                             {"type", "count"}}));
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_young_generation_time_ms, 
MetricUnit::MILLISECONDS,
+                                     "", jvm_gc,
+                                     Labels({{"name", "G1 Young generation 
Time"},
+                                             {"type", "time"}}));
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_old_generation_count, 
MetricUnit::NOUNIT, "", jvm_gc,
+                                     Labels({{"name", "G1 Old generation 
Count"},
+                                             {"type", "count"}}));
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_old_generation_time_ms, 
MetricUnit::MILLISECONDS, "",
+                                     jvm_gc,
+                                     Labels({{"name", "G1 Old generation 
Time"},
+                                             {"type", "time"}}));
+
+const char* JvmMetrics::_s_hook_name = "jvm_metrics";
+
+JvmMetrics::JvmMetrics(MetricRegistry* registry, JNIEnv* env) : 
_jvm_stats(env) {
+    DCHECK(registry != nullptr);
+    _registry = registry;
+
+    _server_entity = _registry->register_entity("server");
+    DCHECK(_server_entity != nullptr);
+    if (_jvm_stats.init_complete()) {
+        _server_entity->register_hook(_s_hook_name, 
std::bind(&JvmMetrics::update, this));
+    }
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_max);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_committed);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_used);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_non_heap_size_bytes_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_non_heap_size_bytes_committed);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_peak_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_max);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_peak_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_max);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_peak_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_new_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_runnable_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_blocked_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_waiting_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_timed_waiting_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_terminated_count);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_gc_g1_young_generation_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_gc_g1_young_generation_time_ms);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_gc_g1_old_generation_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_gc_g1_old_generation_time_ms);
+}
+
+void JvmMetrics::update() {
+    _jvm_stats.refresh(this);
+}
+#include <util/jni-util.h>
+
+jvmStats::jvmStats(JNIEnv* ENV) : env(ENV) {
+    _managementFactoryClass = 
env->FindClass("java/lang/management/ManagementFactory");
+    if (_managementFactoryClass == nullptr) {
+        LOG(WARNING)
+                << "Class java/lang/management/ManagementFactory Not Find.JVM 
monitoring fails.";
+        return;
+    }
+
+    _getMemoryMXBeanMethod = env->GetStaticMethodID(_managementFactoryClass, 
"getMemoryMXBean",
+                                                    
"()Ljava/lang/management/MemoryMXBean;");
+
+    _memoryUsageClass = env->FindClass("java/lang/management/MemoryUsage");
+    if (_memoryUsageClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/MemoryUsage Not Find.JVM 
monitoring fails.";
+        return;
+    }
+    _getMemoryUsageUsedMethod = env->GetMethodID(_memoryUsageClass, "getUsed", 
"()J");
+    _getMemoryUsageCommittedMethod = env->GetMethodID(_memoryUsageClass, 
"getCommitted", "()J");
+    _getMemoryUsageMaxMethod = env->GetMethodID(_memoryUsageClass, "getMax", 
"()J");
+
+    _memoryMXBeanClass = env->FindClass("java/lang/management/MemoryMXBean");
+    if (_memoryMXBeanClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/MemoryMXBean Not Find.JVM 
monitoring fails.";
+        return;
+    }
+    _getHeapMemoryUsageMethod = env->GetMethodID(_memoryMXBeanClass, 
"getHeapMemoryUsage",
+                                                 
"()Ljava/lang/management/MemoryUsage;");
+    _getNonHeapMemoryUsageMethod = env->GetMethodID(_memoryMXBeanClass, 
"getNonHeapMemoryUsage",
+                                                    
"()Ljava/lang/management/MemoryUsage;");
+
+    _getMemoryPoolMXBeansMethod = env->GetStaticMethodID(
+            _managementFactoryClass, "getMemoryPoolMXBeans", 
"()Ljava/util/List;");
+
+    _listClass = env->FindClass("java/util/List");
+    if (_listClass == nullptr) {
+        LOG(WARNING) << "Class java/util/List Not Find.JVM monitoring fails.";
+        return;
+    }
+    _getListSizeMethod = env->GetMethodID(_listClass, "size", "()I");
+    _getListUseIndexMethod = env->GetMethodID(_listClass, "get", 
"(I)Ljava/lang/Object;");
+
+    _memoryPoolMXBeanClass = 
env->FindClass("java/lang/management/MemoryPoolMXBean");
+    if (_memoryPoolMXBeanClass == nullptr) {
+        LOG(WARNING)
+                << "Class java/lang/management/MemoryPoolMXBean Not Find.JVM 
monitoring fails.";
+        return;
+    }
+    _getMemoryPoolMXBeanUsageMethod = env->GetMethodID(_memoryPoolMXBeanClass, 
"getUsage",
+                                                       
"()Ljava/lang/management/MemoryUsage;");
+    _getMemoryPollMXBeanPeakMethod = env->GetMethodID(_memoryPoolMXBeanClass, 
"getPeakUsage",
+                                                      
"()Ljava/lang/management/MemoryUsage;");
+    _getMemoryPollMXBeanNameMethod =
+            env->GetMethodID(_memoryPoolMXBeanClass, "getName", 
"()Ljava/lang/String;");
+
+    _getThreadMXBeanMethod = env->GetStaticMethodID(_managementFactoryClass, 
"getThreadMXBean",
+                                                    
"()Ljava/lang/management/ThreadMXBean;");
+
+    _getGarbageCollectorMXBeansMethod = env->GetStaticMethodID(
+            _managementFactoryClass, "getGarbageCollectorMXBeans", 
"()Ljava/util/List;");
+
+    _garbageCollectorMXBeanClass = 
env->FindClass("java/lang/management/GarbageCollectorMXBean");
+    if (_garbageCollectorMXBeanClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/GarbageCollectorMXBean Not 
Find.JVM monitoring "
+                        "fails.";
+        return;
+    }
+    _getGCNameMethod =
+            env->GetMethodID(_garbageCollectorMXBeanClass, "getName", 
"()Ljava/lang/String;");
+    _getGCCollectionCountMethod =
+            env->GetMethodID(_garbageCollectorMXBeanClass, 
"getCollectionCount", "()J");
+    _getGCCollectionTimeMethod =
+            env->GetMethodID(_garbageCollectorMXBeanClass, 
"getCollectionTime", "()J");
+
+    _threadMXBeanClass = env->FindClass("java/lang/management/ThreadMXBean");
+    if (_threadMXBeanClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/ThreadMXBean Not Find.JVM 
monitoring fails.";
+        return;
+    }
+    _getAllThreadIdsMethod = env->GetMethodID(_threadMXBeanClass, 
"getAllThreadIds", "()[J");
+    _getThreadInfoMethod = env->GetMethodID(_threadMXBeanClass, 
"getThreadInfo",
+                                            
"([JI)[Ljava/lang/management/ThreadInfo;");
+    _getPeakThreadCountMethod = env->GetMethodID(_threadMXBeanClass, 
"getPeakThreadCount", "()I");
+
+    _threadInfoClass = env->FindClass("java/lang/management/ThreadInfo");
+    if (_threadInfoClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/ThreadInfo Not Find.JVM 
monitoring fails.";
+        return;
+    }
+
+    _getThreadStateMethod =
+            env->GetMethodID(_threadInfoClass, "getThreadState", 
"()Ljava/lang/Thread$State;");
+
+    _threadStateClass = env->FindClass("java/lang/Thread$State");
+    if (_threadStateClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/Thread$State Not Find.JVM monitoring 
fails.";
+        return;
+    }
+
+    jfieldID newThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "NEW", 
"Ljava/lang/Thread$State;");
+    jfieldID runnableThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "RUNNABLE", 
"Ljava/lang/Thread$State;");
+    jfieldID blockedThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "BLOCKED", 
"Ljava/lang/Thread$State;");
+    jfieldID waitingThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "WAITING", 
"Ljava/lang/Thread$State;");
+    jfieldID timedWaitingThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "TIMED_WAITING", 
"Ljava/lang/Thread$State;");
+    jfieldID terminatedThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "TERMINATED", 
"Ljava/lang/Thread$State;");
+
+    _newThreadStateObj = env->GetStaticObjectField(_threadStateClass, 
newThreadFieldID);
+    _runnableThreadStateObj = env->GetStaticObjectField(_threadStateClass, 
runnableThreadFieldID);
+    _blockedThreadStateObj = env->GetStaticObjectField(_threadStateClass, 
blockedThreadFieldID);
+    _waitingThreadStateObj = env->GetStaticObjectField(_threadStateClass, 
waitingThreadFieldID);
+    _timedWaitingThreadStateObj =
+            env->GetStaticObjectField(_threadStateClass, 
timedWaitingThreadFieldID);
+    _terminatedThreadStateObj =
+            env->GetStaticObjectField(_threadStateClass, 
terminatedThreadFieldID);
+
+    LOG(INFO) << "Start JVM monitoring.";
+
+    _init_complete = true;
+}
+
+#include "jni.h"
+
+void jvmStats::refresh(JvmMetrics* jvm_metrics) {

Review Comment:
   warning: function 'refresh' exceeds recommended size/complexity thresholds 
[readability-function-size]
   ```cpp
   void jvmStats::refresh(JvmMetrics* jvm_metrics) {
                  ^
   ```
   <details>
   <summary>Additional context</summary>
   
   **be/src/util/jvm_metrics.cpp:250:** 159 lines including whitespace and 
comments (threshold 80)
   ```cpp
   void jvmStats::refresh(JvmMetrics* jvm_metrics) {
                  ^
   ```
   
   </details>
   



##########
be/src/util/jvm_metrics.cpp:
##########
@@ -0,0 +1,423 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "jvm_metrics.h"
+
+#include <functional>
+
+#include "util/metrics.h"
+
+namespace doris {
+
+#define DEFINE_JVM_SIZE_BYTES_METRIC(name, type)                               
      \
+    DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(name##_##type, MetricUnit::BYTES, "", 
name, \
+                                         Labels({{"type", #type}}));
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, max);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, committed);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, used);
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_non_heap_size_bytes, used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_non_heap_size_bytes, committed);
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, peak_used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, max);
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, peak_used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, max);
+
+#define DEFINE_JVM_THREAD_METRIC(type)                                         
                 \
+    DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_thread_##type, 
MetricUnit::NOUNIT, "", jvm_thread, \
+                                         Labels({{"type", #type}}));
+
+DEFINE_JVM_THREAD_METRIC(count);
+DEFINE_JVM_THREAD_METRIC(peak_count);
+DEFINE_JVM_THREAD_METRIC(new_count);
+DEFINE_JVM_THREAD_METRIC(runnable_count);
+DEFINE_JVM_THREAD_METRIC(blocked_count);
+DEFINE_JVM_THREAD_METRIC(waiting_count);
+DEFINE_JVM_THREAD_METRIC(timed_waiting_count);
+DEFINE_JVM_THREAD_METRIC(terminated_count);
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_young_generation_count, 
MetricUnit::NOUNIT, "",
+                                     jvm_gc,
+                                     Labels({{"name", "G1 Young generation 
Count"},
+                                             {"type", "count"}}));
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_young_generation_time_ms, 
MetricUnit::MILLISECONDS,
+                                     "", jvm_gc,
+                                     Labels({{"name", "G1 Young generation 
Time"},
+                                             {"type", "time"}}));
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_old_generation_count, 
MetricUnit::NOUNIT, "", jvm_gc,
+                                     Labels({{"name", "G1 Old generation 
Count"},
+                                             {"type", "count"}}));
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_old_generation_time_ms, 
MetricUnit::MILLISECONDS, "",
+                                     jvm_gc,
+                                     Labels({{"name", "G1 Old generation 
Time"},
+                                             {"type", "time"}}));
+
+const char* JvmMetrics::_s_hook_name = "jvm_metrics";
+
+JvmMetrics::JvmMetrics(MetricRegistry* registry, JNIEnv* env) : 
_jvm_stats(env) {
+    DCHECK(registry != nullptr);
+    _registry = registry;
+
+    _server_entity = _registry->register_entity("server");
+    DCHECK(_server_entity != nullptr);
+    if (_jvm_stats.init_complete()) {
+        _server_entity->register_hook(_s_hook_name, 
std::bind(&JvmMetrics::update, this));
+    }
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_max);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_committed);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_used);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_non_heap_size_bytes_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_non_heap_size_bytes_committed);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_peak_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_max);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_peak_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_max);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_peak_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_new_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_runnable_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_blocked_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_waiting_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_timed_waiting_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_terminated_count);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_gc_g1_young_generation_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_gc_g1_young_generation_time_ms);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_gc_g1_old_generation_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_gc_g1_old_generation_time_ms);
+}
+
+void JvmMetrics::update() {
+    _jvm_stats.refresh(this);
+}
+#include <util/jni-util.h>
+
+jvmStats::jvmStats(JNIEnv* ENV) : env(ENV) {
+    _managementFactoryClass = 
env->FindClass("java/lang/management/ManagementFactory");
+    if (_managementFactoryClass == nullptr) {
+        LOG(WARNING)
+                << "Class java/lang/management/ManagementFactory Not Find.JVM 
monitoring fails.";
+        return;
+    }
+
+    _getMemoryMXBeanMethod = env->GetStaticMethodID(_managementFactoryClass, 
"getMemoryMXBean",
+                                                    
"()Ljava/lang/management/MemoryMXBean;");
+
+    _memoryUsageClass = env->FindClass("java/lang/management/MemoryUsage");
+    if (_memoryUsageClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/MemoryUsage Not Find.JVM 
monitoring fails.";
+        return;
+    }
+    _getMemoryUsageUsedMethod = env->GetMethodID(_memoryUsageClass, "getUsed", 
"()J");
+    _getMemoryUsageCommittedMethod = env->GetMethodID(_memoryUsageClass, 
"getCommitted", "()J");
+    _getMemoryUsageMaxMethod = env->GetMethodID(_memoryUsageClass, "getMax", 
"()J");
+
+    _memoryMXBeanClass = env->FindClass("java/lang/management/MemoryMXBean");
+    if (_memoryMXBeanClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/MemoryMXBean Not Find.JVM 
monitoring fails.";
+        return;
+    }
+    _getHeapMemoryUsageMethod = env->GetMethodID(_memoryMXBeanClass, 
"getHeapMemoryUsage",
+                                                 
"()Ljava/lang/management/MemoryUsage;");
+    _getNonHeapMemoryUsageMethod = env->GetMethodID(_memoryMXBeanClass, 
"getNonHeapMemoryUsage",
+                                                    
"()Ljava/lang/management/MemoryUsage;");
+
+    _getMemoryPoolMXBeansMethod = env->GetStaticMethodID(
+            _managementFactoryClass, "getMemoryPoolMXBeans", 
"()Ljava/util/List;");
+
+    _listClass = env->FindClass("java/util/List");
+    if (_listClass == nullptr) {
+        LOG(WARNING) << "Class java/util/List Not Find.JVM monitoring fails.";
+        return;
+    }
+    _getListSizeMethod = env->GetMethodID(_listClass, "size", "()I");
+    _getListUseIndexMethod = env->GetMethodID(_listClass, "get", 
"(I)Ljava/lang/Object;");
+
+    _memoryPoolMXBeanClass = 
env->FindClass("java/lang/management/MemoryPoolMXBean");
+    if (_memoryPoolMXBeanClass == nullptr) {
+        LOG(WARNING)
+                << "Class java/lang/management/MemoryPoolMXBean Not Find.JVM 
monitoring fails.";
+        return;
+    }
+    _getMemoryPoolMXBeanUsageMethod = env->GetMethodID(_memoryPoolMXBeanClass, 
"getUsage",
+                                                       
"()Ljava/lang/management/MemoryUsage;");
+    _getMemoryPollMXBeanPeakMethod = env->GetMethodID(_memoryPoolMXBeanClass, 
"getPeakUsage",
+                                                      
"()Ljava/lang/management/MemoryUsage;");
+    _getMemoryPollMXBeanNameMethod =
+            env->GetMethodID(_memoryPoolMXBeanClass, "getName", 
"()Ljava/lang/String;");
+
+    _getThreadMXBeanMethod = env->GetStaticMethodID(_managementFactoryClass, 
"getThreadMXBean",
+                                                    
"()Ljava/lang/management/ThreadMXBean;");
+
+    _getGarbageCollectorMXBeansMethod = env->GetStaticMethodID(
+            _managementFactoryClass, "getGarbageCollectorMXBeans", 
"()Ljava/util/List;");
+
+    _garbageCollectorMXBeanClass = 
env->FindClass("java/lang/management/GarbageCollectorMXBean");
+    if (_garbageCollectorMXBeanClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/GarbageCollectorMXBean Not 
Find.JVM monitoring "
+                        "fails.";
+        return;
+    }
+    _getGCNameMethod =
+            env->GetMethodID(_garbageCollectorMXBeanClass, "getName", 
"()Ljava/lang/String;");
+    _getGCCollectionCountMethod =
+            env->GetMethodID(_garbageCollectorMXBeanClass, 
"getCollectionCount", "()J");
+    _getGCCollectionTimeMethod =
+            env->GetMethodID(_garbageCollectorMXBeanClass, 
"getCollectionTime", "()J");
+
+    _threadMXBeanClass = env->FindClass("java/lang/management/ThreadMXBean");
+    if (_threadMXBeanClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/ThreadMXBean Not Find.JVM 
monitoring fails.";
+        return;
+    }
+    _getAllThreadIdsMethod = env->GetMethodID(_threadMXBeanClass, 
"getAllThreadIds", "()[J");
+    _getThreadInfoMethod = env->GetMethodID(_threadMXBeanClass, 
"getThreadInfo",
+                                            
"([JI)[Ljava/lang/management/ThreadInfo;");
+    _getPeakThreadCountMethod = env->GetMethodID(_threadMXBeanClass, 
"getPeakThreadCount", "()I");
+
+    _threadInfoClass = env->FindClass("java/lang/management/ThreadInfo");
+    if (_threadInfoClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/ThreadInfo Not Find.JVM 
monitoring fails.";
+        return;
+    }
+
+    _getThreadStateMethod =
+            env->GetMethodID(_threadInfoClass, "getThreadState", 
"()Ljava/lang/Thread$State;");
+
+    _threadStateClass = env->FindClass("java/lang/Thread$State");
+    if (_threadStateClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/Thread$State Not Find.JVM monitoring 
fails.";
+        return;
+    }
+
+    jfieldID newThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "NEW", 
"Ljava/lang/Thread$State;");
+    jfieldID runnableThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "RUNNABLE", 
"Ljava/lang/Thread$State;");
+    jfieldID blockedThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "BLOCKED", 
"Ljava/lang/Thread$State;");
+    jfieldID waitingThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "WAITING", 
"Ljava/lang/Thread$State;");
+    jfieldID timedWaitingThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "TIMED_WAITING", 
"Ljava/lang/Thread$State;");
+    jfieldID terminatedThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "TERMINATED", 
"Ljava/lang/Thread$State;");
+
+    _newThreadStateObj = env->GetStaticObjectField(_threadStateClass, 
newThreadFieldID);
+    _runnableThreadStateObj = env->GetStaticObjectField(_threadStateClass, 
runnableThreadFieldID);
+    _blockedThreadStateObj = env->GetStaticObjectField(_threadStateClass, 
blockedThreadFieldID);
+    _waitingThreadStateObj = env->GetStaticObjectField(_threadStateClass, 
waitingThreadFieldID);
+    _timedWaitingThreadStateObj =
+            env->GetStaticObjectField(_threadStateClass, 
timedWaitingThreadFieldID);
+    _terminatedThreadStateObj =
+            env->GetStaticObjectField(_threadStateClass, 
terminatedThreadFieldID);
+
+    LOG(INFO) << "Start JVM monitoring.";
+
+    _init_complete = true;
+}
+
+#include "jni.h"
+
+void jvmStats::refresh(JvmMetrics* jvm_metrics) {
+    if (!_init_complete) {
+        return;
+    }
+    static_cast<void>(JniUtil::GetJNIEnv(&env));
+
+    jobject memoryMXBeanObj =
+            env->CallStaticObjectMethod(_managementFactoryClass, 
_getMemoryMXBeanMethod);
+
+    jobject heapMemoryUsageObj = env->CallObjectMethod(memoryMXBeanObj, 
_getHeapMemoryUsageMethod);
+
+    jlong heapMemoryUsed = env->CallLongMethod(heapMemoryUsageObj, 
_getMemoryUsageUsedMethod);
+    jlong heapMemoryCommitted =
+            env->CallLongMethod(heapMemoryUsageObj, 
_getMemoryUsageCommittedMethod);
+    jlong heapMemoryMax = env->CallLongMethod(heapMemoryUsageObj, 
_getMemoryUsageMaxMethod);
+
+    jvm_metrics->jvm_heap_size_bytes_used->set_value(heapMemoryUsed < 0 ? 0 : 
heapMemoryUsed);
+    jvm_metrics->jvm_heap_size_bytes_committed->set_value(
+            heapMemoryCommitted < 0 ? 0 : heapMemoryCommitted);
+    jvm_metrics->jvm_heap_size_bytes_max->set_value(heapMemoryMax < 0 ? 0 : 
heapMemoryMax);
+
+    jobject nonHeapMemoryUsageObj =
+            env->CallObjectMethod(memoryMXBeanObj, 
_getNonHeapMemoryUsageMethod);
+
+    jlong nonHeapMemoryCommitted =
+            env->CallLongMethod(nonHeapMemoryUsageObj, 
_getMemoryUsageCommittedMethod);
+    jlong nonHeapMemoryUsed = env->CallLongMethod(nonHeapMemoryUsageObj, 
_getMemoryUsageUsedMethod);
+
+    jvm_metrics->jvm_non_heap_size_bytes_committed->set_value(
+            nonHeapMemoryCommitted < 0 ? 0 : nonHeapMemoryCommitted);
+    jvm_metrics->jvm_non_heap_size_bytes_used->set_value(nonHeapMemoryUsed < 0 
? 0
+                                                                               
: nonHeapMemoryUsed);
+
+    jobject memoryPoolMXBeansList =
+            env->CallStaticObjectMethod(_managementFactoryClass, 
_getMemoryPoolMXBeansMethod);
+
+    jint size = env->CallIntMethod(memoryPoolMXBeansList, _getListSizeMethod);
+
+    for (int i = 0; i < size; ++i) {
+        jobject memoryPoolMXBean =
+                env->CallObjectMethod(memoryPoolMXBeansList, 
_getListUseIndexMethod, i);
+        jobject usageObject =
+                env->CallObjectMethod(memoryPoolMXBean, 
_getMemoryPoolMXBeanUsageMethod);
+
+        jlong used = env->CallLongMethod(usageObject, 
_getMemoryUsageUsedMethod);
+        jlong max = env->CallLongMethod(usageObject, _getMemoryUsageMaxMethod);
+
+        jobject peakUsageObject =
+                env->CallObjectMethod(memoryPoolMXBean, 
_getMemoryPollMXBeanPeakMethod);
+
+        jlong peakUsed = env->CallLongMethod(peakUsageObject, 
_getMemoryUsageUsedMethod);
+
+        jstring name =
+                (jstring)env->CallObjectMethod(memoryPoolMXBean, 
_getMemoryPollMXBeanNameMethod);
+        const char* nameStr = env->GetStringUTFChars(name, NULL);
+        if (nameStr != NULL) {

Review Comment:
   warning: use nullptr [modernize-use-nullptr]
   
   ```suggestion
           if (nameStr != nullptr) {
   ```
   



##########
be/src/util/jvm_metrics.cpp:
##########
@@ -0,0 +1,423 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "jvm_metrics.h"
+
+#include <functional>
+
+#include "util/metrics.h"
+
+namespace doris {
+
+#define DEFINE_JVM_SIZE_BYTES_METRIC(name, type)                               
      \
+    DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(name##_##type, MetricUnit::BYTES, "", 
name, \
+                                         Labels({{"type", #type}}));
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, max);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, committed);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, used);
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_non_heap_size_bytes, used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_non_heap_size_bytes, committed);
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, peak_used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, max);
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, peak_used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, max);
+
+#define DEFINE_JVM_THREAD_METRIC(type)                                         
                 \
+    DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_thread_##type, 
MetricUnit::NOUNIT, "", jvm_thread, \
+                                         Labels({{"type", #type}}));
+
+DEFINE_JVM_THREAD_METRIC(count);
+DEFINE_JVM_THREAD_METRIC(peak_count);
+DEFINE_JVM_THREAD_METRIC(new_count);
+DEFINE_JVM_THREAD_METRIC(runnable_count);
+DEFINE_JVM_THREAD_METRIC(blocked_count);
+DEFINE_JVM_THREAD_METRIC(waiting_count);
+DEFINE_JVM_THREAD_METRIC(timed_waiting_count);
+DEFINE_JVM_THREAD_METRIC(terminated_count);
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_young_generation_count, 
MetricUnit::NOUNIT, "",
+                                     jvm_gc,
+                                     Labels({{"name", "G1 Young generation 
Count"},
+                                             {"type", "count"}}));
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_young_generation_time_ms, 
MetricUnit::MILLISECONDS,
+                                     "", jvm_gc,
+                                     Labels({{"name", "G1 Young generation 
Time"},
+                                             {"type", "time"}}));
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_old_generation_count, 
MetricUnit::NOUNIT, "", jvm_gc,
+                                     Labels({{"name", "G1 Old generation 
Count"},
+                                             {"type", "count"}}));
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_old_generation_time_ms, 
MetricUnit::MILLISECONDS, "",
+                                     jvm_gc,
+                                     Labels({{"name", "G1 Old generation 
Time"},
+                                             {"type", "time"}}));
+
+const char* JvmMetrics::_s_hook_name = "jvm_metrics";
+
+JvmMetrics::JvmMetrics(MetricRegistry* registry, JNIEnv* env) : 
_jvm_stats(env) {
+    DCHECK(registry != nullptr);
+    _registry = registry;
+
+    _server_entity = _registry->register_entity("server");
+    DCHECK(_server_entity != nullptr);
+    if (_jvm_stats.init_complete()) {
+        _server_entity->register_hook(_s_hook_name, 
std::bind(&JvmMetrics::update, this));
+    }
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_max);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_committed);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_used);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_non_heap_size_bytes_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_non_heap_size_bytes_committed);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_peak_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_max);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_peak_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_max);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_peak_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_new_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_runnable_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_blocked_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_waiting_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_timed_waiting_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_terminated_count);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_gc_g1_young_generation_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_gc_g1_young_generation_time_ms);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_gc_g1_old_generation_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_gc_g1_old_generation_time_ms);
+}
+
+void JvmMetrics::update() {
+    _jvm_stats.refresh(this);
+}
+#include <util/jni-util.h>
+
+jvmStats::jvmStats(JNIEnv* ENV) : env(ENV) {

Review Comment:
   warning: function 'jvmStats' exceeds recommended size/complexity thresholds 
[readability-function-size]
   ```cpp
   jvmStats::jvmStats(JNIEnv* ENV) : env(ENV) {
             ^
   ```
   <details>
   <summary>Additional context</summary>
   
   **be/src/util/jvm_metrics.cpp:123:** 123 lines including whitespace and 
comments (threshold 80)
   ```cpp
   jvmStats::jvmStats(JNIEnv* ENV) : env(ENV) {
             ^
   ```
   
   </details>
   



##########
be/src/util/jvm_metrics.h:
##########
@@ -0,0 +1,149 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+#include <jni.h>

Review Comment:
   warning: 'jni.h' file not found [clang-diagnostic-error]
   ```cpp
   #include <jni.h>
            ^
   ```
   



##########
be/src/util/jvm_metrics.h:
##########
@@ -0,0 +1,149 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+#include <jni.h>
+
+#include "jni.h"
+#include "util/jni-util.h"
+#include "util/metrics.h"
+
+namespace doris {
+
+class JvmMetrics;
+
+class jvmStats {
+private:
+    JNIEnv* env = nullptr;
+    jclass _managementFactoryClass = nullptr;
+    jmethodID _getMemoryMXBeanMethod = nullptr;
+    jclass _memoryUsageClass = nullptr;
+    jclass _memoryMXBeanClass = nullptr;
+    jmethodID _getHeapMemoryUsageMethod = nullptr;
+    jmethodID _getNonHeapMemoryUsageMethod = nullptr;
+    jmethodID _getMemoryUsageUsedMethod = nullptr;
+    jmethodID _getMemoryUsageCommittedMethod = nullptr;
+    jmethodID _getMemoryUsageMaxMethod = nullptr;
+
+    jmethodID _getMemoryPoolMXBeansMethod = nullptr;
+
+    jclass _listClass = nullptr;
+    jmethodID _getListSizeMethod = nullptr;
+    jmethodID _getListUseIndexMethod = nullptr;
+
+    jclass _memoryPoolMXBeanClass = nullptr;
+    jmethodID _getMemoryPoolMXBeanUsageMethod = nullptr;
+
+    jmethodID _getMemoryPollMXBeanPeakMethod = nullptr;
+    jmethodID _getMemoryPollMXBeanNameMethod = nullptr;
+
+    enum memoryPoolNameEnum { YOUNG, SURVIVOR, OLD };
+    const std::map<std::string, memoryPoolNameEnum> _memoryPoolName = {
+            {"Eden Space", YOUNG},
+            {"PS Eden Space", YOUNG},
+            {"Par Eden Space", YOUNG},
+            {"G1 Eden Space", YOUNG},
+
+            {"Survivor Space", SURVIVOR},
+            {"PS Survivor Space", SURVIVOR},
+            {"Par Survivor Space", SURVIVOR},
+            {"G1 Survivor Space", SURVIVOR},
+
+            {"Tenured Gen", OLD},
+            {"PS Old Gen", OLD},
+            {"CMS Old Gen", OLD},
+            {"G1 Old Gen", OLD},
+
+    };
+
+    jmethodID _getThreadMXBeanMethod = nullptr;
+    jclass _threadMXBeanClass = nullptr;
+    jmethodID _getAllThreadIdsMethod = nullptr;
+    jmethodID _getThreadInfoMethod = nullptr;
+    jclass _threadInfoClass = nullptr;
+
+    jmethodID _getPeakThreadCountMethod = nullptr;
+
+    jmethodID _getThreadStateMethod = nullptr;
+    jclass _threadStateClass = nullptr;
+
+    jobject _newThreadStateObj = nullptr;
+    jobject _runnableThreadStateObj = nullptr;
+    jobject _blockedThreadStateObj = nullptr;
+    jobject _waitingThreadStateObj = nullptr;
+    jobject _timedWaitingThreadStateObj = nullptr;
+    jobject _terminatedThreadStateObj = nullptr;
+
+    jclass _garbageCollectorMXBeanClass = nullptr;
+    jmethodID _getGCNameMethod = nullptr;
+    jmethodID _getGarbageCollectorMXBeansMethod = nullptr;
+    jmethodID _getGCCollectionCountMethod = nullptr;
+    jmethodID _getGCCollectionTimeMethod = nullptr;
+
+    bool _init_complete = false;
+
+public:
+    jvmStats(JNIEnv* ENV);
+    bool init_complete() { return _init_complete; }

Review Comment:
   warning: method 'init_complete' can be made const 
[readability-make-member-function-const]
   
   ```suggestion
       bool init_complete() const { return _init_complete; }
   ```
   



##########
be/src/util/jvm_metrics.h:
##########
@@ -0,0 +1,149 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+#include <jni.h>
+
+#include "jni.h"
+#include "util/jni-util.h"
+#include "util/metrics.h"
+
+namespace doris {
+
+class JvmMetrics;
+
+class jvmStats {
+private:
+    JNIEnv* env = nullptr;
+    jclass _managementFactoryClass = nullptr;
+    jmethodID _getMemoryMXBeanMethod = nullptr;
+    jclass _memoryUsageClass = nullptr;
+    jclass _memoryMXBeanClass = nullptr;
+    jmethodID _getHeapMemoryUsageMethod = nullptr;
+    jmethodID _getNonHeapMemoryUsageMethod = nullptr;
+    jmethodID _getMemoryUsageUsedMethod = nullptr;
+    jmethodID _getMemoryUsageCommittedMethod = nullptr;
+    jmethodID _getMemoryUsageMaxMethod = nullptr;
+
+    jmethodID _getMemoryPoolMXBeansMethod = nullptr;
+
+    jclass _listClass = nullptr;
+    jmethodID _getListSizeMethod = nullptr;
+    jmethodID _getListUseIndexMethod = nullptr;
+
+    jclass _memoryPoolMXBeanClass = nullptr;
+    jmethodID _getMemoryPoolMXBeanUsageMethod = nullptr;
+
+    jmethodID _getMemoryPollMXBeanPeakMethod = nullptr;
+    jmethodID _getMemoryPollMXBeanNameMethod = nullptr;
+
+    enum memoryPoolNameEnum { YOUNG, SURVIVOR, OLD };
+    const std::map<std::string, memoryPoolNameEnum> _memoryPoolName = {
+            {"Eden Space", YOUNG},
+            {"PS Eden Space", YOUNG},
+            {"Par Eden Space", YOUNG},
+            {"G1 Eden Space", YOUNG},
+
+            {"Survivor Space", SURVIVOR},
+            {"PS Survivor Space", SURVIVOR},
+            {"Par Survivor Space", SURVIVOR},
+            {"G1 Survivor Space", SURVIVOR},
+
+            {"Tenured Gen", OLD},
+            {"PS Old Gen", OLD},
+            {"CMS Old Gen", OLD},
+            {"G1 Old Gen", OLD},
+
+    };
+
+    jmethodID _getThreadMXBeanMethod = nullptr;
+    jclass _threadMXBeanClass = nullptr;
+    jmethodID _getAllThreadIdsMethod = nullptr;
+    jmethodID _getThreadInfoMethod = nullptr;
+    jclass _threadInfoClass = nullptr;
+
+    jmethodID _getPeakThreadCountMethod = nullptr;
+
+    jmethodID _getThreadStateMethod = nullptr;
+    jclass _threadStateClass = nullptr;
+
+    jobject _newThreadStateObj = nullptr;
+    jobject _runnableThreadStateObj = nullptr;
+    jobject _blockedThreadStateObj = nullptr;
+    jobject _waitingThreadStateObj = nullptr;
+    jobject _timedWaitingThreadStateObj = nullptr;
+    jobject _terminatedThreadStateObj = nullptr;
+
+    jclass _garbageCollectorMXBeanClass = nullptr;
+    jmethodID _getGCNameMethod = nullptr;
+    jmethodID _getGarbageCollectorMXBeansMethod = nullptr;
+    jmethodID _getGCCollectionCountMethod = nullptr;
+    jmethodID _getGCCollectionTimeMethod = nullptr;
+
+    bool _init_complete = false;
+
+public:
+    jvmStats(JNIEnv* ENV);
+    bool init_complete() { return _init_complete; }
+    void refresh(JvmMetrics* jvm_metrics);
+    ~jvmStats();
+};
+
+class JvmMetrics {
+public:
+    JvmMetrics(MetricRegistry* registry, JNIEnv* env);
+    ~JvmMetrics() {}

Review Comment:
   warning: use '= default' to define a trivial destructor 
[modernize-use-equals-default]
   
   ```suggestion
       ~JvmMetrics() = default;
   ```
   



##########
be/src/util/jvm_metrics.cpp:
##########
@@ -0,0 +1,423 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "jvm_metrics.h"
+
+#include <functional>
+
+#include "util/metrics.h"
+
+namespace doris {
+
+#define DEFINE_JVM_SIZE_BYTES_METRIC(name, type)                               
      \
+    DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(name##_##type, MetricUnit::BYTES, "", 
name, \
+                                         Labels({{"type", #type}}));
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, max);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, committed);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, used);
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_non_heap_size_bytes, used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_non_heap_size_bytes, committed);
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, peak_used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, max);
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, peak_used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, max);
+
+#define DEFINE_JVM_THREAD_METRIC(type)                                         
                 \
+    DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_thread_##type, 
MetricUnit::NOUNIT, "", jvm_thread, \
+                                         Labels({{"type", #type}}));
+
+DEFINE_JVM_THREAD_METRIC(count);
+DEFINE_JVM_THREAD_METRIC(peak_count);
+DEFINE_JVM_THREAD_METRIC(new_count);
+DEFINE_JVM_THREAD_METRIC(runnable_count);
+DEFINE_JVM_THREAD_METRIC(blocked_count);
+DEFINE_JVM_THREAD_METRIC(waiting_count);
+DEFINE_JVM_THREAD_METRIC(timed_waiting_count);
+DEFINE_JVM_THREAD_METRIC(terminated_count);
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_young_generation_count, 
MetricUnit::NOUNIT, "",
+                                     jvm_gc,
+                                     Labels({{"name", "G1 Young generation 
Count"},
+                                             {"type", "count"}}));
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_young_generation_time_ms, 
MetricUnit::MILLISECONDS,
+                                     "", jvm_gc,
+                                     Labels({{"name", "G1 Young generation 
Time"},
+                                             {"type", "time"}}));
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_old_generation_count, 
MetricUnit::NOUNIT, "", jvm_gc,
+                                     Labels({{"name", "G1 Old generation 
Count"},
+                                             {"type", "count"}}));
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_old_generation_time_ms, 
MetricUnit::MILLISECONDS, "",
+                                     jvm_gc,
+                                     Labels({{"name", "G1 Old generation 
Time"},
+                                             {"type", "time"}}));
+
+const char* JvmMetrics::_s_hook_name = "jvm_metrics";
+
+JvmMetrics::JvmMetrics(MetricRegistry* registry, JNIEnv* env) : 
_jvm_stats(env) {
+    DCHECK(registry != nullptr);
+    _registry = registry;
+
+    _server_entity = _registry->register_entity("server");
+    DCHECK(_server_entity != nullptr);
+    if (_jvm_stats.init_complete()) {
+        _server_entity->register_hook(_s_hook_name, 
std::bind(&JvmMetrics::update, this));
+    }
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_max);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_committed);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_used);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_non_heap_size_bytes_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_non_heap_size_bytes_committed);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_peak_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_max);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_peak_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_max);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_peak_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_new_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_runnable_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_blocked_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_waiting_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_timed_waiting_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_terminated_count);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_gc_g1_young_generation_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_gc_g1_young_generation_time_ms);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_gc_g1_old_generation_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_gc_g1_old_generation_time_ms);
+}
+
+void JvmMetrics::update() {
+    _jvm_stats.refresh(this);
+}
+#include <util/jni-util.h>
+
+jvmStats::jvmStats(JNIEnv* ENV) : env(ENV) {
+    _managementFactoryClass = 
env->FindClass("java/lang/management/ManagementFactory");
+    if (_managementFactoryClass == nullptr) {
+        LOG(WARNING)
+                << "Class java/lang/management/ManagementFactory Not Find.JVM 
monitoring fails.";
+        return;
+    }
+
+    _getMemoryMXBeanMethod = env->GetStaticMethodID(_managementFactoryClass, 
"getMemoryMXBean",
+                                                    
"()Ljava/lang/management/MemoryMXBean;");
+
+    _memoryUsageClass = env->FindClass("java/lang/management/MemoryUsage");
+    if (_memoryUsageClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/MemoryUsage Not Find.JVM 
monitoring fails.";
+        return;
+    }
+    _getMemoryUsageUsedMethod = env->GetMethodID(_memoryUsageClass, "getUsed", 
"()J");
+    _getMemoryUsageCommittedMethod = env->GetMethodID(_memoryUsageClass, 
"getCommitted", "()J");
+    _getMemoryUsageMaxMethod = env->GetMethodID(_memoryUsageClass, "getMax", 
"()J");
+
+    _memoryMXBeanClass = env->FindClass("java/lang/management/MemoryMXBean");
+    if (_memoryMXBeanClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/MemoryMXBean Not Find.JVM 
monitoring fails.";
+        return;
+    }
+    _getHeapMemoryUsageMethod = env->GetMethodID(_memoryMXBeanClass, 
"getHeapMemoryUsage",
+                                                 
"()Ljava/lang/management/MemoryUsage;");
+    _getNonHeapMemoryUsageMethod = env->GetMethodID(_memoryMXBeanClass, 
"getNonHeapMemoryUsage",
+                                                    
"()Ljava/lang/management/MemoryUsage;");
+
+    _getMemoryPoolMXBeansMethod = env->GetStaticMethodID(
+            _managementFactoryClass, "getMemoryPoolMXBeans", 
"()Ljava/util/List;");
+
+    _listClass = env->FindClass("java/util/List");
+    if (_listClass == nullptr) {
+        LOG(WARNING) << "Class java/util/List Not Find.JVM monitoring fails.";
+        return;
+    }
+    _getListSizeMethod = env->GetMethodID(_listClass, "size", "()I");
+    _getListUseIndexMethod = env->GetMethodID(_listClass, "get", 
"(I)Ljava/lang/Object;");
+
+    _memoryPoolMXBeanClass = 
env->FindClass("java/lang/management/MemoryPoolMXBean");
+    if (_memoryPoolMXBeanClass == nullptr) {
+        LOG(WARNING)
+                << "Class java/lang/management/MemoryPoolMXBean Not Find.JVM 
monitoring fails.";
+        return;
+    }
+    _getMemoryPoolMXBeanUsageMethod = env->GetMethodID(_memoryPoolMXBeanClass, 
"getUsage",
+                                                       
"()Ljava/lang/management/MemoryUsage;");
+    _getMemoryPollMXBeanPeakMethod = env->GetMethodID(_memoryPoolMXBeanClass, 
"getPeakUsage",
+                                                      
"()Ljava/lang/management/MemoryUsage;");
+    _getMemoryPollMXBeanNameMethod =
+            env->GetMethodID(_memoryPoolMXBeanClass, "getName", 
"()Ljava/lang/String;");
+
+    _getThreadMXBeanMethod = env->GetStaticMethodID(_managementFactoryClass, 
"getThreadMXBean",
+                                                    
"()Ljava/lang/management/ThreadMXBean;");
+
+    _getGarbageCollectorMXBeansMethod = env->GetStaticMethodID(
+            _managementFactoryClass, "getGarbageCollectorMXBeans", 
"()Ljava/util/List;");
+
+    _garbageCollectorMXBeanClass = 
env->FindClass("java/lang/management/GarbageCollectorMXBean");
+    if (_garbageCollectorMXBeanClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/GarbageCollectorMXBean Not 
Find.JVM monitoring "
+                        "fails.";
+        return;
+    }
+    _getGCNameMethod =
+            env->GetMethodID(_garbageCollectorMXBeanClass, "getName", 
"()Ljava/lang/String;");
+    _getGCCollectionCountMethod =
+            env->GetMethodID(_garbageCollectorMXBeanClass, 
"getCollectionCount", "()J");
+    _getGCCollectionTimeMethod =
+            env->GetMethodID(_garbageCollectorMXBeanClass, 
"getCollectionTime", "()J");
+
+    _threadMXBeanClass = env->FindClass("java/lang/management/ThreadMXBean");
+    if (_threadMXBeanClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/ThreadMXBean Not Find.JVM 
monitoring fails.";
+        return;
+    }
+    _getAllThreadIdsMethod = env->GetMethodID(_threadMXBeanClass, 
"getAllThreadIds", "()[J");
+    _getThreadInfoMethod = env->GetMethodID(_threadMXBeanClass, 
"getThreadInfo",
+                                            
"([JI)[Ljava/lang/management/ThreadInfo;");
+    _getPeakThreadCountMethod = env->GetMethodID(_threadMXBeanClass, 
"getPeakThreadCount", "()I");
+
+    _threadInfoClass = env->FindClass("java/lang/management/ThreadInfo");
+    if (_threadInfoClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/ThreadInfo Not Find.JVM 
monitoring fails.";
+        return;
+    }
+
+    _getThreadStateMethod =
+            env->GetMethodID(_threadInfoClass, "getThreadState", 
"()Ljava/lang/Thread$State;");
+
+    _threadStateClass = env->FindClass("java/lang/Thread$State");
+    if (_threadStateClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/Thread$State Not Find.JVM monitoring 
fails.";
+        return;
+    }
+
+    jfieldID newThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "NEW", 
"Ljava/lang/Thread$State;");
+    jfieldID runnableThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "RUNNABLE", 
"Ljava/lang/Thread$State;");
+    jfieldID blockedThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "BLOCKED", 
"Ljava/lang/Thread$State;");
+    jfieldID waitingThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "WAITING", 
"Ljava/lang/Thread$State;");
+    jfieldID timedWaitingThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "TIMED_WAITING", 
"Ljava/lang/Thread$State;");
+    jfieldID terminatedThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "TERMINATED", 
"Ljava/lang/Thread$State;");
+
+    _newThreadStateObj = env->GetStaticObjectField(_threadStateClass, 
newThreadFieldID);
+    _runnableThreadStateObj = env->GetStaticObjectField(_threadStateClass, 
runnableThreadFieldID);
+    _blockedThreadStateObj = env->GetStaticObjectField(_threadStateClass, 
blockedThreadFieldID);
+    _waitingThreadStateObj = env->GetStaticObjectField(_threadStateClass, 
waitingThreadFieldID);
+    _timedWaitingThreadStateObj =
+            env->GetStaticObjectField(_threadStateClass, 
timedWaitingThreadFieldID);
+    _terminatedThreadStateObj =
+            env->GetStaticObjectField(_threadStateClass, 
terminatedThreadFieldID);
+
+    LOG(INFO) << "Start JVM monitoring.";
+
+    _init_complete = true;
+}
+
+#include "jni.h"
+
+void jvmStats::refresh(JvmMetrics* jvm_metrics) {

Review Comment:
   warning: function 'refresh' has cognitive complexity of 65 (threshold 50) 
[readability-function-cognitive-complexity]
   ```cpp
   void jvmStats::refresh(JvmMetrics* jvm_metrics) {
                  ^
   ```
   <details>
   <summary>Additional context</summary>
   
   **be/src/util/jvm_metrics.cpp:251:** +1, including nesting penalty of 0, 
nesting level increased to 1
   ```cpp
       if (!_init_complete) {
       ^
   ```
   **be/src/util/jvm_metrics.cpp:266:** +1, including nesting penalty of 0, 
nesting level increased to 1
   ```cpp
       jvm_metrics->jvm_heap_size_bytes_used->set_value(heapMemoryUsed < 0 ? 0 
: heapMemoryUsed);
                                                                           ^
   ```
   **be/src/util/jvm_metrics.cpp:268:** +1, including nesting penalty of 0, 
nesting level increased to 1
   ```cpp
               heapMemoryCommitted < 0 ? 0 : heapMemoryCommitted);
                                       ^
   ```
   **be/src/util/jvm_metrics.cpp:269:** +1, including nesting penalty of 0, 
nesting level increased to 1
   ```cpp
       jvm_metrics->jvm_heap_size_bytes_max->set_value(heapMemoryMax < 0 ? 0 : 
heapMemoryMax);
                                                                         ^
   ```
   **be/src/util/jvm_metrics.cpp:279:** +1, including nesting penalty of 0, 
nesting level increased to 1
   ```cpp
               nonHeapMemoryCommitted < 0 ? 0 : nonHeapMemoryCommitted);
                                          ^
   ```
   **be/src/util/jvm_metrics.cpp:280:** +1, including nesting penalty of 0, 
nesting level increased to 1
   ```cpp
       jvm_metrics->jvm_non_heap_size_bytes_used->set_value(nonHeapMemoryUsed < 
0 ? 0
                                                                                
  ^
   ```
   **be/src/util/jvm_metrics.cpp:288:** +1, including nesting penalty of 0, 
nesting level increased to 1
   ```cpp
       for (int i = 0; i < size; ++i) {
       ^
   ```
   **be/src/util/jvm_metrics.cpp:305:** +2, including nesting penalty of 1, 
nesting level increased to 2
   ```cpp
           if (nameStr != NULL) {
           ^
   ```
   **be/src/util/jvm_metrics.cpp:307:** +3, including nesting penalty of 2, 
nesting level increased to 3
   ```cpp
               if (it == _memoryPoolName.end()) {
               ^
   ```
   **be/src/util/jvm_metrics.cpp:310:** +3, including nesting penalty of 2, 
nesting level increased to 3
   ```cpp
               if (it->second == memoryPoolNameEnum::YOUNG) {
               ^
   ```
   **be/src/util/jvm_metrics.cpp:311:** +4, including nesting penalty of 3, 
nesting level increased to 4
   ```cpp
                   jvm_metrics->jvm_young_size_bytes_used->set_value(used < 0 ? 
0 : used);
                                                                              ^
   ```
   **be/src/util/jvm_metrics.cpp:312:** +4, including nesting penalty of 3, 
nesting level increased to 4
   ```cpp
                   
jvm_metrics->jvm_young_size_bytes_peak_used->set_value(peakUsed < 0 ? 0 : 
peakUsed);
                                                                                
       ^
   ```
   **be/src/util/jvm_metrics.cpp:313:** +4, including nesting penalty of 3, 
nesting level increased to 4
   ```cpp
                   jvm_metrics->jvm_young_size_bytes_max->set_value(max < 0 ? 0 
: max);
                                                                            ^
   ```
   **be/src/util/jvm_metrics.cpp:315:** +1, nesting level increased to 3
   ```cpp
               } else if (it->second == memoryPoolNameEnum::OLD) {
                      ^
   ```
   **be/src/util/jvm_metrics.cpp:316:** +4, including nesting penalty of 3, 
nesting level increased to 4
   ```cpp
                   jvm_metrics->jvm_old_size_bytes_used->set_value(used < 0 ? 0 
: used);
                                                                            ^
   ```
   **be/src/util/jvm_metrics.cpp:317:** +4, including nesting penalty of 3, 
nesting level increased to 4
   ```cpp
                   
jvm_metrics->jvm_old_size_bytes_peak_used->set_value(peakUsed < 0 ? 0 : 
peakUsed);
                                                                                
     ^
   ```
   **be/src/util/jvm_metrics.cpp:318:** +4, including nesting penalty of 3, 
nesting level increased to 4
   ```cpp
                   jvm_metrics->jvm_old_size_bytes_max->set_value(max < 0 ? 0 : 
max);
                                                                          ^
   ```
   **be/src/util/jvm_metrics.cpp:341:** +1, including nesting penalty of 0, 
nesting level increased to 1
   ```cpp
       jvm_metrics->jvm_thread_peak_count->set_value(peakThreadCount < 0 ? 0 : 
peakThreadCount);
                                                                         ^
   ```
   **be/src/util/jvm_metrics.cpp:342:** +1, including nesting penalty of 0, 
nesting level increased to 1
   ```cpp
       jvm_metrics->jvm_thread_count->set_value(threadCount < 0 ? 0 : 
threadCount);
                                                                ^
   ```
   **be/src/util/jvm_metrics.cpp:344:** +1, including nesting penalty of 0, 
nesting level increased to 1
   ```cpp
       for (int i = 0; i < threadCount; i++) {
       ^
   ```
   **be/src/util/jvm_metrics.cpp:346:** +2, including nesting penalty of 1, 
nesting level increased to 2
   ```cpp
           if (threadInfo == nullptr) {
           ^
   ```
   **be/src/util/jvm_metrics.cpp:351:** +2, including nesting penalty of 1, 
nesting level increased to 2
   ```cpp
           if (env->IsSameObject(threadState, _newThreadStateObj)) {
           ^
   ```
   **be/src/util/jvm_metrics.cpp:353:** +1, nesting level increased to 2
   ```cpp
           } else if (env->IsSameObject(threadState, _runnableThreadStateObj)) {
                  ^
   ```
   **be/src/util/jvm_metrics.cpp:355:** +1, nesting level increased to 2
   ```cpp
           } else if (env->IsSameObject(threadState, _blockedThreadStateObj)) {
                  ^
   ```
   **be/src/util/jvm_metrics.cpp:357:** +1, nesting level increased to 2
   ```cpp
           } else if (env->IsSameObject(threadState, _waitingThreadStateObj)) {
                  ^
   ```
   **be/src/util/jvm_metrics.cpp:359:** +1, nesting level increased to 2
   ```cpp
           } else if (env->IsSameObject(threadState, 
_timedWaitingThreadStateObj)) {
                  ^
   ```
   **be/src/util/jvm_metrics.cpp:361:** +1, nesting level increased to 2
   ```cpp
           } else if (env->IsSameObject(threadState, 
_terminatedThreadStateObj)) {
                  ^
   ```
   **be/src/util/jvm_metrics.cpp:368:** +1, including nesting penalty of 0, 
nesting level increased to 1
   ```cpp
       jvm_metrics->jvm_thread_new_count->set_value(threadsNew < 0 ? 0 : 
threadsNew);
                                                                   ^
   ```
   **be/src/util/jvm_metrics.cpp:369:** +1, including nesting penalty of 0, 
nesting level increased to 1
   ```cpp
       jvm_metrics->jvm_thread_runnable_count->set_value(threadsRunnable < 0 ? 
0 : threadsRunnable);
                                                                             ^
   ```
   **be/src/util/jvm_metrics.cpp:370:** +1, including nesting penalty of 0, 
nesting level increased to 1
   ```cpp
       jvm_metrics->jvm_thread_blocked_count->set_value(threadsBlocked < 0 ? 0 
: threadsBlocked);
                                                                           ^
   ```
   **be/src/util/jvm_metrics.cpp:371:** +1, including nesting penalty of 0, 
nesting level increased to 1
   ```cpp
       jvm_metrics->jvm_thread_waiting_count->set_value(threadsWaiting < 0 ? 0 
: threadsWaiting);
                                                                           ^
   ```
   **be/src/util/jvm_metrics.cpp:373:** +1, including nesting penalty of 0, 
nesting level increased to 1
   ```cpp
               threadsTimedWaiting < 0 ? 0 : threadsTimedWaiting);
                                       ^
   ```
   **be/src/util/jvm_metrics.cpp:374:** +1, including nesting penalty of 0, 
nesting level increased to 1
   ```cpp
       jvm_metrics->jvm_thread_terminated_count->set_value(threadsTerminated < 
0 ? 0
                                                                                
 ^
   ```
   **be/src/util/jvm_metrics.cpp:382:** +1, including nesting penalty of 0, 
nesting level increased to 1
   ```cpp
       for (int i = 0; i < numCollectors; i++) {
       ^
   ```
   **be/src/util/jvm_metrics.cpp:389:** +2, including nesting penalty of 1, 
nesting level increased to 2
   ```cpp
           if (gcNameStr != nullptr) {
           ^
   ```
   **be/src/util/jvm_metrics.cpp:390:** +3, including nesting penalty of 2, 
nesting level increased to 3
   ```cpp
               if (strcmp(gcNameStr, "G1 Young Generation") == 0) {
               ^
   ```
   **be/src/util/jvm_metrics.cpp:394:** +1, nesting level increased to 3
   ```cpp
               } else {
                 ^
   ```
   
   </details>
   



##########
be/src/util/jvm_metrics.cpp:
##########
@@ -0,0 +1,423 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "jvm_metrics.h"
+
+#include <functional>
+
+#include "util/metrics.h"
+
+namespace doris {
+
+#define DEFINE_JVM_SIZE_BYTES_METRIC(name, type)                               
      \
+    DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(name##_##type, MetricUnit::BYTES, "", 
name, \
+                                         Labels({{"type", #type}}));
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, max);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, committed);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, used);
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_non_heap_size_bytes, used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_non_heap_size_bytes, committed);
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, peak_used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, max);
+
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, peak_used);
+DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, max);
+
+#define DEFINE_JVM_THREAD_METRIC(type)                                         
                 \
+    DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_thread_##type, 
MetricUnit::NOUNIT, "", jvm_thread, \
+                                         Labels({{"type", #type}}));
+
+DEFINE_JVM_THREAD_METRIC(count);
+DEFINE_JVM_THREAD_METRIC(peak_count);
+DEFINE_JVM_THREAD_METRIC(new_count);
+DEFINE_JVM_THREAD_METRIC(runnable_count);
+DEFINE_JVM_THREAD_METRIC(blocked_count);
+DEFINE_JVM_THREAD_METRIC(waiting_count);
+DEFINE_JVM_THREAD_METRIC(timed_waiting_count);
+DEFINE_JVM_THREAD_METRIC(terminated_count);
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_young_generation_count, 
MetricUnit::NOUNIT, "",
+                                     jvm_gc,
+                                     Labels({{"name", "G1 Young generation 
Count"},
+                                             {"type", "count"}}));
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_young_generation_time_ms, 
MetricUnit::MILLISECONDS,
+                                     "", jvm_gc,
+                                     Labels({{"name", "G1 Young generation 
Time"},
+                                             {"type", "time"}}));
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_old_generation_count, 
MetricUnit::NOUNIT, "", jvm_gc,
+                                     Labels({{"name", "G1 Old generation 
Count"},
+                                             {"type", "count"}}));
+
+DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_old_generation_time_ms, 
MetricUnit::MILLISECONDS, "",
+                                     jvm_gc,
+                                     Labels({{"name", "G1 Old generation 
Time"},
+                                             {"type", "time"}}));
+
+const char* JvmMetrics::_s_hook_name = "jvm_metrics";
+
+JvmMetrics::JvmMetrics(MetricRegistry* registry, JNIEnv* env) : 
_jvm_stats(env) {
+    DCHECK(registry != nullptr);
+    _registry = registry;
+
+    _server_entity = _registry->register_entity("server");
+    DCHECK(_server_entity != nullptr);
+    if (_jvm_stats.init_complete()) {
+        _server_entity->register_hook(_s_hook_name, 
std::bind(&JvmMetrics::update, this));
+    }
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_max);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_committed);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_used);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_non_heap_size_bytes_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_non_heap_size_bytes_committed);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_peak_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_max);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_peak_used);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_max);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_peak_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_new_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_runnable_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_blocked_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_waiting_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_timed_waiting_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_terminated_count);
+
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_gc_g1_young_generation_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_gc_g1_young_generation_time_ms);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_gc_g1_old_generation_count);
+    INT_GAUGE_METRIC_REGISTER(_server_entity, 
jvm_gc_g1_old_generation_time_ms);
+}
+
+void JvmMetrics::update() {
+    _jvm_stats.refresh(this);
+}
+#include <util/jni-util.h>
+
+jvmStats::jvmStats(JNIEnv* ENV) : env(ENV) {
+    _managementFactoryClass = 
env->FindClass("java/lang/management/ManagementFactory");
+    if (_managementFactoryClass == nullptr) {
+        LOG(WARNING)
+                << "Class java/lang/management/ManagementFactory Not Find.JVM 
monitoring fails.";
+        return;
+    }
+
+    _getMemoryMXBeanMethod = env->GetStaticMethodID(_managementFactoryClass, 
"getMemoryMXBean",
+                                                    
"()Ljava/lang/management/MemoryMXBean;");
+
+    _memoryUsageClass = env->FindClass("java/lang/management/MemoryUsage");
+    if (_memoryUsageClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/MemoryUsage Not Find.JVM 
monitoring fails.";
+        return;
+    }
+    _getMemoryUsageUsedMethod = env->GetMethodID(_memoryUsageClass, "getUsed", 
"()J");
+    _getMemoryUsageCommittedMethod = env->GetMethodID(_memoryUsageClass, 
"getCommitted", "()J");
+    _getMemoryUsageMaxMethod = env->GetMethodID(_memoryUsageClass, "getMax", 
"()J");
+
+    _memoryMXBeanClass = env->FindClass("java/lang/management/MemoryMXBean");
+    if (_memoryMXBeanClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/MemoryMXBean Not Find.JVM 
monitoring fails.";
+        return;
+    }
+    _getHeapMemoryUsageMethod = env->GetMethodID(_memoryMXBeanClass, 
"getHeapMemoryUsage",
+                                                 
"()Ljava/lang/management/MemoryUsage;");
+    _getNonHeapMemoryUsageMethod = env->GetMethodID(_memoryMXBeanClass, 
"getNonHeapMemoryUsage",
+                                                    
"()Ljava/lang/management/MemoryUsage;");
+
+    _getMemoryPoolMXBeansMethod = env->GetStaticMethodID(
+            _managementFactoryClass, "getMemoryPoolMXBeans", 
"()Ljava/util/List;");
+
+    _listClass = env->FindClass("java/util/List");
+    if (_listClass == nullptr) {
+        LOG(WARNING) << "Class java/util/List Not Find.JVM monitoring fails.";
+        return;
+    }
+    _getListSizeMethod = env->GetMethodID(_listClass, "size", "()I");
+    _getListUseIndexMethod = env->GetMethodID(_listClass, "get", 
"(I)Ljava/lang/Object;");
+
+    _memoryPoolMXBeanClass = 
env->FindClass("java/lang/management/MemoryPoolMXBean");
+    if (_memoryPoolMXBeanClass == nullptr) {
+        LOG(WARNING)
+                << "Class java/lang/management/MemoryPoolMXBean Not Find.JVM 
monitoring fails.";
+        return;
+    }
+    _getMemoryPoolMXBeanUsageMethod = env->GetMethodID(_memoryPoolMXBeanClass, 
"getUsage",
+                                                       
"()Ljava/lang/management/MemoryUsage;");
+    _getMemoryPollMXBeanPeakMethod = env->GetMethodID(_memoryPoolMXBeanClass, 
"getPeakUsage",
+                                                      
"()Ljava/lang/management/MemoryUsage;");
+    _getMemoryPollMXBeanNameMethod =
+            env->GetMethodID(_memoryPoolMXBeanClass, "getName", 
"()Ljava/lang/String;");
+
+    _getThreadMXBeanMethod = env->GetStaticMethodID(_managementFactoryClass, 
"getThreadMXBean",
+                                                    
"()Ljava/lang/management/ThreadMXBean;");
+
+    _getGarbageCollectorMXBeansMethod = env->GetStaticMethodID(
+            _managementFactoryClass, "getGarbageCollectorMXBeans", 
"()Ljava/util/List;");
+
+    _garbageCollectorMXBeanClass = 
env->FindClass("java/lang/management/GarbageCollectorMXBean");
+    if (_garbageCollectorMXBeanClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/GarbageCollectorMXBean Not 
Find.JVM monitoring "
+                        "fails.";
+        return;
+    }
+    _getGCNameMethod =
+            env->GetMethodID(_garbageCollectorMXBeanClass, "getName", 
"()Ljava/lang/String;");
+    _getGCCollectionCountMethod =
+            env->GetMethodID(_garbageCollectorMXBeanClass, 
"getCollectionCount", "()J");
+    _getGCCollectionTimeMethod =
+            env->GetMethodID(_garbageCollectorMXBeanClass, 
"getCollectionTime", "()J");
+
+    _threadMXBeanClass = env->FindClass("java/lang/management/ThreadMXBean");
+    if (_threadMXBeanClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/ThreadMXBean Not Find.JVM 
monitoring fails.";
+        return;
+    }
+    _getAllThreadIdsMethod = env->GetMethodID(_threadMXBeanClass, 
"getAllThreadIds", "()[J");
+    _getThreadInfoMethod = env->GetMethodID(_threadMXBeanClass, 
"getThreadInfo",
+                                            
"([JI)[Ljava/lang/management/ThreadInfo;");
+    _getPeakThreadCountMethod = env->GetMethodID(_threadMXBeanClass, 
"getPeakThreadCount", "()I");
+
+    _threadInfoClass = env->FindClass("java/lang/management/ThreadInfo");
+    if (_threadInfoClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/management/ThreadInfo Not Find.JVM 
monitoring fails.";
+        return;
+    }
+
+    _getThreadStateMethod =
+            env->GetMethodID(_threadInfoClass, "getThreadState", 
"()Ljava/lang/Thread$State;");
+
+    _threadStateClass = env->FindClass("java/lang/Thread$State");
+    if (_threadStateClass == nullptr) {
+        LOG(WARNING) << "Class java/lang/Thread$State Not Find.JVM monitoring 
fails.";
+        return;
+    }
+
+    jfieldID newThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "NEW", 
"Ljava/lang/Thread$State;");
+    jfieldID runnableThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "RUNNABLE", 
"Ljava/lang/Thread$State;");
+    jfieldID blockedThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "BLOCKED", 
"Ljava/lang/Thread$State;");
+    jfieldID waitingThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "WAITING", 
"Ljava/lang/Thread$State;");
+    jfieldID timedWaitingThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "TIMED_WAITING", 
"Ljava/lang/Thread$State;");
+    jfieldID terminatedThreadFieldID =
+            env->GetStaticFieldID(_threadStateClass, "TERMINATED", 
"Ljava/lang/Thread$State;");
+
+    _newThreadStateObj = env->GetStaticObjectField(_threadStateClass, 
newThreadFieldID);
+    _runnableThreadStateObj = env->GetStaticObjectField(_threadStateClass, 
runnableThreadFieldID);
+    _blockedThreadStateObj = env->GetStaticObjectField(_threadStateClass, 
blockedThreadFieldID);
+    _waitingThreadStateObj = env->GetStaticObjectField(_threadStateClass, 
waitingThreadFieldID);
+    _timedWaitingThreadStateObj =
+            env->GetStaticObjectField(_threadStateClass, 
timedWaitingThreadFieldID);
+    _terminatedThreadStateObj =
+            env->GetStaticObjectField(_threadStateClass, 
terminatedThreadFieldID);
+
+    LOG(INFO) << "Start JVM monitoring.";
+
+    _init_complete = true;
+}
+
+#include "jni.h"
+
+void jvmStats::refresh(JvmMetrics* jvm_metrics) {

Review Comment:
   warning: method 'refresh' can be made const 
[readability-make-member-function-const]
   
   be/src/util/jvm_metrics.h:102:
   ```diff
   -     void refresh(JvmMetrics* jvm_metrics);
   +     void refresh(JvmMetrics* jvm_metrics) const;
   ```
   
   ```suggestion
   void jvmStats::refresh(JvmMetrics* jvm_metrics) const {
   ```
   



##########
be/src/util/jvm_metrics.h:
##########
@@ -0,0 +1,149 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+#include <jni.h>
+
+#include "jni.h"

Review Comment:
   warning: duplicate include [readability-duplicate-include]
   
   be/src/util/jvm_metrics.h:20:
   ```diff
   - 
   - #include "jni.h"
   
   ```
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to