Skip to content

Commit

Permalink
add some new thread metric and class metric to JVMMetric(apache#7230)
Browse files Browse the repository at this point in the history
  • Loading branch information
Switch-vov committed Jul 2, 2021
1 parent 04bb667 commit 2e2a008
Show file tree
Hide file tree
Showing 11 changed files with 257 additions and 6 deletions.
Expand Up @@ -25,6 +25,7 @@
import org.apache.skywalking.apm.agent.core.boot.DefaultImplementor;
import org.apache.skywalking.apm.agent.core.boot.DefaultNamedThreadFactory;
import org.apache.skywalking.apm.agent.core.boot.ServiceManager;
import org.apache.skywalking.apm.agent.core.jvm.clazz.ClassProvider;
import org.apache.skywalking.apm.agent.core.jvm.cpu.CPUProvider;
import org.apache.skywalking.apm.agent.core.jvm.gc.GCProvider;
import org.apache.skywalking.apm.agent.core.jvm.memory.MemoryProvider;
Expand All @@ -37,8 +38,8 @@
import org.apache.skywalking.apm.util.RunnableWithExceptionProtection;

/**
* The <code>JVMService</code> represents a timer, which collectors JVM cpu, memory, memorypool and gc info, and send
* the collected info to Collector through the channel provided by {@link GRPCChannelManager}
* The <code>JVMService</code> represents a timer, which collectors JVM cpu, memory, memorypool, gc, thread and class info,
* and send the collected info to Collector through the channel provided by {@link GRPCChannelManager}
*/
@DefaultImplementor
public class JVMService implements BootService, Runnable {
Expand Down Expand Up @@ -100,6 +101,7 @@ public void run() {
jvmBuilder.addAllMemoryPool(MemoryPoolProvider.INSTANCE.getMemoryPoolMetricsList());
jvmBuilder.addAllGc(GCProvider.INSTANCE.getGCList());
jvmBuilder.setThread(ThreadProvider.INSTANCE.getThreadMetrics());
jvmBuilder.setClazz(ClassProvider.INSTANCE.getClassMetrics());

sender.offer(jvmBuilder.build());
} catch (Exception e) {
Expand Down
@@ -0,0 +1,43 @@
/*
* 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.
*
*/

package org.apache.skywalking.apm.agent.core.jvm.clazz;

import java.lang.management.ClassLoadingMXBean;
import java.lang.management.ManagementFactory;
import org.apache.skywalking.apm.network.language.agent.v3.Class;

public enum ClassProvider {
INSTANCE;
private final ClassLoadingMXBean classLoadingMXBean;

ClassProvider() {
this.classLoadingMXBean = ManagementFactory.getClassLoadingMXBean();
}

public Class getClassMetrics() {
int loadedClassCount = classLoadingMXBean.getLoadedClassCount();
long unloadedClassCount = classLoadingMXBean.getUnloadedClassCount();
long totalLoadedClassCount = classLoadingMXBean.getTotalLoadedClassCount();
return Class.newBuilder().setLoadedClassCount(loadedClassCount)
.setUnloadedClassCount(unloadedClassCount)
.setTotalLoadedClassCount(totalLoadedClassCount)
.build();
}

}
Expand Up @@ -19,6 +19,7 @@
package org.apache.skywalking.apm.agent.core.jvm.thread;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import org.apache.skywalking.apm.network.language.agent.v3.Thread;

Expand All @@ -31,12 +32,63 @@ public enum ThreadProvider {
}

public Thread getThreadMetrics() {
int newThreadCount = 0;
int runnableThreadCount = 0;
int blockedThreadCount = 0;
int waitThreadCount = 0;
int timeWaitThreadCount = 0;
int terminatedThreadCount = 0;

ThreadInfo[] threadInfos = threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds());
if (threadInfos != null) {
for (ThreadInfo threadInfo : threadInfos) {
if (threadInfo != null) {
switch (threadInfo.getThreadState()) {
case NEW:
newThreadCount++;
break;
case RUNNABLE:
runnableThreadCount++;
break;
case BLOCKED:
blockedThreadCount++;
break;
case WAITING:
waitThreadCount++;
break;
case TIMED_WAITING:
timeWaitThreadCount++;
break;
case TERMINATED:
terminatedThreadCount++;
break;
default:
break;
}
} else {
terminatedThreadCount++;
}
}
}

int threadCount = threadMXBean.getThreadCount();
int daemonThreadCount = threadMXBean.getDaemonThreadCount();
int peakThreadCount = threadMXBean.getPeakThreadCount();
int deadlocked = threadMXBean.findDeadlockedThreads() != null ? threadMXBean.findDeadlockedThreads().length : 0;
int monitorDeadlocked = threadMXBean.findMonitorDeadlockedThreads() != null ?
threadMXBean.findMonitorDeadlockedThreads().length : 0;
return Thread.newBuilder().setLiveCount(threadCount)
.setDaemonCount(daemonThreadCount)
.setPeakCount(peakThreadCount).build();
.setPeakCount(peakThreadCount)
.setDeadlocked(deadlocked)
.setMonitorDeadlocked(monitorDeadlocked)
.setNewThreadCount(newThreadCount)
.setRunnableThreadCount(runnableThreadCount)
.setBlockedThreadCount(blockedThreadCount)
.setWaitThreadCount(waitThreadCount)
.setTimeWaitThreadCount(timeWaitThreadCount)
.setTerminatedThreadCount(terminatedThreadCount)
.build();
}

}
Expand Up @@ -21,6 +21,7 @@
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.apm.network.common.v3.CPU;
import org.apache.skywalking.apm.network.language.agent.v3.Class;
import org.apache.skywalking.apm.network.language.agent.v3.GC;
import org.apache.skywalking.apm.network.language.agent.v3.JVMMetric;
import org.apache.skywalking.apm.network.language.agent.v3.Memory;
Expand All @@ -33,6 +34,7 @@
import org.apache.skywalking.oap.server.core.source.GCPhrase;
import org.apache.skywalking.oap.server.core.source.MemoryPoolType;
import org.apache.skywalking.oap.server.core.source.ServiceInstanceJVMCPU;
import org.apache.skywalking.oap.server.core.source.ServiceInstanceJVMClass;
import org.apache.skywalking.oap.server.core.source.ServiceInstanceJVMGC;
import org.apache.skywalking.oap.server.core.source.ServiceInstanceJVMMemory;
import org.apache.skywalking.oap.server.core.source.ServiceInstanceJVMMemoryPool;
Expand Down Expand Up @@ -64,6 +66,8 @@ public void sendMetric(String service, String serviceInstance, JVMMetric metrics
service, serviceId, serviceInstance, serviceInstanceId, minuteTimeBucket, metrics.getGcList());
this.sendToThreadMetricProcess(
service, serviceId, serviceInstance, serviceInstanceId, minuteTimeBucket, metrics.getThread());
this.sendToClassMetricProcess(
service, serviceId, serviceInstance, serviceInstanceId, minuteTimeBucket, metrics.getClazz());
}

