From 4067fba2abde828c5dcdcf7797df802354f692d3 Mon Sep 17 00:00:00 2001 From: Switch Date: Wed, 7 Jul 2021 16:30:55 +0800 Subject: [PATCH] Add some new thread metric and class metric to JVMMetric (#7230) (#7243) --- .github/workflows/e2e.compat.yaml | 2 +- CHANGES.md | 1 + apm-protocol/apm-network/src/main/proto | 2 +- .../apm/agent/core/jvm/JVMService.java | 6 +- .../agent/core/jvm/clazz/ClassProvider.java | 43 ++++ .../agent/core/jvm/thread/ThreadProvider.java | 38 +++- .../jvm/clazz/ClassProviderBenchmark.java | 63 ++++++ .../jvm/thread/ThreadProviderBenchmark.java | 64 ++++++ .../concepts-and-designs/scope-definitions.md | 20 +- .../provider/jvm/JVMSourceDispatcher.java | 26 +++ .../skywalking/oal/rt/grammar/OALLexer.g4 | 1 + .../skywalking/oal/rt/grammar/OALParser.g4 | 2 +- .../src/main/resources/oal/java-agent.oal | 9 +- .../ui-initialized-templates/apm.yml | 22 ++ .../core/source/DefaultScopeDefine.java | 2 + .../core/source/ServiceInstanceJVMClass.java | 64 ++++++ .../core/source/ServiceInstanceJVMThread.java | 12 ++ .../skywalking/e2e/metrics/MetricsQuery.java | 15 ++ test/e2e/e2e-protocol/src/main/proto | 2 +- .../skywalking/e2e/compat/CompatE2E.java | 141 ++++++++++++ .../apache/skywalking/e2e/kafka/KafkaE2E.java | 165 +------------- .../skywalking/e2e/simple/SimpleE2E.java | 170 +-------------- .../skywalking/e2e/simple/SimpleE2EBase.java | 202 ++++++++++++++++++ 23 files changed, 729 insertions(+), 343 deletions(-) create mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/clazz/ClassProvider.java create mode 100644 apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/jvm/clazz/ClassProviderBenchmark.java create mode 100644 apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/jvm/thread/ThreadProviderBenchmark.java create mode 100644 oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ServiceInstanceJVMClass.java create mode 100644 test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/compat/CompatE2E.java create mode 100644 test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/simple/SimpleE2EBase.java diff --git a/.github/workflows/e2e.compat.yaml b/.github/workflows/e2e.compat.yaml index ff87efec6b..e67bdbf903 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 f8d8c7092d..3aeba63397 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 7da226cfce..e626ee0485 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 736fccfc56..4c9b25ddbb 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 0000000000..769cadc9e0 --- /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 25243f27d2..3e89ce78b8 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 0000000000..547e9ca63c --- /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 0000000000..e60c8f9569 --- /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 51b330a6d9..812f777b36 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 ad2d3600d9..bed6241958 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 ea3976f64e..25654dacb7 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 337d0ab566..050defc2f4 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 ca344605f8..b7a3702dff 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 901bd88538..5854c07988 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 f87d82bf45..43f2fa5ef0 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 0000000000..451619864b --- /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 42ee6a2e20..741d2ac2ae 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 7117760df6..110a8ce28b 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 9a689b0188..e626ee0485 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 0000000000..7881254a89 --- /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 89716aac04..25c3e03ab4 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 0a80655077..f39dee35e1 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 0000000000..abd2ea35a4 --- /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; + } + } + } + } + } +} -- GitLab