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