diff --git a/.github/workflows/e2e.compat.yaml b/.github/workflows/e2e.compat.yaml
index ff87efec6b61c90590839127b9af8d155789c04d..e67bdbf903bc49e92887051251671b8fc700f0ea 100644
--- a/.github/workflows/e2e.compat.yaml
+++ b/.github/workflows/e2e.compat.yaml
@@ -58,4 +58,4 @@ jobs:
if: env.SKIP_CI != 'true'
uses: ./.github/actions/e2e-test
with:
- test_class: org.apache.skywalking.e2e.simple.SimpleE2E
+ test_class: org.apache.skywalking.e2e.compat.CompatE2E
diff --git a/CHANGES.md b/CHANGES.md
index f8d8c7092d6510d3f76811c215953825caf2b1ea..3aeba6339711d9d06025869b86e9c1067f5da454 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -74,6 +74,7 @@ Release Notes.
* Replace zuul proxy with spring cloud gateway 2.x. in webapp module.
* Upgrade etcd cluster coordinator and dynamic configuration to v3.x.
* Configuration: Allow to configure server maximum request header size.
+* Add thread state metric and class loaded info metric to JVMMetric.
#### UI
diff --git a/apm-protocol/apm-network/src/main/proto b/apm-protocol/apm-network/src/main/proto
index 7da226cfced7fa4eb91c6528e8c30827288531a0..e626ee04850703c220f64b642d2893fa65572943 160000
--- a/apm-protocol/apm-network/src/main/proto
+++ b/apm-protocol/apm-network/src/main/proto
@@ -1 +1 @@
-Subproject commit 7da226cfced7fa4eb91c6528e8c30827288531a0
+Subproject commit e626ee04850703c220f64b642d2893fa65572943
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/JVMService.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/JVMService.java
index 736fccfc560264233ebcecd80ea52e7184a1e4c8..4c9b25ddbb7c04968d05c49566c352a18be98223 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/JVMService.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/JVMService.java
@@ -25,6 +25,7 @@ import org.apache.skywalking.apm.agent.core.boot.BootService;
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;
@@ -37,8 +38,8 @@ import org.apache.skywalking.apm.network.language.agent.v3.JVMMetric;
import org.apache.skywalking.apm.util.RunnableWithExceptionProtection;
/**
- * The JVMService
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 JVMService
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 {
@@ -100,6 +101,7 @@ public class JVMService implements BootService, Runnable {
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) {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/clazz/ClassProvider.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/clazz/ClassProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..769cadc9e09853f1e4b7e29c2e6db216d726934c
--- /dev/null
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/clazz/ClassProvider.java
@@ -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 totalUnloadedClassCount = classLoadingMXBean.getUnloadedClassCount();
+ long totalLoadedClassCount = classLoadingMXBean.getTotalLoadedClassCount();
+ return Class.newBuilder().setLoadedClassCount(loadedClassCount)
+ .setTotalUnloadedClassCount(totalUnloadedClassCount)
+ .setTotalLoadedClassCount(totalLoadedClassCount)
+ .build();
+ }
+
+}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/thread/ThreadProvider.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/thread/ThreadProvider.java
index 25243f27d23f5b21d5a3b2037fd7ce28887115f5..3e89ce78b853b92c3364c185b62f3c5e429e5bff 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/thread/ThreadProvider.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/thread/ThreadProvider.java
@@ -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;
@@ -31,12 +32,47 @@ public enum ThreadProvider {
}
public Thread getThreadMetrics() {
+ int runnableStateThreadCount = 0;
+ int blockedStateThreadCount = 0;
+ int waitingStateThreadCount = 0;
+ int timedWaitingStateThreadCount = 0;
+
+ ThreadInfo[] threadInfos = threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds(), 0);
+ if (threadInfos != null) {
+ for (ThreadInfo threadInfo : threadInfos) {
+ if (threadInfo == null) {
+ continue;
+ }
+ switch (threadInfo.getThreadState()) {
+ case RUNNABLE:
+ runnableStateThreadCount++;
+ break;
+ case BLOCKED:
+ blockedStateThreadCount++;
+ break;
+ case WAITING:
+ waitingStateThreadCount++;
+ break;
+ case TIMED_WAITING:
+ timedWaitingStateThreadCount++;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
int threadCount = threadMXBean.getThreadCount();
int daemonThreadCount = threadMXBean.getDaemonThreadCount();
int peakThreadCount = threadMXBean.getPeakThreadCount();
return Thread.newBuilder().setLiveCount(threadCount)
.setDaemonCount(daemonThreadCount)
- .setPeakCount(peakThreadCount).build();
+ .setPeakCount(peakThreadCount)
+ .setRunnableStateThreadCount(runnableStateThreadCount)
+ .setBlockedStateThreadCount(blockedStateThreadCount)
+ .setWaitingStateThreadCount(waitingStateThreadCount)
+ .setTimedWaitingStateThreadCount(timedWaitingStateThreadCount)
+ .build();
}
}
diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/jvm/clazz/ClassProviderBenchmark.java b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/jvm/clazz/ClassProviderBenchmark.java
new file mode 100644
index 0000000000000000000000000000000000000000..547e9ca63cb47147a752b0f2d0c5f1cd3194a5ba
--- /dev/null
+++ b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/jvm/clazz/ClassProviderBenchmark.java
@@ -0,0 +1,63 @@
+/*
+ * 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 org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.util.concurrent.TimeUnit;
+
+public class ClassProviderBenchmark {
+
+ @Benchmark
+ @Fork(value = 5, warmups = 3)
+ @OutputTimeUnit(TimeUnit.SECONDS)
+ @BenchmarkMode(Mode.Throughput)
+ public void getThreadMetrics(Blackhole bh) {
+ bh.consume(ClassProvider.INSTANCE.getClassMetrics());
+ }
+
+ public static void main(String[] args) throws Exception {
+ Options opt = new OptionsBuilder().include(ClassProviderBenchmark.class.getSimpleName())
+ .build();
+ new Runner(opt).run();
+ }
+
+ /**
+ # JMH version: 1.21
+ # VM version: JDK 1.8.0_231, Java HotSpot(TM) 64-Bit Server VM, 25.231-b11
+ # VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/bin/java
+ # VM options: -javaagent:/Users/switch/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/211.7442.40/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=52931:/Users/switch/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/211.7442.40/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8
+ # Warmup: 5 iterations, 10 s each
+ # Measurement: 5 iterations, 10 s each
+ # Timeout: 10 min per iteration
+ # Threads: 1 thread, will synchronize iterations
+ # Benchmark mode: Throughput, ops/time
+ *
+ * Benchmark Mode Cnt Score Error Units
+ * ClassProviderBenchmark.getThreadMetrics thrpt 25 6542809.978 ± 8794.520 ops/s
+ */
+}
\ No newline at end of file
diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/jvm/thread/ThreadProviderBenchmark.java b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/jvm/thread/ThreadProviderBenchmark.java
new file mode 100644
index 0000000000000000000000000000000000000000..e60c8f95690ad7681e333643e17c6a6a7c4fc728
--- /dev/null
+++ b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/jvm/thread/ThreadProviderBenchmark.java
@@ -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.apm.agent.core.jvm.thread;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.util.concurrent.TimeUnit;
+
+public class ThreadProviderBenchmark {
+
+ @Benchmark
+ @Fork(value = 5, warmups = 3)
+ @OutputTimeUnit(TimeUnit.SECONDS)
+ @BenchmarkMode(Mode.Throughput)
+ public void getThreadMetrics(Blackhole bh) {
+ bh.consume(ThreadProvider.INSTANCE.getThreadMetrics());
+ }
+
+ public static void main(String[] args) throws Exception {
+ Options opt = new OptionsBuilder().include(ThreadProviderBenchmark.class.getSimpleName())
+ .build();
+ new Runner(opt).run();
+ }
+
+ /**
+ * # JMH version: 1.21
+ * # VM version: JDK 1.8.0_231, Java HotSpot(TM) 64-Bit Server VM, 25.231-b11
+ * # VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/bin/java
+ * # VM options: -javaagent:/Users/switch/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/211.7442.40/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=52623:/Users/switch/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/211.7442.40/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8
+ * # Warmup: 5 iterations, 10 s each
+ * # Measurement: 5 iterations, 10 s each
+ * # Timeout: 10 min per iteration
+ * # Threads: 1 thread, will synchronize iterations
+ * # Benchmark mode: Throughput, ops/time
+ * # Benchmark: org.apache.skywalking.apm.agent.core.jvm.thread.ThreadProviderBenchmark.getThreadMetrics
+ *
+ * Benchmark Mode Cnt Score Error Units
+ * ThreadProviderBenchmark.getThreadMetrics thrpt 25 247393.607 ± 2493.640 ops/s
+ */
+}
\ No newline at end of file
diff --git a/docs/en/concepts-and-designs/scope-definitions.md b/docs/en/concepts-and-designs/scope-definitions.md
index 51b330a6d9f94eb2f20f230c0fc14d491f4362f7..812f777b36130ad1043785d0eb7d450c0fffa904 100644
--- a/docs/en/concepts-and-designs/scope-definitions.md
+++ b/docs/en/concepts-and-designs/scope-definitions.md
@@ -104,9 +104,23 @@ This calculates the metrics data if the service instance is a JVM and collects t
|---|---|---|---|
| name | The name of the service instance, such as `ip:port@Service Name`. **Note**: Currently, the native agent uses `uuid@ipv4` as the instance name, which does not assist in setting up a filter in aggregation. | | string|
| serviceName | The name of the service. | | string |
-| liveCount | The current number of live threads. | | int |
-| daemonCount | The current number of daemon threads. | | int |
-| peakCount | The current number of peak threads. | | int |
+| liveCount | The current number of live threads. | | long |
+| daemonCount | The current number of daemon threads. | | long |
+| peakCount | The current number of peak threads. | | long |
+| runnableStateThreadCount | The current number of threads in runnable state. | | long |
+| blockedStateThreadCount | The current number of threads in blocked state. | | long |
+| waitingStateThreadCount | The current number of threads in waiting state. | | long |
+| timedWaitingStateThreadCount | The current number of threads in time-waiting state. | | long |
+
+6. SCOPE `ServiceInstanceJVMClass`
+
+| Name | Remarks | Group Key | Type |
+|---|---|---|---|
+| name | The name of the service instance, such as `ip:port@Service Name`. **Note**: Currently, the native agent uses `uuid@ipv4` as the instance name, which does not assist in setting up a filter in aggregation. | | string|
+| serviceName | The name of the service. | | string |
+| loadedClassCount | The number of classes that are currently loaded in the JVM. | | long |
+| totalUnloadedClassCount | The total number of classes unloaded since the JVM has started execution. | | long |
+| totalLoadedClassCount | The total number of classes that have been loaded since the JVM has started execution. | | long |
### SCOPE `Endpoint`
diff --git a/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/jvm/JVMSourceDispatcher.java b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/jvm/JVMSourceDispatcher.java
index ad2d3600d91b12ff11e9825c039e4b31ac76f4b5..bed6241958e7a7d8cfe133f9984111f5e17d4085 100644
--- a/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/jvm/JVMSourceDispatcher.java
+++ b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/jvm/JVMSourceDispatcher.java
@@ -21,6 +21,7 @@ package org.apache.skywalking.oap.server.analyzer.provider.jvm;
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;
@@ -33,6 +34,7 @@ import org.apache.skywalking.oap.server.core.analysis.TimeBucket;
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;
@@ -64,6 +66,8 @@ public class JVMSourceDispatcher {
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,
@@ -193,7 +197,29 @@ public class JVMSourceDispatcher {
serviceInstanceJVMThread.setLiveCount(thread.getLiveCount());
serviceInstanceJVMThread.setDaemonCount(thread.getDaemonCount());
serviceInstanceJVMThread.setPeakCount(thread.getPeakCount());
+ serviceInstanceJVMThread.setRunnableStateThreadCount(thread.getRunnableStateThreadCount());
+ serviceInstanceJVMThread.setBlockedStateThreadCount(thread.getBlockedStateThreadCount());
+ serviceInstanceJVMThread.setWaitingStateThreadCount(thread.getWaitingStateThreadCount());
+ serviceInstanceJVMThread.setTimedWaitingStateThreadCount(thread.getTimedWaitingStateThreadCount());
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.setTotalUnloadedClassCount(clazz.getTotalUnloadedClassCount());
+ serviceInstanceJVMClass.setTotalLoadedClassCount(clazz.getTotalLoadedClassCount());
+ serviceInstanceJVMClass.setTimeBucket(timeBucket);
+ sourceReceiver.receive(serviceInstanceJVMClass);
+ }
}
diff --git a/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALLexer.g4 b/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALLexer.g4
index ea3976f64eb467df8e71e1fa0fe38e3842b92cb1..25654dacb7c305d233e76be049ff3c9d996b3768 100644
--- a/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALLexer.g4
+++ b/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALLexer.g4
@@ -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';
diff --git a/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALParser.g4 b/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALParser.g4
index 337d0ab56664c0b81fc2c0878e3c5d54504cb00a..050defc2f490eae704475fd604b81a1eba40f884 100644
--- a/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALParser.g4
+++ b/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALParser.g4
@@ -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 |
diff --git a/oap-server/server-bootstrap/src/main/resources/oal/java-agent.oal b/oap-server/server-bootstrap/src/main/resources/oal/java-agent.oal
index ca344605f88c362d26f8a4370422bae23df7591e..b7a3702dff521977db7948b4c3a36fded52930d7 100644
--- a/oap-server/server-bootstrap/src/main/resources/oal/java-agent.oal
+++ b/oap-server/server-bootstrap/src/main/resources/oal/java-agent.oal
@@ -28,4 +28,11 @@ 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();
\ No newline at end of file
+instance_jvm_thread_peak_count = from(ServiceInstanceJVMThread.peakCount).longAvg();
+instance_jvm_thread_runnable_state_thread_count = from(ServiceInstanceJVMThread.runnableStateThreadCount).longAvg();
+instance_jvm_thread_blocked_state_thread_count = from(ServiceInstanceJVMThread.blockedStateThreadCount).longAvg();
+instance_jvm_thread_waiting_state_thread_count = from(ServiceInstanceJVMThread.waitingStateThreadCount).longAvg();
+instance_jvm_thread_timed_waiting_state_thread_count = from(ServiceInstanceJVMThread.timedWaitingStateThreadCount).longAvg();
+instance_jvm_class_loaded_class_count = from(ServiceInstanceJVMClass.loadedClassCount).longAvg();
+instance_jvm_class_total_unloaded_class_count = from(ServiceInstanceJVMClass.totalUnloadedClassCount).longAvg();
+instance_jvm_class_total_loaded_class_count = from(ServiceInstanceJVMClass.totalLoadedClassCount).longAvg();
\ No newline at end of file
diff --git a/oap-server/server-bootstrap/src/main/resources/ui-initialized-templates/apm.yml b/oap-server/server-bootstrap/src/main/resources/ui-initialized-templates/apm.yml
index 901bd88538ba5dc7e47dc3fd3a77dc74f4cbdc11..5854c0798809b60f769e839753fbab1360d893c5 100644
--- a/oap-server/server-bootstrap/src/main/resources/ui-initialized-templates/apm.yml
+++ b/oap-server/server-bootstrap/src/main/resources/ui-initialized-templates/apm.yml
@@ -400,6 +400,28 @@ templates:
"chartType": "ChartLine",
"metricName": "instance_jvm_thread_live_count, instance_jvm_thread_daemon_count, instance_jvm_thread_peak_count"
},
+ {
+ "width": 3,
+ "title": "JVM Thread State Count (Java Service)",
+ "height": "250",
+ "entityType": "ServiceInstance",
+ "independentSelector": false,
+ "metricType": "REGULAR_VALUE",
+ "metricName": "instance_jvm_thread_runnable_state_thread_count, instance_jvm_thread_blocked_state_thread_count, instance_jvm_thread_waiting_state_thread_count, instance_jvm_thread_timed_waiting_state_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_total_unloaded_class_count, instance_jvm_class_total_loaded_class_count",
+ "queryMetricType": "readMetricsValues",
+ "chartType": "ChartArea"
+ },
{
"width": 3,
"title": "CLR CPU (.NET Service)",
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DefaultScopeDefine.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DefaultScopeDefine.java
index f87d82bf457fb38af5fe91a3ddd8151e8dcd6110..43f2fa5ef0348004fee659ce8f4f4eedc99cf833 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DefaultScopeDefine.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DefaultScopeDefine.java
@@ -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.
*/
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ServiceInstanceJVMClass.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ServiceInstanceJVMClass.java
new file mode 100644
index 0000000000000000000000000000000000000000..451619864be55afd99a54ad9af27e961751110d7
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ServiceInstanceJVMClass.java
@@ -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 totalUnloadedClassCount;
+ @Getter
+ @Setter
+ private long totalLoadedClassCount;
+}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ServiceInstanceJVMThread.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ServiceInstanceJVMThread.java
index 42ee6a2e203227f79d94b7a1e8cdeb9d0c373132..741d2ac2ae60be1b1fc83bd0bc9a23efab810447 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ServiceInstanceJVMThread.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ServiceInstanceJVMThread.java
@@ -61,4 +61,16 @@ public class ServiceInstanceJVMThread extends Source {
@Getter
@Setter
private long peakCount;
+ @Getter
+ @Setter
+ private long runnableStateThreadCount;
+ @Getter
+ @Setter
+ private long blockedStateThreadCount;
+ @Getter
+ @Setter
+ private long waitingStateThreadCount;
+ @Getter
+ @Setter
+ private long timedWaitingStateThreadCount;
}
diff --git a/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/metrics/MetricsQuery.java b/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/metrics/MetricsQuery.java
index 7117760df67ab636c2de3e7ffac4de57af4a7b1b..110a8ce28b261e068914c067773bba26bef1f80f 100644
--- a/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/metrics/MetricsQuery.java
+++ b/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/metrics/MetricsQuery.java
@@ -75,7 +75,22 @@ public class MetricsQuery extends AbstractQuery {
public static String INSTANCE_JVM_THREAD_LIVE_COUNT = "instance_jvm_thread_live_count";
public static String INSTANCE_JVM_THREAD_DAEMON_COUNT = "instance_jvm_thread_daemon_count";
public static String INSTANCE_JVM_THREAD_PEAK_COUNT = "instance_jvm_thread_peak_count";
+ public static String INSTANCE_JVM_THREAD_RUNNABLE_STATE_THREAD_COUNT = "instance_jvm_thread_runnable_state_thread_count";
+ public static String INSTANCE_JVM_CLASS_LOADED_CLASS_COUNT = "instance_jvm_class_loaded_class_count";
+ public static String INSTANCE_JVM_CLASS_TOTAL_LOADED_CLASS_COUNT = "instance_jvm_class_total_loaded_class_count";
public static String [] ALL_INSTANCE_JVM_METRICS = {
+ INSTANCE_JVM_CLASS_TOTAL_LOADED_CLASS_COUNT,
+ INSTANCE_JVM_CLASS_LOADED_CLASS_COUNT,
+ INSTANCE_JVM_THREAD_RUNNABLE_STATE_THREAD_COUNT,
+ INSTANCE_JVM_THREAD_LIVE_COUNT,
+ INSTANCE_JVM_THREAD_DAEMON_COUNT,
+ INSTANCE_JVM_THREAD_PEAK_COUNT,
+ INSTANCE_JVM_MEMORY_NOHEAP,
+ INSTANCE_JVM_MEMORY_HEAP_MAX,
+ INSTANCE_JVM_MEMORY_HEAP,
+ };
+
+ public static String [] ALL_INSTANCE_JVM_METRICS_COMPAT = {
INSTANCE_JVM_THREAD_LIVE_COUNT,
INSTANCE_JVM_THREAD_DAEMON_COUNT,
INSTANCE_JVM_THREAD_PEAK_COUNT,
diff --git a/test/e2e/e2e-protocol/src/main/proto b/test/e2e/e2e-protocol/src/main/proto
index 9a689b0188cbdc7bd8d6ddd99b4ad5283e82fe88..e626ee04850703c220f64b642d2893fa65572943 160000
--- a/test/e2e/e2e-protocol/src/main/proto
+++ b/test/e2e/e2e-protocol/src/main/proto
@@ -1 +1 @@
-Subproject commit 9a689b0188cbdc7bd8d6ddd99b4ad5283e82fe88
+Subproject commit e626ee04850703c220f64b642d2893fa65572943
diff --git a/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/compat/CompatE2E.java b/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/compat/CompatE2E.java
new file mode 100644
index 0000000000000000000000000000000000000000..7881254a890b887278ecbf4318bcec5f55e97c60
--- /dev/null
+++ b/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/compat/CompatE2E.java
@@ -0,0 +1,141 @@
+/*
+ * 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.e2e.compat;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.skywalking.e2e.annotation.ContainerHostAndPort;
+import org.apache.skywalking.e2e.annotation.DockerCompose;
+import org.apache.skywalking.e2e.base.SkyWalkingE2E;
+import org.apache.skywalking.e2e.common.HostAndPort;
+import org.apache.skywalking.e2e.retryable.RetryableTest;
+import org.apache.skywalking.e2e.service.Service;
+import org.apache.skywalking.e2e.service.ServicesMatcher;
+import org.apache.skywalking.e2e.service.ServicesQuery;
+import org.apache.skywalking.e2e.service.endpoint.Endpoints;
+import org.apache.skywalking.e2e.service.instance.Instances;
+import org.apache.skywalking.e2e.simple.SimpleE2EBase;
+import org.apache.skywalking.e2e.topo.ServiceInstanceTopology;
+import org.apache.skywalking.e2e.topo.ServiceInstanceTopologyMatcher;
+import org.apache.skywalking.e2e.topo.ServiceInstanceTopologyQuery;
+import org.apache.skywalking.e2e.topo.TopoMatcher;
+import org.apache.skywalking.e2e.topo.TopoQuery;
+import org.apache.skywalking.e2e.topo.Topology;
+import org.apache.skywalking.e2e.trace.Trace;
+import org.apache.skywalking.e2e.trace.TracesMatcher;
+import org.apache.skywalking.e2e.trace.TracesQuery;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.testcontainers.containers.DockerComposeContainer;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_INSTANCE_JVM_METRICS_COMPAT;
+import static org.apache.skywalking.e2e.utils.Times.now;
+import static org.apache.skywalking.e2e.utils.Yamls.load;
+
+@Slf4j
+@SkyWalkingE2E
+public class CompatE2E extends SimpleE2EBase {
+ @SuppressWarnings("unused")
+ @DockerCompose("docker/simple/${SW_SIMPLE_CASE}/docker-compose.yml")
+ protected DockerComposeContainer> justForSideEffects;
+
+ @SuppressWarnings("unused")
+ @ContainerHostAndPort(name = "ui", port = 8080)
+ protected HostAndPort swWebappHostPort;
+
+ @SuppressWarnings("unused")
+ @ContainerHostAndPort(name = "provider", port = 9090)
+ protected HostAndPort serviceHostPort;
+
+ @BeforeAll
+ void setUp() throws Exception {
+ queryClient(swWebappHostPort);
+
+ trafficController(serviceHostPort, "/users");
+ }
+
+ @AfterAll
+ public void tearDown() {
+ trafficController.stop();
+ }
+
+ @RetryableTest
+ void services() throws Exception {
+ List services = graphql.services(new ServicesQuery().start(startTime).end(now()));
+
+ services = services.stream().filter(s -> !s.getLabel().equals("oap::oap-server")).collect(Collectors.toList());
+ LOGGER.info("services: {}", services);
+
+ load("expected/simple/services.yml").as(ServicesMatcher.class).verify(services);
+
+ for (final Service service : services) {
+ LOGGER.info("verifying service instances: {}", service);
+
+ verifyServiceMetrics(service);
+
+ final Instances instances = verifyServiceInstances(service);
+
+ verifyInstancesMetrics(instances);
+
+ verifyInstancesJVMMetrics(instances, ALL_INSTANCE_JVM_METRICS_COMPAT);
+
+ final Endpoints endpoints = verifyServiceEndpoints(service);
+
+ verifyEndpointsMetrics(endpoints);
+ }
+ }
+
+ @RetryableTest
+ void traces() throws Exception {
+ final List traces = graphql.traces(new TracesQuery().start(startTime).end(now()).orderByDuration());
+
+ LOGGER.info("traces: {}", traces);
+
+ load("expected/simple/traces.yml").as(TracesMatcher.class).verifyLoosely(traces);
+ }
+
+ @RetryableTest
+ void topology() throws Exception {
+ final Topology topology = graphql.topo(new TopoQuery().stepByMinute().start(startTime.minusDays(1)).end(now()));
+
+ LOGGER.info("topology: {}", topology);
+
+ load("expected/simple/topo.yml").as(TopoMatcher.class).verify(topology);
+
+ verifyServiceRelationMetrics(topology.getCalls());
+ }
+
+ @RetryableTest
+ void serviceInstances() throws Exception {
+ final ServiceInstanceTopology topology = graphql.serviceInstanceTopo(
+ new ServiceInstanceTopologyQuery().stepByMinute()
+ .start(startTime.minusDays(1))
+ .end(now())
+ .clientServiceId("VXNlcg==.0")
+ .serverServiceId("WW91cl9BcHBsaWNhdGlvbk5hbWU=.1"));
+
+ LOGGER.info("instance topology: {}", topology);
+
+ load("expected/simple/serviceInstanceTopo.yml").as(ServiceInstanceTopologyMatcher.class).verify(topology);
+
+ verifyServiceInstanceRelationMetrics(topology.getCalls());
+ }
+}
diff --git a/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/kafka/KafkaE2E.java b/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/kafka/KafkaE2E.java
index 89716aac0402914775b5d15932cc9e1652d4be1d..25c3e03ab47784aa6bed41a05f307a09a1fa0712 100644
--- a/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/kafka/KafkaE2E.java
+++ b/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/kafka/KafkaE2E.java
@@ -24,11 +24,9 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.e2e.annotation.ContainerHostAndPort;
import org.apache.skywalking.e2e.annotation.DockerCompose;
import org.apache.skywalking.e2e.base.SkyWalkingE2E;
-import org.apache.skywalking.e2e.base.SkyWalkingTestAdapter;
import org.apache.skywalking.e2e.common.HostAndPort;
import org.apache.skywalking.e2e.metrics.AtLeastOneOfMetricsMatcher;
import org.apache.skywalking.e2e.metrics.Metrics;
-import org.apache.skywalking.e2e.metrics.MetricsQuery;
import org.apache.skywalking.e2e.metrics.MetricsValueMatcher;
import org.apache.skywalking.e2e.metrics.ReadLabeledMetricsQuery;
import org.apache.skywalking.e2e.metrics.ReadMetrics;
@@ -37,15 +35,12 @@ import org.apache.skywalking.e2e.retryable.RetryableTest;
import org.apache.skywalking.e2e.service.Service;
import org.apache.skywalking.e2e.service.ServicesMatcher;
import org.apache.skywalking.e2e.service.ServicesQuery;
-import org.apache.skywalking.e2e.service.endpoint.Endpoint;
-import org.apache.skywalking.e2e.service.endpoint.EndpointQuery;
import org.apache.skywalking.e2e.service.endpoint.Endpoints;
-import org.apache.skywalking.e2e.service.endpoint.EndpointsMatcher;
import org.apache.skywalking.e2e.service.instance.Instance;
import org.apache.skywalking.e2e.service.instance.Instances;
import org.apache.skywalking.e2e.service.instance.InstancesMatcher;
import org.apache.skywalking.e2e.service.instance.InstancesQuery;
-import org.apache.skywalking.e2e.topo.Call;
+import org.apache.skywalking.e2e.simple.SimpleE2EBase;
import org.apache.skywalking.e2e.topo.ServiceInstanceTopology;
import org.apache.skywalking.e2e.topo.ServiceInstanceTopologyMatcher;
import org.apache.skywalking.e2e.topo.ServiceInstanceTopologyQuery;
@@ -59,18 +54,6 @@ import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.testcontainers.containers.DockerComposeContainer;
-import static org.apache.skywalking.e2e.metrics.MetricsMatcher.verifyMetrics;
-import static org.apache.skywalking.e2e.metrics.MetricsMatcher.verifyPercentileMetrics;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_ENDPOINT_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_ENDPOINT_MULTIPLE_LINEAR_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_INSTANCE_JVM_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_INSTANCE_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_INSTANCE_RELATION_CLIENT_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_INSTANCE_RELATION_SERVER_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_MULTIPLE_LINEAR_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_RELATION_CLIENT_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_RELATION_SERVER_METRICS;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SO11Y_LABELED_METRICS;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SO11Y_LINER_METRICS;
import static org.apache.skywalking.e2e.utils.Times.now;
@@ -78,7 +61,7 @@ import static org.apache.skywalking.e2e.utils.Yamls.load;
@Slf4j
@SkyWalkingE2E
-public class KafkaE2E extends SkyWalkingTestAdapter {
+public class KafkaE2E extends SimpleE2EBase {
@SuppressWarnings("unused")
@DockerCompose({
@@ -221,148 +204,4 @@ public class KafkaE2E extends SkyWalkingTestAdapter {
}
}
}
-
- private Instances verifyServiceInstances(final Service service) throws Exception {
- final Instances instances = graphql.instances(
- new InstancesQuery().serviceId(service.getKey()).start(startTime).end(now())
- );
-
- LOGGER.info("instances: {}", instances);
-
- load("expected/simple/instances.yml").as(InstancesMatcher.class).verify(instances);
-
- return instances;
- }
-
- private Endpoints verifyServiceEndpoints(final Service service) throws Exception {
- final Endpoints endpoints = graphql.endpoints(new EndpointQuery().serviceId(service.getKey()));
-
- LOGGER.info("endpoints: {}", endpoints);
-
- load("expected/simple/endpoints.yml").as(EndpointsMatcher.class).verify(endpoints);
-
- return endpoints;
- }
-
- private void verifyInstancesMetrics(final Instances instances) throws Exception {
- for (Instance instance : instances.getInstances()) {
- for (String metricsName : ALL_INSTANCE_METRICS) {
- LOGGER.info("verifying service instance response time: {}", instance);
- final Metrics instanceMetrics = graphql.metrics(
- new MetricsQuery().stepByMinute().metricsName(metricsName).id(instance.getKey())
- );
-
- LOGGER.info("instance metrics: {}", instanceMetrics);
-
- final AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
- final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
- greaterThanZero.setValue("gt 0");
- instanceRespTimeMatcher.setValue(greaterThanZero);
- instanceRespTimeMatcher.verify(instanceMetrics);
- LOGGER.info("{}: {}", metricsName, instanceMetrics);
- }
- }
- }
-
- private void verifyInstancesJVMMetrics(final Instances instances) throws Exception {
- for (Instance instance : instances.getInstances()) {
- for (String metricsName : ALL_INSTANCE_JVM_METRICS) {
- LOGGER.info("verifying service instance response time: {}", instance);
- final Metrics instanceJVMMetrics = graphql.metrics(
- new MetricsQuery().stepByMinute().metricsName(metricsName).id(instance.getKey())
- );
-
- LOGGER.info("instance jvm metrics: {}", instanceJVMMetrics);
-
- final AtLeastOneOfMetricsMatcher instanceThreadMatcher = new AtLeastOneOfMetricsMatcher();
- final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
- greaterThanZero.setValue("gt 0");
- instanceThreadMatcher.setValue(greaterThanZero);
- instanceThreadMatcher.verify(instanceJVMMetrics);
- LOGGER.info("{}: {}", metricsName, instanceJVMMetrics);
- }
- }
- }
-
- private void verifyEndpointsMetrics(final Endpoints endpoints) throws Exception {
- for (Endpoint endpoint : endpoints.getEndpoints()) {
- if (!endpoint.getLabel().equals("/users")) {
- continue;
- }
- for (final String metricName : ALL_ENDPOINT_METRICS) {
- LOGGER.info("verifying endpoint {}: {}", endpoint, metricName);
-
- final Metrics metrics = graphql.metrics(
- new MetricsQuery().stepByMinute().metricsName(metricName).id(endpoint.getKey())
- );
-
- LOGGER.info("metrics: {}", metrics);
-
- final AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
- final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
- greaterThanZero.setValue("gt 0");
- instanceRespTimeMatcher.setValue(greaterThanZero);
- instanceRespTimeMatcher.verify(metrics);
-
- LOGGER.info("{}: {}", metricName, metrics);
- }
- for (String metricName : ALL_ENDPOINT_MULTIPLE_LINEAR_METRICS) {
- verifyPercentileMetrics(graphql, metricName, endpoint.getKey(), startTime);
- }
- }
- }
-
- private void verifyServiceMetrics(final Service service) throws Exception {
- for (String metricName : ALL_SERVICE_METRICS) {
- LOGGER.info("verifying service {}, metrics: {}", service, metricName);
- final Metrics serviceMetrics = graphql.metrics(
- new MetricsQuery().stepByMinute().metricsName(metricName).id(service.getKey())
- );
- LOGGER.info("serviceMetrics: {}", serviceMetrics);
- final AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
- final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
- greaterThanZero.setValue("gt 0");
- instanceRespTimeMatcher.setValue(greaterThanZero);
- instanceRespTimeMatcher.verify(serviceMetrics);
- LOGGER.info("{}: {}", metricName, serviceMetrics);
- }
-
- for (String metricName : ALL_SERVICE_MULTIPLE_LINEAR_METRICS) {
- verifyPercentileMetrics(graphql, metricName, service.getKey(), startTime);
- }
- }
-
- private void verifyServiceInstanceRelationMetrics(final List calls) throws Exception {
- verifyRelationMetrics(
- calls, ALL_SERVICE_INSTANCE_RELATION_CLIENT_METRICS,
- ALL_SERVICE_INSTANCE_RELATION_SERVER_METRICS
- );
- }
-
- private void verifyServiceRelationMetrics(final List calls) throws Exception {
- verifyRelationMetrics(calls, ALL_SERVICE_RELATION_CLIENT_METRICS, ALL_SERVICE_RELATION_SERVER_METRICS);
- }
-
- private void verifyRelationMetrics(final List calls,
- final String[] relationClientMetrics,
- final String[] relationServerMetrics) throws Exception {
- for (Call call : calls) {
- for (String detectPoint : call.getDetectPoints()) {
- switch (detectPoint) {
- case "CLIENT": {
- for (String metricName : relationClientMetrics) {
- verifyMetrics(graphql, metricName, call.getId(), startTime);
- }
- break;
- }
- case "SERVER": {
- for (String metricName : relationServerMetrics) {
- verifyMetrics(graphql, metricName, call.getId(), startTime);
- }
- break;
- }
- }
- }
- }
- }
}
diff --git a/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/simple/SimpleE2E.java b/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/simple/SimpleE2E.java
index 0a80655077525cf3c50258a55b27631ab355a22e..f39dee35e189f73af89395d333f6a166944f0ae9 100644
--- a/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/simple/SimpleE2E.java
+++ b/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/simple/SimpleE2E.java
@@ -24,25 +24,13 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.e2e.annotation.ContainerHostAndPort;
import org.apache.skywalking.e2e.annotation.DockerCompose;
import org.apache.skywalking.e2e.base.SkyWalkingE2E;
-import org.apache.skywalking.e2e.base.SkyWalkingTestAdapter;
import org.apache.skywalking.e2e.common.HostAndPort;
-import org.apache.skywalking.e2e.metrics.AtLeastOneOfMetricsMatcher;
-import org.apache.skywalking.e2e.metrics.Metrics;
-import org.apache.skywalking.e2e.metrics.MetricsQuery;
-import org.apache.skywalking.e2e.metrics.MetricsValueMatcher;
import org.apache.skywalking.e2e.retryable.RetryableTest;
import org.apache.skywalking.e2e.service.Service;
import org.apache.skywalking.e2e.service.ServicesMatcher;
import org.apache.skywalking.e2e.service.ServicesQuery;
-import org.apache.skywalking.e2e.service.endpoint.Endpoint;
-import org.apache.skywalking.e2e.service.endpoint.EndpointQuery;
import org.apache.skywalking.e2e.service.endpoint.Endpoints;
-import org.apache.skywalking.e2e.service.endpoint.EndpointsMatcher;
-import org.apache.skywalking.e2e.service.instance.Instance;
import org.apache.skywalking.e2e.service.instance.Instances;
-import org.apache.skywalking.e2e.service.instance.InstancesMatcher;
-import org.apache.skywalking.e2e.service.instance.InstancesQuery;
-import org.apache.skywalking.e2e.topo.Call;
import org.apache.skywalking.e2e.topo.ServiceInstanceTopology;
import org.apache.skywalking.e2e.topo.ServiceInstanceTopologyMatcher;
import org.apache.skywalking.e2e.topo.ServiceInstanceTopologyQuery;
@@ -56,18 +44,6 @@ import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.testcontainers.containers.DockerComposeContainer;
-import static org.apache.skywalking.e2e.metrics.MetricsMatcher.verifyMetrics;
-import static org.apache.skywalking.e2e.metrics.MetricsMatcher.verifyPercentileMetrics;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_ENDPOINT_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_ENDPOINT_MULTIPLE_LINEAR_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_INSTANCE_JVM_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_INSTANCE_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_INSTANCE_RELATION_CLIENT_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_INSTANCE_RELATION_SERVER_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_MULTIPLE_LINEAR_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_RELATION_CLIENT_METRICS;
-import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_RELATION_SERVER_METRICS;
import static org.apache.skywalking.e2e.utils.Times.now;
import static org.apache.skywalking.e2e.utils.Yamls.load;
@@ -107,7 +83,7 @@ import static org.apache.skywalking.e2e.utils.Yamls.load;
*/
@Slf4j
@SkyWalkingE2E
-public class SimpleE2E extends SkyWalkingTestAdapter {
+public class SimpleE2E extends SimpleE2EBase {
@SuppressWarnings("unused")
@DockerCompose("docker/simple/${SW_SIMPLE_CASE}/docker-compose.yml")
protected DockerComposeContainer> justForSideEffects;
@@ -193,148 +169,4 @@ public class SimpleE2E extends SkyWalkingTestAdapter {
verifyServiceInstanceRelationMetrics(topology.getCalls());
}
-
- private Instances verifyServiceInstances(final Service service) throws Exception {
- final Instances instances = graphql.instances(
- new InstancesQuery().serviceId(service.getKey()).start(startTime).end(now())
- );
-
- LOGGER.info("instances: {}", instances);
-
- load("expected/simple/instances.yml").as(InstancesMatcher.class).verify(instances);
-
- return instances;
- }
-
- private Endpoints verifyServiceEndpoints(final Service service) throws Exception {
- final Endpoints endpoints = graphql.endpoints(new EndpointQuery().serviceId(service.getKey()));
-
- LOGGER.info("endpoints: {}", endpoints);
-
- load("expected/simple/endpoints.yml").as(EndpointsMatcher.class).verify(endpoints);
-
- return endpoints;
- }
-
- private void verifyInstancesMetrics(final Instances instances) throws Exception {
- for (Instance instance : instances.getInstances()) {
- for (String metricsName : ALL_INSTANCE_METRICS) {
- LOGGER.info("verifying service instance response time: {}", instance);
- final Metrics instanceMetrics = graphql.metrics(
- new MetricsQuery().stepByMinute().metricsName(metricsName).id(instance.getKey())
- );
-
- LOGGER.info("instance metrics: {}", instanceMetrics);
-
- final AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
- final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
- greaterThanZero.setValue("gt 0");
- instanceRespTimeMatcher.setValue(greaterThanZero);
- instanceRespTimeMatcher.verify(instanceMetrics);
- LOGGER.info("{}: {}", metricsName, instanceMetrics);
- }
- }
- }
-
- private void verifyInstancesJVMMetrics(final Instances instances) throws Exception {
- for (Instance instance : instances.getInstances()) {
- for (String metricsName : ALL_INSTANCE_JVM_METRICS) {
- LOGGER.info("verifying service instance response time: {}", instance);
- final Metrics instanceJVMMetrics = graphql.metrics(
- new MetricsQuery().stepByMinute().metricsName(metricsName).id(instance.getKey())
- );
-
- LOGGER.info("instance jvm metrics: {}", instanceJVMMetrics);
-
- final AtLeastOneOfMetricsMatcher instanceMatcher = new AtLeastOneOfMetricsMatcher();
- final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
- greaterThanZero.setValue("gt 0");
- instanceMatcher.setValue(greaterThanZero);
- instanceMatcher.verify(instanceJVMMetrics);
- LOGGER.info("{}: {}", metricsName, instanceJVMMetrics);
- }
- }
- }
-
- private void verifyEndpointsMetrics(final Endpoints endpoints) throws Exception {
- for (Endpoint endpoint : endpoints.getEndpoints()) {
- if (!endpoint.getLabel().equals("/users")) {
- continue;
- }
- for (final String metricName : ALL_ENDPOINT_METRICS) {
- LOGGER.info("verifying endpoint {}: {}", endpoint, metricName);
-
- final Metrics metrics = graphql.metrics(
- new MetricsQuery().stepByMinute().metricsName(metricName).id(endpoint.getKey())
- );
-
- LOGGER.info("metrics: {}", metrics);
-
- final AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
- final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
- greaterThanZero.setValue("gt 0");
- instanceRespTimeMatcher.setValue(greaterThanZero);
- instanceRespTimeMatcher.verify(metrics);
-
- LOGGER.info("{}: {}", metricName, metrics);
- }
- for (String metricName : ALL_ENDPOINT_MULTIPLE_LINEAR_METRICS) {
- verifyPercentileMetrics(graphql, metricName, endpoint.getKey(), startTime);
- }
- }
- }
-
- private void verifyServiceMetrics(final Service service) throws Exception {
- for (String metricName : ALL_SERVICE_METRICS) {
- LOGGER.info("verifying service {}, metrics: {}", service, metricName);
- final Metrics serviceMetrics = graphql.metrics(
- new MetricsQuery().stepByMinute().metricsName(metricName).id(service.getKey())
- );
- LOGGER.info("serviceMetrics: {}", serviceMetrics);
- final AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
- final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
- greaterThanZero.setValue("gt 0");
- instanceRespTimeMatcher.setValue(greaterThanZero);
- instanceRespTimeMatcher.verify(serviceMetrics);
- LOGGER.info("{}: {}", metricName, serviceMetrics);
- }
-
- for (String metricName : ALL_SERVICE_MULTIPLE_LINEAR_METRICS) {
- verifyPercentileMetrics(graphql, metricName, service.getKey(), startTime);
- }
- }
-
- private void verifyServiceInstanceRelationMetrics(final List calls) throws Exception {
- verifyRelationMetrics(
- calls, ALL_SERVICE_INSTANCE_RELATION_CLIENT_METRICS,
- ALL_SERVICE_INSTANCE_RELATION_SERVER_METRICS
- );
- }
-
- private void verifyServiceRelationMetrics(final List calls) throws Exception {
- verifyRelationMetrics(calls, ALL_SERVICE_RELATION_CLIENT_METRICS, ALL_SERVICE_RELATION_SERVER_METRICS);
- }
-
- private void verifyRelationMetrics(final List calls,
- final String[] relationClientMetrics,
- final String[] relationServerMetrics) throws Exception {
- for (Call call : calls) {
- for (String detectPoint : call.getDetectPoints()) {
- switch (detectPoint) {
- case "CLIENT": {
- for (String metricName : relationClientMetrics) {
- verifyMetrics(graphql, metricName, call.getId(), startTime);
- }
- break;
- }
- case "SERVER": {
- for (String metricName : relationServerMetrics) {
- verifyMetrics(graphql, metricName, call.getId(), startTime);
- }
- break;
- }
- }
- }
- }
- }
}
diff --git a/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/simple/SimpleE2EBase.java b/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/simple/SimpleE2EBase.java
new file mode 100644
index 0000000000000000000000000000000000000000..abd2ea35a43b3a0610d84cd82571ee029a3a045f
--- /dev/null
+++ b/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/simple/SimpleE2EBase.java
@@ -0,0 +1,202 @@
+/*
+ * 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.e2e.simple;
+
+import java.util.List;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.skywalking.e2e.base.SkyWalkingTestAdapter;
+import org.apache.skywalking.e2e.metrics.AtLeastOneOfMetricsMatcher;
+import org.apache.skywalking.e2e.metrics.Metrics;
+import org.apache.skywalking.e2e.metrics.MetricsQuery;
+import org.apache.skywalking.e2e.metrics.MetricsValueMatcher;
+import org.apache.skywalking.e2e.service.Service;
+import org.apache.skywalking.e2e.service.endpoint.Endpoint;
+import org.apache.skywalking.e2e.service.endpoint.EndpointQuery;
+import org.apache.skywalking.e2e.service.endpoint.Endpoints;
+import org.apache.skywalking.e2e.service.endpoint.EndpointsMatcher;
+import org.apache.skywalking.e2e.service.instance.Instance;
+import org.apache.skywalking.e2e.service.instance.Instances;
+import org.apache.skywalking.e2e.service.instance.InstancesMatcher;
+import org.apache.skywalking.e2e.service.instance.InstancesQuery;
+import org.apache.skywalking.e2e.topo.Call;
+
+import static org.apache.skywalking.e2e.metrics.MetricsMatcher.verifyMetrics;
+import static org.apache.skywalking.e2e.metrics.MetricsMatcher.verifyPercentileMetrics;
+import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_ENDPOINT_METRICS;
+import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_ENDPOINT_MULTIPLE_LINEAR_METRICS;
+import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_INSTANCE_JVM_METRICS;
+import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_INSTANCE_METRICS;
+import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_INSTANCE_RELATION_CLIENT_METRICS;
+import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_INSTANCE_RELATION_SERVER_METRICS;
+import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_METRICS;
+import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_MULTIPLE_LINEAR_METRICS;
+import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_RELATION_CLIENT_METRICS;
+import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_RELATION_SERVER_METRICS;
+import static org.apache.skywalking.e2e.utils.Times.now;
+import static org.apache.skywalking.e2e.utils.Yamls.load;
+
+@Slf4j
+public class SimpleE2EBase extends SkyWalkingTestAdapter {
+ protected Instances verifyServiceInstances(final Service service) throws Exception {
+ final Instances instances = graphql.instances(
+ new InstancesQuery().serviceId(service.getKey()).start(startTime).end(now())
+ );
+
+ LOGGER.info("instances: {}", instances);
+
+ load("expected/simple/instances.yml").as(InstancesMatcher.class).verify(instances);
+
+ return instances;
+ }
+
+ protected Endpoints verifyServiceEndpoints(final Service service) throws Exception {
+ final Endpoints endpoints = graphql.endpoints(new EndpointQuery().serviceId(service.getKey()));
+
+ LOGGER.info("endpoints: {}", endpoints);
+
+ load("expected/simple/endpoints.yml").as(EndpointsMatcher.class).verify(endpoints);
+
+ return endpoints;
+ }
+
+ protected void verifyInstancesMetrics(final Instances instances) throws Exception {
+ for (Instance instance : instances.getInstances()) {
+ for (String metricsName : ALL_INSTANCE_METRICS) {
+ LOGGER.info("verifying service instance response time: {}", instance);
+ final Metrics instanceMetrics = graphql.metrics(
+ new MetricsQuery().stepByMinute().metricsName(metricsName).id(instance.getKey())
+ );
+
+ LOGGER.info("instance metrics: {}", instanceMetrics);
+
+ final AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
+ final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
+ greaterThanZero.setValue("gt 0");
+ instanceRespTimeMatcher.setValue(greaterThanZero);
+ instanceRespTimeMatcher.verify(instanceMetrics);
+ LOGGER.info("{}: {}", metricsName, instanceMetrics);
+ }
+ }
+ }
+
+ protected void verifyInstancesJVMMetrics(final Instances instances) throws Exception {
+ verifyInstancesJVMMetrics(instances, ALL_INSTANCE_JVM_METRICS);
+ }
+
+ protected void verifyInstancesJVMMetrics(final Instances instances, final String[] metrics) throws Exception {
+ for (Instance instance : instances.getInstances()) {
+ for (String metricsName : metrics) {
+ LOGGER.info("verifying service instance response time: {}", instance);
+ final Metrics instanceJVMMetrics = graphql.metrics(
+ new MetricsQuery().stepByMinute().metricsName(metricsName).id(instance.getKey())
+ );
+
+ LOGGER.info("instance jvm metrics: {}", instanceJVMMetrics);
+
+ final AtLeastOneOfMetricsMatcher instanceMatcher = new AtLeastOneOfMetricsMatcher();
+ final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
+ greaterThanZero.setValue("gt 0");
+ instanceMatcher.setValue(greaterThanZero);
+ instanceMatcher.verify(instanceJVMMetrics);
+ LOGGER.info("{}: {}", metricsName, instanceJVMMetrics);
+ }
+ }
+ }
+
+ protected void verifyEndpointsMetrics(final Endpoints endpoints) throws Exception {
+ for (Endpoint endpoint : endpoints.getEndpoints()) {
+ if (!endpoint.getLabel().equals("/users")) {
+ continue;
+ }
+ for (final String metricName : ALL_ENDPOINT_METRICS) {
+ LOGGER.info("verifying endpoint {}: {}", endpoint, metricName);
+
+ final Metrics metrics = graphql.metrics(
+ new MetricsQuery().stepByMinute().metricsName(metricName).id(endpoint.getKey())
+ );
+
+ LOGGER.info("metrics: {}", metrics);
+
+ final AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
+ final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
+ greaterThanZero.setValue("gt 0");
+ instanceRespTimeMatcher.setValue(greaterThanZero);
+ instanceRespTimeMatcher.verify(metrics);
+
+ LOGGER.info("{}: {}", metricName, metrics);
+ }
+ for (String metricName : ALL_ENDPOINT_MULTIPLE_LINEAR_METRICS) {
+ verifyPercentileMetrics(graphql, metricName, endpoint.getKey(), startTime);
+ }
+ }
+ }
+
+ protected void verifyServiceMetrics(final Service service) throws Exception {
+ for (String metricName : ALL_SERVICE_METRICS) {
+ LOGGER.info("verifying service {}, metrics: {}", service, metricName);
+ final Metrics serviceMetrics = graphql.metrics(
+ new MetricsQuery().stepByMinute().metricsName(metricName).id(service.getKey())
+ );
+ LOGGER.info("serviceMetrics: {}", serviceMetrics);
+ final AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
+ final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
+ greaterThanZero.setValue("gt 0");
+ instanceRespTimeMatcher.setValue(greaterThanZero);
+ instanceRespTimeMatcher.verify(serviceMetrics);
+ LOGGER.info("{}: {}", metricName, serviceMetrics);
+ }
+
+ for (String metricName : ALL_SERVICE_MULTIPLE_LINEAR_METRICS) {
+ verifyPercentileMetrics(graphql, metricName, service.getKey(), startTime);
+ }
+ }
+
+ protected void verifyServiceInstanceRelationMetrics(final List calls) throws Exception {
+ verifyRelationMetrics(
+ calls, ALL_SERVICE_INSTANCE_RELATION_CLIENT_METRICS,
+ ALL_SERVICE_INSTANCE_RELATION_SERVER_METRICS
+ );
+ }
+
+ protected void verifyServiceRelationMetrics(final List calls) throws Exception {
+ verifyRelationMetrics(calls, ALL_SERVICE_RELATION_CLIENT_METRICS, ALL_SERVICE_RELATION_SERVER_METRICS);
+ }
+
+ protected void verifyRelationMetrics(final List calls,
+ final String[] relationClientMetrics,
+ final String[] relationServerMetrics) throws Exception {
+ for (Call call : calls) {
+ for (String detectPoint : call.getDetectPoints()) {
+ switch (detectPoint) {
+ case "CLIENT": {
+ for (String metricName : relationClientMetrics) {
+ verifyMetrics(graphql, metricName, call.getId(), startTime);
+ }
+ break;
+ }
+ case "SERVER": {
+ for (String metricName : relationServerMetrics) {
+ verifyMetrics(graphql, metricName, call.getId(), startTime);
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+}