You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2021/09/14 08:38:59 UTC

[skywalking-java] branch main updated: Chore: Add benchmark and improve docs for exception-ignore plugin (#25)

This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-java.git


The following commit(s) were added to refs/heads/main by this push:
     new a7a74a4  Chore: Add benchmark and improve docs for exception-ignore plugin (#25)
a7a74a4 is described below

commit a7a74a4067736c2dbfee1b9a22619a34715f13d4
Author: Jiajing LU <lu...@gmail.com>
AuthorDate: Tue Sep 14 16:38:54 2021 +0800

    Chore: Add benchmark and improve docs for exception-ignore plugin (#25)
    
    * add benchmark and improve docs
    
    Signed-off-by: Megrez Lu <lu...@gmail.com>
    
    * modify changelog and copy benchmark results to the docs
---
 CHANGES.md                                         |  1 +
 .../status/HierarchyMatchExceptionBenchmark.java   | 90 ++++++++++++++++++++++
 .../java-agent/How-to-tolerate-exceptions.md       | 30 +++++++-
 pom.xml                                            |  6 +-
 4 files changed, 122 insertions(+), 5 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 0961d7b..d62ac17 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -18,6 +18,7 @@ Release Notes.
 * fix the bug that plugin record wrong time elapse for lettuce plugin
 * fix the bug that the wrong db.instance value displayed on Skywalking-UI when existing multi-database-instance on same host port pair.
 * Add thrift plugin support thrift TMultiplexedProcessor.
+* Add benchmark result for `exception-ignore` plugin and polish plugin guide.
 
 #### Documentation
 
diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/status/HierarchyMatchExceptionBenchmark.java b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/status/HierarchyMatchExceptionBenchmark.java
new file mode 100644
index 0000000..01e3b84
--- /dev/null
+++ b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/status/HierarchyMatchExceptionBenchmark.java
@@ -0,0 +1,90 @@
+/*
+ * 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.context.status;
+
+import org.apache.skywalking.apm.agent.core.boot.ServiceManager;
+import org.apache.skywalking.apm.agent.core.conf.Config;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+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;
+
+/**
+ * # JMH version: 1.33
+ * # VM version: JDK 1.8.0_292, OpenJDK 64-Bit Server VM, 25.292-b10
+ * # VM invoker: /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/bin/java
+ * # VM options: -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=54972:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8
+ * # Blackhole mode: full + dont-inline hint (default, use -Djmh.blackhole.autoDetect=true to auto-detect)
+ * # 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: Average time, time/op
+ * <p/>
+ * Benchmark                                             Mode  Cnt   Score   Error  Units
+ * HierarchyMatchExceptionBenchmark.depthOneBenchmark    avgt   25  31.050 ± 0.731  ns/op
+ * HierarchyMatchExceptionBenchmark.depthTwoBenchmark    avgt   25  64.918 ± 2.537  ns/op
+ * HierarchyMatchExceptionBenchmark.depthThreeBenchmark  avgt   25  89.645 ± 2.556  ns/op
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class HierarchyMatchExceptionBenchmark {
+
+    @State(Scope.Benchmark)
+    public static class ThrowableState {
+        static {
+            Config.StatusCheck.IGNORED_EXCEPTIONS = "java.lang.NullPointerException";
+            Config.StatusCheck.MAX_RECURSIVE_DEPTH = 2;
+            ServiceManager.INSTANCE.boot();
+        }
+
+        private final Throwable singleT = new NullPointerException();
+        private final Throwable doubleT = new RuntimeException(new NullPointerException());
+        private final Throwable tripleT = new RuntimeException(new RuntimeException(new NullPointerException()));
+    }
+
+    @Benchmark
+    public void depthOneBenchmark(Blackhole bh, ThrowableState state) {
+        bh.consume(ServiceManager.INSTANCE.findService(StatusCheckService.class).isError(state.singleT));
+    }
+
+    @Benchmark
+    public void depthTwoBenchmark(Blackhole bh, ThrowableState state) {
+        bh.consume(ServiceManager.INSTANCE.findService(StatusCheckService.class).isError(state.doubleT));
+    }
+
+    @Benchmark
+    public void depthThreeBenchmark(Blackhole bh, ThrowableState state) {
+        bh.consume(ServiceManager.INSTANCE.findService(StatusCheckService.class).isError(state.tripleT));
+    }
+
+    public static void main(String[] args) throws Exception {
+        Options options = new OptionsBuilder()
+                .include(HierarchyMatchExceptionBenchmark.class.getSimpleName()).build();
+        new Runner(options).run();
+    }
+}
diff --git a/docs/en/setup/service-agent/java-agent/How-to-tolerate-exceptions.md b/docs/en/setup/service-agent/java-agent/How-to-tolerate-exceptions.md
index e80f73c..9d64770 100644
--- a/docs/en/setup/service-agent/java-agent/How-to-tolerate-exceptions.md
+++ b/docs/en/setup/service-agent/java-agent/How-to-tolerate-exceptions.md
@@ -107,8 +107,34 @@ If an exception has the `@IgnoredException` annotation, the exception wouldn't b
       `org.apache.skywalking.apm.agent.core.context.status.TestAnnotatedException`  | false |
 
 ## Recursive check
-Due to the wrapper nature of Java exceptions, sometimes users need recursive checking. Skywalking also supports it. Typically, we don't recommend setting this more than 10, which could cause a performance issue. Negative value and 0 would be ignored, which means all exceptions would make the span tagged in error status.
+Due to the wrapper nature of Java exceptions, sometimes users need recursive checking. Skywalking also supports it. 
 
 ```
-    statuscheck.max_recursive_depth=${SW_STATUSCHECK_MAX_RECURSIVE_DEPTH:1}
+statuscheck.max_recursive_depth=${SW_STATUSCHECK_MAX_RECURSIVE_DEPTH:1}
 ```
+
+The following report shows the benchmark results of the exception checks with different recursive depths,
+
+```
+# JMH version: 1.33
+# VM version: JDK 1.8.0_292, OpenJDK 64-Bit Server VM, 25.292-b10
+# VM invoker: /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/bin/java
+# VM options: -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=54972:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8
+# Blackhole mode: full + dont-inline hint (default, use -Djmh.blackhole.autoDetect=true to auto-detect)
+# 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: Average time, time/op
+Benchmark                                             Mode  Cnt   Score   Error  Units
+HierarchyMatchExceptionBenchmark.depthOneBenchmark    avgt   25  31.050 ± 0.731  ns/op
+HierarchyMatchExceptionBenchmark.depthTwoBenchmark    avgt   25  64.918 ± 2.537  ns/op
+HierarchyMatchExceptionBenchmark.depthThreeBenchmark  avgt   25  89.645 ± 2.556  ns/op
+```
+
+According to the reported results above, the exception check time is nearly proportional to the recursive depth being set.
+For each single check, it costs about ten of nanoseconds (~30 nanoseconds in the report, but may vary according 
+to different hardware and platforms).
+
+Typically, we don't recommend setting this more than 10, which could cause a performance issue. 
+Negative value and 0 would be ignored, which means all exceptions would make the span tagged in error status.
diff --git a/pom.xml b/pom.xml
index d16eeb6..c961212 100755
--- a/pom.xml
+++ b/pom.xml
@@ -119,7 +119,7 @@
         <versions-maven-plugin.version>2.5</versions-maven-plugin.version>
         <coveralls-maven-plugin.version>4.3.0</coveralls-maven-plugin.version>
         <maven-checkstyle-plugin.version>3.1.0</maven-checkstyle-plugin.version>
-        <jmh.version>1.21</jmh.version>
+        <jmh.version>1.33</jmh.version>
         <gmaven-plugin.version>1.5</gmaven-plugin.version>
         <checkstyle.fails.on.error>true</checkstyle.fails.on.error>
 
@@ -414,8 +414,8 @@
                         org/apache/skywalking/oal/rt/grammar/*.java,
                         org/apache/skywalking/oap/server/exporter/grpc/*.java,
                         org/apache/skywalking/oap/server/configuration/service/*.java,
-                        **/generated/*_jmhType*.java,
-                        **/generated/*_jmhTest.java
+                        **/jmh_generated/*_jmhType*.java,
+                        **/jmh_generated/*_jmhTest.java
                     </excludes>
                     <propertyExpansion>
                         import.control=${maven.multiModuleProjectDirectory}/apm-checkstyle/importControl.xml