be/src/common/metrics/jvm_metrics.cpp
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | #include "common/metrics/jvm_metrics.h" |
19 | | |
20 | | #include <functional> |
21 | | |
22 | | #include "common/config.h" |
23 | | #include "common/metrics/metrics.h" |
24 | | #include "util/defer_op.h" |
25 | | #include "util/jni-util.h" |
26 | | |
27 | | namespace doris { |
28 | | |
29 | | #define DEFINE_JVM_SIZE_BYTES_METRIC(name, type) \ |
30 | | DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(name##_##type, MetricUnit::BYTES, "", name, \ |
31 | | Labels({{"type", #type}})); |
32 | | |
33 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, max); |
34 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, committed); |
35 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, used); |
36 | | |
37 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_non_heap_size_bytes, used); |
38 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_non_heap_size_bytes, committed); |
39 | | |
40 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, used); |
41 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, peak_used); |
42 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, max); |
43 | | |
44 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, used); |
45 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, peak_used); |
46 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, max); |
47 | | |
48 | | #define DEFINE_JVM_THREAD_METRIC(type) \ |
49 | | DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_thread_##type, MetricUnit::NOUNIT, "", jvm_thread, \ |
50 | | Labels({{"type", #type}})); |
51 | | |
52 | | DEFINE_JVM_THREAD_METRIC(count); |
53 | | DEFINE_JVM_THREAD_METRIC(peak_count); |
54 | | DEFINE_JVM_THREAD_METRIC(new_count); |
55 | | DEFINE_JVM_THREAD_METRIC(runnable_count); |
56 | | DEFINE_JVM_THREAD_METRIC(blocked_count); |
57 | | DEFINE_JVM_THREAD_METRIC(waiting_count); |
58 | | DEFINE_JVM_THREAD_METRIC(timed_waiting_count); |
59 | | DEFINE_JVM_THREAD_METRIC(terminated_count); |
60 | | |
61 | | DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_young_generation_count, MetricUnit::NOUNIT, "", |
62 | | jvm_gc, |
63 | | Labels({{"name", "G1 Young generation Count"}, |
64 | | {"type", "count"}})); |
65 | | |
66 | | DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_young_generation_time_ms, MetricUnit::MILLISECONDS, |
67 | | "", jvm_gc, |
68 | | Labels({{"name", "G1 Young generation Time"}, |
69 | | {"type", "time"}})); |
70 | | |
71 | | DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_old_generation_count, MetricUnit::NOUNIT, "", jvm_gc, |
72 | | Labels({{"name", "G1 Old generation Count"}, |
73 | | {"type", "count"}})); |
74 | | |
75 | | DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_old_generation_time_ms, MetricUnit::MILLISECONDS, "", |
76 | | jvm_gc, |
77 | | Labels({{"name", "G1 Old generation Time"}, |
78 | | {"type", "time"}})); |
79 | | |
80 | | const char* JvmMetrics::_s_hook_name = "jvm_metrics"; |
81 | | |
82 | 7 | JvmMetrics::JvmMetrics(MetricRegistry* registry) { |
83 | 7 | DCHECK(registry != nullptr); |
84 | 7 | _registry = registry; |
85 | | |
86 | 7 | _server_entity = _registry->register_entity("server"); |
87 | 7 | DCHECK(_server_entity != nullptr); |
88 | | |
89 | 7 | do { |
90 | 7 | if (!doris::config::enable_jvm_monitor) { |
91 | 0 | break; |
92 | 0 | } |
93 | 7 | try { |
94 | 7 | Status st = _jvm_stats.init(); |
95 | 7 | if (!st) { |
96 | 0 | LOG(WARNING) << "jvm Stats Init Fail. " << st.to_string(); |
97 | 0 | break; |
98 | 0 | } |
99 | 7 | } catch (...) { |
100 | 0 | LOG(WARNING) << "jvm Stats Throw Exception Init Fail."; |
101 | 0 | break; |
102 | 0 | } |
103 | 7 | if (!_jvm_stats.init_complete()) { |
104 | 0 | break; |
105 | 0 | } |
106 | 7 | _server_entity->register_hook(_s_hook_name, std::bind(&JvmMetrics::update, this)); |
107 | 7 | } while (false); |
108 | | |
109 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_max); |
110 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_committed); |
111 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_used); |
112 | | |
113 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_non_heap_size_bytes_used); |
114 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_non_heap_size_bytes_committed); |
115 | | |
116 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_used); |
117 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_peak_used); |
118 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_max); |
119 | | |
120 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_used); |
121 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_peak_used); |
122 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_max); |
123 | | |
124 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_count); |
125 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_peak_count); |
126 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_new_count); |
127 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_runnable_count); |
128 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_blocked_count); |
129 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_waiting_count); |
130 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_timed_waiting_count); |
131 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_terminated_count); |
132 | | |
133 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_gc_g1_young_generation_count); |
134 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_gc_g1_young_generation_time_ms); |
135 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_gc_g1_old_generation_count); |
136 | 7 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_gc_g1_old_generation_time_ms); |
137 | 7 | } |
138 | | |
139 | 3 | JvmMetrics::~JvmMetrics() { |
140 | 3 | if (_jvm_stats.init_complete()) { |
141 | 3 | _server_entity->deregister_hook(_s_hook_name); |
142 | 3 | } |
143 | 3 | } |
144 | | |
145 | 2.11k | void JvmMetrics::update() { |
146 | | // If enable_jvm_monitor is false, the jvm stats object is not initialized. call jvm_stats.refresh() may core. |
147 | 2.11k | if (!doris::config::enable_jvm_monitor) { |
148 | 0 | return; |
149 | 0 | } |
150 | 2.11k | static long fail_count = 0; |
151 | 2.11k | if (fail_count >= 30) { |
152 | 0 | return; |
153 | 0 | } |
154 | | |
155 | 2.11k | try { |
156 | 2.11k | Status st = _jvm_stats.refresh(this); |
157 | 2.11k | if (!st) { |
158 | 0 | fail_count++; |
159 | 0 | LOG(WARNING) << "Jvm Stats update Fail! " << st.to_string(); |
160 | 2.11k | } else { |
161 | 2.11k | fail_count = 0; |
162 | 2.11k | } |
163 | 2.11k | } catch (...) { |
164 | 0 | LOG(WARNING) << "Jvm Stats update throw Exception!"; |
165 | 0 | fail_count++; |
166 | 0 | } |
167 | | |
168 | | //When 30 consecutive exceptions occur, turn off jvm information collection. |
169 | 2.11k | if (fail_count >= 30) { |
170 | 0 | LOG(WARNING) << "Jvm Stats CLOSE!"; |
171 | 0 | jvm_heap_size_bytes_max->set_value(0); |
172 | 0 | jvm_heap_size_bytes_committed->set_value(0); |
173 | 0 | jvm_heap_size_bytes_used->set_value(0); |
174 | |
|
175 | 0 | jvm_non_heap_size_bytes_used->set_value(0); |
176 | 0 | jvm_non_heap_size_bytes_committed->set_value(0); |
177 | |
|
178 | 0 | jvm_young_size_bytes_used->set_value(0); |
179 | 0 | jvm_young_size_bytes_peak_used->set_value(0); |
180 | 0 | jvm_young_size_bytes_max->set_value(0); |
181 | |
|
182 | 0 | jvm_old_size_bytes_used->set_value(0); |
183 | 0 | jvm_old_size_bytes_peak_used->set_value(0); |
184 | 0 | jvm_old_size_bytes_max->set_value(0); |
185 | |
|
186 | 0 | jvm_thread_count->set_value(0); |
187 | 0 | jvm_thread_peak_count->set_value(0); |
188 | 0 | jvm_thread_new_count->set_value(0); |
189 | 0 | jvm_thread_runnable_count->set_value(0); |
190 | 0 | jvm_thread_blocked_count->set_value(0); |
191 | 0 | jvm_thread_waiting_count->set_value(0); |
192 | 0 | jvm_thread_timed_waiting_count->set_value(0); |
193 | 0 | jvm_thread_terminated_count->set_value(0); |
194 | |
|
195 | 0 | jvm_gc_g1_young_generation_count->set_value(0); |
196 | 0 | jvm_gc_g1_young_generation_time_ms->set_value(0); |
197 | 0 | jvm_gc_g1_old_generation_count->set_value(0); |
198 | 0 | jvm_gc_g1_old_generation_time_ms->set_value(0); |
199 | 0 | } |
200 | 2.11k | } |
201 | | |
202 | 7 | Status JvmStats::init() { |
203 | 7 | JNIEnv* env = nullptr; |
204 | 7 | RETURN_IF_ERROR(Jni::Env::Get(&env)); |
205 | | |
206 | 7 | RETURN_IF_ERROR(Jni::Util::find_class(env, "java/lang/management/ManagementFactory", |
207 | 7 | &_managementFactoryClass)); |
208 | 7 | RETURN_IF_ERROR(_managementFactoryClass.get_static_method( |
209 | 7 | env, "getMemoryMXBean", "()Ljava/lang/management/MemoryMXBean;", |
210 | 7 | &_getMemoryMXBeanMethod)); |
211 | | |
212 | 7 | RETURN_IF_ERROR( |
213 | 7 | Jni::Util::find_class(env, "java/lang/management/MemoryUsage", &_memoryUsageClass)); |
214 | 7 | RETURN_IF_ERROR( |
215 | 7 | _memoryUsageClass.get_method(env, "getUsed", "()J", &_getMemoryUsageUsedMethod)); |
216 | 7 | RETURN_IF_ERROR(_memoryUsageClass.get_method(env, "getCommitted", "()J", |
217 | 7 | &_getMemoryUsageCommittedMethod)); |
218 | 7 | RETURN_IF_ERROR(_memoryUsageClass.get_method(env, "getMax", "()J", &_getMemoryUsageMaxMethod)); |
219 | | |
220 | 7 | RETURN_IF_ERROR( |
221 | 7 | Jni::Util::find_class(env, "java/lang/management/MemoryMXBean", &_memoryMXBeanClass)); |
222 | 7 | RETURN_IF_ERROR(_memoryMXBeanClass.get_method(env, "getHeapMemoryUsage", |
223 | 7 | "()Ljava/lang/management/MemoryUsage;", |
224 | 7 | &_getHeapMemoryUsageMethod)); |
225 | 7 | RETURN_IF_ERROR(_memoryMXBeanClass.get_method(env, "getNonHeapMemoryUsage", |
226 | 7 | "()Ljava/lang/management/MemoryUsage;", |
227 | 7 | &_getNonHeapMemoryUsageMethod)); |
228 | | |
229 | 7 | RETURN_IF_ERROR(_managementFactoryClass.get_static_method( |
230 | 7 | env, "getMemoryPoolMXBeans", "()Ljava/util/List;", &_getMemoryPoolMXBeansMethod)); |
231 | | |
232 | 7 | RETURN_IF_ERROR(Jni::Util::find_class(env, "java/util/List", &_listClass)); |
233 | 7 | RETURN_IF_ERROR(_listClass.get_method(env, "size", "()I", &_getListSizeMethod)); |
234 | 7 | RETURN_IF_ERROR( |
235 | 7 | _listClass.get_method(env, "get", "(I)Ljava/lang/Object;", &_getListUseIndexMethod)); |
236 | | |
237 | 7 | RETURN_IF_ERROR(Jni::Util::find_class(env, "java/lang/management/MemoryPoolMXBean", |
238 | 7 | &_memoryPoolMXBeanClass)); |
239 | 7 | RETURN_IF_ERROR(_memoryPoolMXBeanClass.get_method(env, "getUsage", |
240 | 7 | "()Ljava/lang/management/MemoryUsage;", |
241 | 7 | &_getMemoryPoolMXBeanUsageMethod)); |
242 | 7 | RETURN_IF_ERROR(_memoryPoolMXBeanClass.get_method(env, "getPeakUsage", |
243 | 7 | "()Ljava/lang/management/MemoryUsage;", |
244 | 7 | &_getMemoryPoolMXBeanPeakMethod)); |
245 | 7 | RETURN_IF_ERROR(_memoryPoolMXBeanClass.get_method(env, "getName", "()Ljava/lang/String;", |
246 | 7 | &_getMemoryPoolMXBeanNameMethod)); |
247 | | |
248 | 7 | RETURN_IF_ERROR(_managementFactoryClass.get_static_method( |
249 | 7 | env, "getThreadMXBean", "()Ljava/lang/management/ThreadMXBean;", |
250 | 7 | &_getThreadMXBeanMethod)); |
251 | 7 | RETURN_IF_ERROR(_managementFactoryClass.get_static_method(env, "getGarbageCollectorMXBeans", |
252 | 7 | "()Ljava/util/List;", |
253 | 7 | &_getGarbageCollectorMXBeansMethod)); |
254 | | |
255 | 7 | RETURN_IF_ERROR(Jni::Util::find_class(env, "java/lang/management/GarbageCollectorMXBean", |
256 | 7 | &_garbageCollectorMXBeanClass)); |
257 | 7 | RETURN_IF_ERROR(_garbageCollectorMXBeanClass.get_method(env, "getName", "()Ljava/lang/String;", |
258 | 7 | &_getGCNameMethod)); |
259 | 7 | RETURN_IF_ERROR(_garbageCollectorMXBeanClass.get_method(env, "getCollectionCount", "()J", |
260 | 7 | &_getGCCollectionCountMethod)); |
261 | 7 | RETURN_IF_ERROR(_garbageCollectorMXBeanClass.get_method(env, "getCollectionTime", "()J", |
262 | 7 | &_getGCCollectionTimeMethod)); |
263 | | |
264 | 7 | RETURN_IF_ERROR( |
265 | 7 | Jni::Util::find_class(env, "java/lang/management/ThreadMXBean", &_threadMXBeanClass)); |
266 | 7 | RETURN_IF_ERROR( |
267 | 7 | _threadMXBeanClass.get_method(env, "getAllThreadIds", "()[J", &_getAllThreadIdsMethod)); |
268 | 7 | RETURN_IF_ERROR(_threadMXBeanClass.get_method(env, "getThreadInfo", |
269 | 7 | "([JI)[Ljava/lang/management/ThreadInfo;", |
270 | 7 | &_getThreadInfoMethod)); |
271 | 7 | RETURN_IF_ERROR(_threadMXBeanClass.get_method(env, "getPeakThreadCount", "()I", |
272 | 7 | &_getPeakThreadCountMethod)); |
273 | | |
274 | 7 | RETURN_IF_ERROR( |
275 | 7 | Jni::Util::find_class(env, "java/lang/management/ThreadInfo", &_threadInfoClass)); |
276 | 7 | RETURN_IF_ERROR(_threadInfoClass.get_method(env, "getThreadState", "()Ljava/lang/Thread$State;", |
277 | 7 | &_getThreadStateMethod)); |
278 | | |
279 | 7 | RETURN_IF_ERROR(Jni::Util::find_class(env, "java/lang/Thread$State", &_threadStateClass)); |
280 | 7 | RETURN_IF_ERROR(_threadStateClass.get_static_object_field( |
281 | 7 | env, "NEW", "Ljava/lang/Thread$State;", &_newThreadStateObj)); |
282 | 7 | RETURN_IF_ERROR(_threadStateClass.get_static_object_field( |
283 | 7 | env, "RUNNABLE", "Ljava/lang/Thread$State;", &_runnableThreadStateObj)); |
284 | 7 | RETURN_IF_ERROR(_threadStateClass.get_static_object_field( |
285 | 7 | env, "BLOCKED", "Ljava/lang/Thread$State;", &_blockedThreadStateObj)); |
286 | 7 | RETURN_IF_ERROR(_threadStateClass.get_static_object_field( |
287 | 7 | env, "WAITING", "Ljava/lang/Thread$State;", &_waitingThreadStateObj)); |
288 | 7 | RETURN_IF_ERROR(_threadStateClass.get_static_object_field( |
289 | 7 | env, "TIMED_WAITING", "Ljava/lang/Thread$State;", &_timedWaitingThreadStateObj)); |
290 | 7 | RETURN_IF_ERROR(_threadStateClass.get_static_object_field( |
291 | 7 | env, "TERMINATED", "Ljava/lang/Thread$State;", &_terminatedThreadStateObj)); |
292 | | |
293 | 7 | _init_complete = true; |
294 | 7 | LOG(INFO) << "Start JVM monitoring."; |
295 | 7 | return Status::OK(); |
296 | 7 | } |
297 | | |
298 | 2.11k | Status JvmStats::refresh(JvmMetrics* jvm_metrics) const { |
299 | 2.11k | if (!_init_complete) { |
300 | 0 | return Status::InternalError("Jvm Stats not init complete."); |
301 | 0 | } |
302 | | |
303 | 2.11k | JNIEnv* env = nullptr; |
304 | 2.11k | RETURN_IF_ERROR(Jni::Env::Get(&env)); |
305 | | |
306 | 2.11k | Jni::LocalObject memoryMXBeanObj; |
307 | 2.11k | RETURN_IF_ERROR(_managementFactoryClass.call_static_object_method(env, _getMemoryMXBeanMethod) |
308 | 2.11k | .call(&memoryMXBeanObj)); |
309 | | |
310 | 2.11k | Jni::LocalObject heapMemoryUsageObj; |
311 | 2.11k | RETURN_IF_ERROR(memoryMXBeanObj.call_object_method(env, _getHeapMemoryUsageMethod) |
312 | 2.11k | .call(&heapMemoryUsageObj)); |
313 | | |
314 | 2.11k | jlong heapMemoryUsed = 0; |
315 | 2.11k | RETURN_IF_ERROR(heapMemoryUsageObj.call_long_method(env, _getMemoryUsageUsedMethod) |
316 | 2.11k | .call(&heapMemoryUsed)); |
317 | | |
318 | 2.11k | jlong heapMemoryCommitted = 0; |
319 | 2.11k | RETURN_IF_ERROR(heapMemoryUsageObj.call_long_method(env, _getMemoryUsageCommittedMethod) |
320 | 2.11k | .call(&heapMemoryCommitted)); |
321 | | |
322 | 2.11k | jlong heapMemoryMax = 0; |
323 | 2.11k | RETURN_IF_ERROR(heapMemoryUsageObj.call_long_method(env, _getMemoryUsageMaxMethod) |
324 | 2.11k | .call(&heapMemoryMax)); |
325 | | |
326 | 2.11k | jvm_metrics->jvm_heap_size_bytes_used->set_value(heapMemoryUsed < 0 ? 0 : heapMemoryUsed); |
327 | 2.11k | jvm_metrics->jvm_heap_size_bytes_committed->set_value( |
328 | 2.11k | heapMemoryCommitted < 0 ? 0 : heapMemoryCommitted); |
329 | 2.11k | jvm_metrics->jvm_heap_size_bytes_max->set_value(heapMemoryMax < 0 ? 0 : heapMemoryMax); |
330 | | |
331 | 2.11k | Jni::LocalObject nonHeapMemoryUsageObj; |
332 | 2.11k | RETURN_IF_ERROR(memoryMXBeanObj.call_object_method(env, _getNonHeapMemoryUsageMethod) |
333 | 2.11k | .call(&nonHeapMemoryUsageObj)); |
334 | | |
335 | 2.11k | jlong nonHeapMemoryCommitted = 0; |
336 | 2.11k | RETURN_IF_ERROR(nonHeapMemoryUsageObj.call_long_method(env, _getMemoryUsageCommittedMethod) |
337 | 2.11k | .call(&nonHeapMemoryCommitted)); |
338 | | |
339 | 2.11k | jlong nonHeapMemoryUsed = 0; |
340 | 2.11k | RETURN_IF_ERROR(nonHeapMemoryUsageObj.call_long_method(env, _getMemoryUsageUsedMethod) |
341 | 2.11k | .call(&nonHeapMemoryUsed)); |
342 | | |
343 | 2.11k | jvm_metrics->jvm_non_heap_size_bytes_committed->set_value( |
344 | 2.11k | nonHeapMemoryCommitted < 0 ? 0 : nonHeapMemoryCommitted); |
345 | 2.11k | jvm_metrics->jvm_non_heap_size_bytes_used->set_value(nonHeapMemoryUsed < 0 ? 0 |
346 | 2.11k | : nonHeapMemoryUsed); |
347 | | |
348 | 2.11k | Jni::LocalObject memoryPoolMXBeansList; |
349 | 2.11k | RETURN_IF_ERROR( |
350 | 2.11k | _managementFactoryClass.call_static_object_method(env, _getMemoryPoolMXBeansMethod) |
351 | 2.11k | .call(&memoryPoolMXBeansList)); |
352 | | |
353 | 2.11k | jint beanSize = 0; |
354 | 2.11k | RETURN_IF_ERROR(memoryPoolMXBeansList.call_int_method(env, _getListSizeMethod).call(&beanSize)); |
355 | | |
356 | 19.0k | for (int i = 0; i < beanSize; ++i) { |
357 | 16.9k | Jni::LocalObject memoryPoolMXBean; |
358 | 16.9k | RETURN_IF_ERROR(memoryPoolMXBeansList.call_object_method(env, _getListUseIndexMethod) |
359 | 16.9k | .with_arg(i) |
360 | 16.9k | .call(&memoryPoolMXBean)); |
361 | | |
362 | 16.9k | Jni::LocalObject usageObject; |
363 | 16.9k | RETURN_IF_ERROR(memoryPoolMXBean.call_object_method(env, _getMemoryPoolMXBeanUsageMethod) |
364 | 16.9k | .call(&usageObject)); |
365 | | |
366 | 16.9k | jlong used = 0; |
367 | 16.9k | RETURN_IF_ERROR(usageObject.call_long_method(env, _getMemoryUsageUsedMethod).call(&used)); |
368 | | |
369 | 16.9k | jlong max = 0; |
370 | 16.9k | RETURN_IF_ERROR(usageObject.call_long_method(env, _getMemoryUsageMaxMethod).call(&max)); |
371 | | |
372 | 16.9k | Jni::LocalObject peakUsageObject; |
373 | 16.9k | RETURN_IF_ERROR(memoryPoolMXBean.call_object_method(env, _getMemoryPoolMXBeanPeakMethod) |
374 | 16.9k | .call(&peakUsageObject)); |
375 | | |
376 | 16.9k | jlong peakUsed = 0; |
377 | 16.9k | RETURN_IF_ERROR( |
378 | 16.9k | peakUsageObject.call_long_method(env, _getMemoryUsageUsedMethod).call(&peakUsed)); |
379 | | |
380 | 16.9k | Jni::LocalString name; |
381 | 16.9k | RETURN_IF_ERROR(memoryPoolMXBean.call_object_method(env, _getMemoryPoolMXBeanNameMethod) |
382 | 16.9k | .call(&name)); |
383 | | |
384 | 16.9k | Jni::LocalStringBufferGuard nameStr; |
385 | 16.9k | RETURN_IF_ERROR(name.get_string_chars(env, &nameStr)); |
386 | 16.9k | if (nameStr.get() != nullptr) { |
387 | 16.9k | auto it = _memoryPoolName.find(nameStr.get()); |
388 | 16.9k | if (it == _memoryPoolName.end()) { |
389 | 10.5k | continue; |
390 | 10.5k | } |
391 | 6.34k | if (it->second == memoryPoolNameEnum::YOUNG) { |
392 | 2.11k | jvm_metrics->jvm_young_size_bytes_used->set_value(used < 0 ? 0 : used); |
393 | 2.11k | jvm_metrics->jvm_young_size_bytes_peak_used->set_value(peakUsed < 0 ? 0 : peakUsed); |
394 | 2.11k | jvm_metrics->jvm_young_size_bytes_max->set_value(max < 0 ? 0 : max); |
395 | | |
396 | 4.23k | } else if (it->second == memoryPoolNameEnum::OLD) { |
397 | 2.11k | jvm_metrics->jvm_old_size_bytes_used->set_value(used < 0 ? 0 : used); |
398 | 2.11k | jvm_metrics->jvm_old_size_bytes_peak_used->set_value(peakUsed < 0 ? 0 : peakUsed); |
399 | 2.11k | jvm_metrics->jvm_old_size_bytes_max->set_value(max < 0 ? 0 : max); |
400 | 2.11k | } |
401 | 6.34k | } |
402 | 16.9k | } |
403 | | |
404 | 2.11k | Jni::LocalObject threadMXBean; |
405 | 2.11k | RETURN_IF_ERROR(_managementFactoryClass.call_static_object_method(env, _getThreadMXBeanMethod) |
406 | 2.11k | .call(&threadMXBean)); |
407 | | |
408 | 2.11k | Jni::LocalArray threadIds; |
409 | 2.11k | RETURN_IF_ERROR(threadMXBean.call_object_method(env, _getAllThreadIdsMethod).call(&threadIds)); |
410 | | |
411 | 2.11k | jsize threadCount = 0; |
412 | 2.11k | RETURN_IF_ERROR(threadIds.get_length(env, &threadCount)); |
413 | | |
414 | 2.11k | Jni::LocalArray threadInfos; |
415 | 2.11k | RETURN_IF_ERROR(threadMXBean.call_object_method(env, _getThreadInfoMethod) |
416 | 2.11k | .with_arg(threadIds) |
417 | 2.11k | .with_arg(0) |
418 | 2.11k | .call(&threadInfos)); |
419 | | |
420 | 2.11k | int threadsNew = 0, threadsRunnable = 0, threadsBlocked = 0, threadsWaiting = 0, |
421 | 2.11k | threadsTimedWaiting = 0, threadsTerminated = 0; |
422 | | |
423 | 2.11k | jint peakThreadCount = 0; |
424 | 2.11k | RETURN_IF_ERROR( |
425 | 2.11k | threadMXBean.call_int_method(env, _getPeakThreadCountMethod).call(&peakThreadCount)); |
426 | | |
427 | 2.11k | jvm_metrics->jvm_thread_peak_count->set_value(peakThreadCount < 0 ? 0 : peakThreadCount); |
428 | 2.11k | jvm_metrics->jvm_thread_count->set_value(threadCount < 0 ? 0 : threadCount); |
429 | | |
430 | 1.72M | for (int i = 0; i < threadCount; i++) { |
431 | 1.72M | Jni::LocalObject threadInfo; |
432 | 1.72M | RETURN_IF_ERROR(threadInfos.get_object_array_element(env, i, &threadInfo)); |
433 | 1.72M | if (threadInfo.uninitialized()) { |
434 | 30 | continue; |
435 | 30 | } |
436 | 1.72M | Jni::LocalObject threadState; |
437 | 1.72M | RETURN_IF_ERROR( |
438 | 1.72M | threadInfo.call_object_method(env, _getThreadStateMethod).call(&threadState)); |
439 | | |
440 | 1.72M | if (threadState.equal(env, _newThreadStateObj)) { |
441 | 0 | threadsNew++; |
442 | 1.72M | } else if (threadState.equal(env, _runnableThreadStateObj)) { |
443 | 320k | threadsRunnable++; |
444 | 1.40M | } else if (threadState.equal(env, _blockedThreadStateObj)) { |
445 | 50 | threadsBlocked++; |
446 | 1.40M | } else if (threadState.equal(env, _waitingThreadStateObj)) { |
447 | 1.25M | threadsWaiting++; |
448 | 1.25M | } else if (threadState.equal(env, _timedWaitingThreadStateObj)) { |
449 | 150k | threadsTimedWaiting++; |
450 | 150k | } else if (threadState.equal(env, _terminatedThreadStateObj)) { |
451 | 0 | threadsTerminated++; |
452 | 0 | } |
453 | 1.72M | } |
454 | | |
455 | 2.11k | jvm_metrics->jvm_thread_new_count->set_value(threadsNew < 0 ? 0 : threadsNew); |
456 | 2.11k | jvm_metrics->jvm_thread_runnable_count->set_value(threadsRunnable < 0 ? 0 : threadsRunnable); |
457 | 2.11k | jvm_metrics->jvm_thread_blocked_count->set_value(threadsBlocked < 0 ? 0 : threadsBlocked); |
458 | 2.11k | jvm_metrics->jvm_thread_waiting_count->set_value(threadsWaiting < 0 ? 0 : threadsWaiting); |
459 | 2.11k | jvm_metrics->jvm_thread_timed_waiting_count->set_value( |
460 | 2.11k | threadsTimedWaiting < 0 ? 0 : threadsTimedWaiting); |
461 | 2.11k | jvm_metrics->jvm_thread_terminated_count->set_value(threadsTerminated < 0 ? 0 |
462 | 2.11k | : threadsTerminated); |
463 | | |
464 | 2.11k | Jni::LocalObject gcMXBeansList; |
465 | 2.11k | RETURN_IF_ERROR(_managementFactoryClass |
466 | 2.11k | .call_static_object_method(env, _getGarbageCollectorMXBeansMethod) |
467 | 2.11k | .call(&gcMXBeansList)); |
468 | 2.11k | jint numCollectors = 0; |
469 | 2.11k | RETURN_IF_ERROR(gcMXBeansList.call_int_method(env, _getListSizeMethod).call(&numCollectors)); |
470 | | |
471 | 6.34k | for (int i = 0; i < numCollectors; i++) { |
472 | 4.23k | Jni::LocalObject gcMXBean; |
473 | 4.23k | RETURN_IF_ERROR(gcMXBeansList.call_object_method(env, _getListUseIndexMethod) |
474 | 4.23k | .with_arg(i) |
475 | 4.23k | .call(&gcMXBean)); |
476 | | |
477 | 4.23k | Jni::LocalString gcName; |
478 | 4.23k | RETURN_IF_ERROR(gcMXBean.call_object_method(env, _getGCNameMethod).call(&gcName)); |
479 | | |
480 | 4.23k | jlong gcCollectionCount = 0; |
481 | 4.23k | RETURN_IF_ERROR(gcMXBean.call_long_method(env, _getGCCollectionCountMethod) |
482 | 4.23k | .call(&gcCollectionCount)); |
483 | | |
484 | 4.23k | jlong gcCollectionTime = 0; |
485 | 4.23k | RETURN_IF_ERROR( |
486 | 4.23k | gcMXBean.call_long_method(env, _getGCCollectionTimeMethod).call(&gcCollectionTime)); |
487 | | |
488 | 4.23k | Jni::LocalStringBufferGuard gcNameStr; |
489 | 4.23k | RETURN_IF_ERROR(gcName.get_string_chars(env, &gcNameStr)); |
490 | | |
491 | 4.23k | if (gcNameStr.get() != nullptr) { |
492 | 4.23k | if (strcmp(gcNameStr.get(), "G1 Young Generation") == 0) { |
493 | 2.11k | jvm_metrics->jvm_gc_g1_young_generation_count->set_value(gcCollectionCount); |
494 | 2.11k | jvm_metrics->jvm_gc_g1_young_generation_time_ms->set_value(gcCollectionTime); |
495 | | |
496 | 2.11k | } else { |
497 | 2.11k | jvm_metrics->jvm_gc_g1_old_generation_count->set_value(gcCollectionCount); |
498 | 2.11k | jvm_metrics->jvm_gc_g1_old_generation_time_ms->set_value(gcCollectionTime); |
499 | 2.11k | } |
500 | 4.23k | } |
501 | 4.23k | } |
502 | | |
503 | 2.11k | return Status::OK(); |
504 | 2.11k | } |
505 | 3 | JvmStats::~JvmStats() {} |
506 | | |
507 | | } // namespace doris |