private void sendToCpuMetricProcess(String service,
Expand Down Expand Up @@ -193,7 +197,33 @@ private void sendToThreadMetricProcess(String service,
serviceInstanceJVMThread.setLiveCount(thread.getLiveCount());
serviceInstanceJVMThread.setDaemonCount(thread.getDaemonCount());
serviceInstanceJVMThread.setPeakCount(thread.getPeakCount());
serviceInstanceJVMThread.setDeadlocked(thread.getDeadlocked());
serviceInstanceJVMThread.setMonitorDeadlocked(thread.getMonitorDeadlocked());
serviceInstanceJVMThread.setNewThreadCount(thread.getNewThreadCount());
serviceInstanceJVMThread.setRunnableThreadCount(thread.getRunnableThreadCount());
serviceInstanceJVMThread.setBlockedThreadCount(thread.getBlockedThreadCount());
serviceInstanceJVMThread.setWaitThreadCount(thread.getWaitThreadCount());
serviceInstanceJVMThread.setTimeWaitThreadCount(thread.getTimeWaitThreadCount());
serviceInstanceJVMThread.setTerminatedThreadCount(thread.getTerminatedThreadCount());
serviceInstanceJVMThread.setTimeBucket(timeBucket);
sourceReceiver.receive(serviceInstanceJVMThread);
}

private void sendToClassMetricProcess(String service,
String serviceId,
String serviceInstance,
String serviceInstanceId,
long timeBucket,
Class clazz) {
ServiceInstanceJVMClass serviceInstanceJVMClass = new ServiceInstanceJVMClass();
serviceInstanceJVMClass.setId(serviceInstanceId);
serviceInstanceJVMClass.setName(serviceInstance);
serviceInstanceJVMClass.setServiceId(serviceId);
serviceInstanceJVMClass.setServiceName(service);
serviceInstanceJVMClass.setLoadedClassCount(clazz.getLoadedClassCount());
serviceInstanceJVMClass.setUnloadedClassCount(clazz.getUnloadedClassCount());
serviceInstanceJVMClass.setTotalLoadedClassCount(clazz.getTotalLoadedClassCount());
serviceInstanceJVMClass.setTimeBucket(timeBucket);
sourceReceiver.receive(serviceInstanceJVMClass);
}
}
Expand Up @@ -39,6 +39,7 @@ SRC_SERVICE_INSTANCE_JVM_MEMORY: 'ServiceInstanceJVMMemory';
SRC_SERVICE_INSTANCE_JVM_MEMORY_POOL: 'ServiceInstanceJVMMemoryPool';
SRC_SERVICE_INSTANCE_JVM_GC: 'ServiceInstanceJVMGC';
SRC_SERVICE_INSTANCE_JVM_THREAD: 'ServiceInstanceJVMThread';
SRC_SERVICE_INSTANCE_JVM_CLASS:'ServiceInstanceJVMClass';
SRC_DATABASE_ACCESS: 'DatabaseAccess';
SRC_SERVICE_INSTANCE_CLR_CPU: 'ServiceInstanceCLRCPU';
SRC_SERVICE_INSTANCE_CLR_GC: 'ServiceInstanceCLRGC';
Expand Down
Expand Up @@ -53,7 +53,7 @@ source
: SRC_ALL | SRC_SERVICE | SRC_DATABASE_ACCESS | SRC_SERVICE_INSTANCE | SRC_ENDPOINT |
SRC_SERVICE_RELATION | SRC_SERVICE_INSTANCE_RELATION | SRC_ENDPOINT_RELATION |
SRC_SERVICE_INSTANCE_CLR_CPU | SRC_SERVICE_INSTANCE_CLR_GC | SRC_SERVICE_INSTANCE_CLR_THREAD |
SRC_SERVICE_INSTANCE_JVM_CPU | SRC_SERVICE_INSTANCE_JVM_MEMORY | SRC_SERVICE_INSTANCE_JVM_MEMORY_POOL | SRC_SERVICE_INSTANCE_JVM_GC | SRC_SERVICE_INSTANCE_JVM_THREAD |// JVM source of service instance
SRC_SERVICE_INSTANCE_JVM_CPU | SRC_SERVICE_INSTANCE_JVM_MEMORY | SRC_SERVICE_INSTANCE_JVM_MEMORY_POOL | SRC_SERVICE_INSTANCE_JVM_GC | SRC_SERVICE_INSTANCE_JVM_THREAD | SRC_SERVICE_INSTANCE_JVM_CLASS |// JVM source of service instance
SRC_ENVOY_INSTANCE_METRIC |
SRC_BROWSER_APP_PERF | SRC_BROWSER_APP_PAGE_PERF | SRC_BROWSER_APP_SINGLE_VERSION_PERF |
SRC_BROWSER_APP_TRAFFIC | SRC_BROWSER_APP_PAGE_TRAFFIC | SRC_BROWSER_APP_SINGLE_VERSION_TRAFFIC |
Expand Down
Expand Up @@ -28,4 +28,15 @@ instance_jvm_young_gc_count = from(ServiceInstanceJVMGC.count).filter(phrase ==
instance_jvm_old_gc_count = from(ServiceInstanceJVMGC.count).filter(phrase == GCPhrase.OLD).sum();
instance_jvm_thread_live_count = from(ServiceInstanceJVMThread.liveCount).longAvg();
instance_jvm_thread_daemon_count = from(ServiceInstanceJVMThread.daemonCount).longAvg();
instance_jvm_thread_peak_count = from(ServiceInstanceJVMThread.peakCount).longAvg();
instance_jvm_thread_peak_count = from(ServiceInstanceJVMThread.peakCount).longAvg();
instance_jvm_thread_deadlocked = from(ServiceInstanceJVMThread.deadlocked).longAvg();
instance_jvm_thread_monitor_deadlocked = from(ServiceInstanceJVMThread.monitorDeadlocked).longAvg();
instance_jvm_thread_new_thread_count = from(ServiceInstanceJVMThread.newThreadCount).longAvg();
instance_jvm_thread_runnable_thread_count = from(ServiceInstanceJVMThread.runnableThreadCount).longAvg();
instance_jvm_thread_blocked_thread_count = from(ServiceInstanceJVMThread.blockedThreadCount).longAvg();
instance_jvm_thread_wait_thread_count = from(ServiceInstanceJVMThread.waitThreadCount).longAvg();
instance_jvm_thread_time_wait_thread_count = from(ServiceInstanceJVMThread.timeWaitThreadCount).longAvg();
instance_jvm_thread_terminated_thread_count = from(ServiceInstanceJVMThread.terminatedThreadCount).longAvg();
instance_jvm_class_loaded_class_count = from(ServiceInstanceJVMClass.loadedClassCount).longAvg();
instance_jvm_class_unloaded_class_count = from(ServiceInstanceJVMClass.unloadedClassCount).longAvg();
instance_jvm_class_total_loaded_class_count = from(ServiceInstanceJVMClass.totalLoadedClassCount).longAvg();
Expand Up @@ -398,7 +398,29 @@ templates:
"metricType": "REGULAR_VALUE",
"queryMetricType": "readMetricsValues",
"chartType": "ChartLine",
"metricName": "instance_jvm_thread_live_count, instance_jvm_thread_daemon_count, instance_jvm_thread_peak_count"
"metricName": "instance_jvm_thread_live_count, instance_jvm_thread_daemon_count, instance_jvm_thread_peak_count, instance_jvm_thread_deadlocked, instance_jvm_thread_monitor_deadlocked"
},
{
"width": 3,
"title": "JVM Thread State Count (Java Service)",
"height": "250",
"entityType": "ServiceInstance",
"independentSelector": false,
"metricType": "REGULAR_VALUE",
"metricName": "instance_jvm_thread_new_thread_count, instance_jvm_thread_runnable_thread_count, instance_jvm_thread_blocked_thread_count, instance_jvm_thread_wait_thread_count, instance_jvm_thread_time_wait_thread_count, instance_jvm_thread_terminated_thread_count",
"queryMetricType": "readMetricsValues",
"chartType": "ChartBar"
},
{
"width": 3,
"title": "JVM Class Count (Java Service)",
"height": "250",
"entityType": "ServiceInstance",
"independentSelector": false,
"metricType": "REGULAR_VALUE",
"metricName": "instance_jvm_class_loaded_class_count, instance_jvm_class_unloaded_class_count, instance_jvm_class_total_loaded_class_count",
"queryMetricType": "readMetricsValues",
"chartType": "ChartArea"
},
{
"width": 3,
Expand Down
Expand Up @@ -83,6 +83,8 @@ public class DefaultScopeDefine {

public static final int EVENT = 43;

public static final int SERVICE_INSTANCE_JVM_CLASS = 44;

/**
* Catalog of scope, the metrics processor could use this to group all generated metrics by oal rt.
*/
Expand Down
@@ -0,0 +1,64 @@
/*
* 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.
*
*/

package org.apache.skywalking.oap.server.core.source;

import lombok.Getter;
import lombok.Setter;

import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.SERVICE_INSTANCE_CATALOG_NAME;
import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.SERVICE_INSTANCE_JVM_CLASS;

@ScopeDeclaration(id = SERVICE_INSTANCE_JVM_CLASS, name = "ServiceInstanceJVMClass", catalog = SERVICE_INSTANCE_CATALOG_NAME)
@ScopeDefaultColumn.VirtualColumnDefinition(fieldName = "entityId", columnName = "entity_id", isID = true, type = String.class)
public class ServiceInstanceJVMClass extends Source {
@Override
public int scope() {
return SERVICE_INSTANCE_JVM_CLASS;
}

@Override
public String getEntityId() {
return String.valueOf(id);
}

@Getter
@Setter
private String id;
@Getter
@Setter
@ScopeDefaultColumn.DefinedByField(columnName = "name", requireDynamicActive = true)
private String name;
@Getter
@Setter
@ScopeDefaultColumn.DefinedByField(columnName = "service_name", requireDynamicActive = true)
private String serviceName;
@Getter
@Setter
@ScopeDefaultColumn.DefinedByField(columnName = "service_id")
private String serviceId;
@Getter
@Setter
private long loadedClassCount;
@Getter
@Setter
private long unloadedClassCount;
@Getter
@Setter
private long totalLoadedClassCount;
}
Expand Up @@ -61,4 +61,28 @@ public String getEntityId() {
@Getter
@Setter
private long peakCount;
@Getter
@Setter
private long deadlocked;
@Getter
@Setter
private long monitorDeadlocked;
@Getter
@Setter
private long newThreadCount;
@Getter
@Setter
private long runnableThreadCount;
@Getter
@Setter
private long blockedThreadCount;
@Getter
@Setter
private long waitThreadCount;
@Getter
@Setter
private long timeWaitThreadCount;
@Getter
@Setter
private long terminatedThreadCount;
}

0 comments on commit 2e2a008

Please sign in to comment.