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 2024/09/15 10:04:14 UTC

(skywalking-java) branch main updated: Add agent self-observability. (#716)

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 7536424165 Add agent self-observability. (#716)
7536424165 is described below

commit 75364241659c28e64557a3edffd53b9a8ae46188
Author: weixiang1862 <65...@qq.com>
AuthorDate: Sun Sep 15 18:04:09 2024 +0800

    Add agent self-observability. (#716)
---
 .github/actions/build/action.yml                   |   4 +-
 .github/actions/run/action.yml                     |   6 +-
 .github/workflows/plugins-test.0.yaml              |   1 +
 .github/workflows/publish-docker.yaml              |   4 +-
 CHANGES.md                                         |   1 +
 .../apm/agent/core/context/ContextManager.java     |   2 +
 .../core/context/ContextManagerExtendService.java  |   6 +
 .../agent/core/context/IgnoredTracerContext.java   |   2 +
 .../apm/agent/core/context/TracingContext.java     |   8 +-
 .../plugin/AbstractClassEnhancePluginDefine.java   |  17 ++
 .../apm/agent/core/plugin/PluginBootstrap.java     |   1 +
 .../plugin/bootstrap/BootstrapInstrumentBoost.java |  49 +++---
 .../template/ConstructorInterTemplate.java         |  14 ++
 .../template/InstanceMethodInterTemplate.java      |  20 +++
 ...nstanceMethodInterWithOverrideArgsTemplate.java |  20 +++
 .../template/StaticMethodInterTemplate.java        |  21 +++
 .../StaticMethodInterWithOverrideArgsTemplate.java |  21 +++
 .../template/v2/InstanceMethodInterV2Template.java |  19 +++
 ...tanceMethodInterV2WithOverrideArgsTemplate.java |  20 +++
 .../template/v2/StaticMethodInterV2Template.java   |  21 +++
 ...taticMethodInterV2WithOverrideArgsTemplate.java |  21 +++
 .../enhance/BootstrapInterRuntimeAssist.java       |  14 ++
 .../enhance/ClassEnhancePluginDefine.java          |  10 +-
 .../interceptor/enhance/ConstructorInter.java      |  13 +-
 .../interceptor/enhance/InstMethodsInter.java      |  19 ++-
 .../enhance/InstMethodsInterWithOverrideArgs.java  |  18 ++-
 .../interceptor/enhance/StaticMethodsInter.java    |  19 ++-
 .../StaticMethodsInterWithOverrideArgs.java        |  20 ++-
 .../enhance/v2/ClassEnhancePluginDefineV2.java     |  10 +-
 .../interceptor/enhance/v2/InstMethodsInterV2.java |  19 ++-
 .../v2/InstMethodsInterV2WithOverrideArgs.java     |  19 ++-
 .../enhance/v2/StaticMethodsInterV2.java           |  19 ++-
 .../v2/StaticMethodsInterV2WithOverrideArgs.java   |  19 ++-
 .../apm/agent/core/so11y/AgentSo11y.java           | 153 ++++++++++++++++++
 .../core/so11y/bootstrap/BootstrapPluginSo11y.java |  25 +++
 .../bootstrap/BootstrapPluginSo11yBridge.java      |  46 ++++++
 .../java-agent/Agent-self-observability.md         |  16 ++
 .../setup/service-agent/java-agent/Plugin-test.md  |   2 +-
 docs/menu.yml                                      |   6 +-
 .../main/resources/compose-start-script.template   |   6 +-
 .../main/resources/container-start-script.template |   5 +
 .../scenarios/agent-so11y-scenario/bin/startup.sh  |  21 +++
 .../agent-so11y-scenario/config/expectedData.yaml  | 177 +++++++++++++++++++++
 .../agent-so11y-scenario/configuration.yml         |  25 +++
 test/plugin/scenarios/agent-so11y-scenario/pom.xml | 128 +++++++++++++++
 .../src/main/assembly/assembly.xml                 |  41 +++++
 .../skywalking/apm/testcase/h2/Application.java    |  30 ++++
 .../apm/testcase/h2/controller/CaseController.java |  76 +++++++++
 .../apm/testcase/h2/controller/SQLExecutor.java    |  75 +++++++++
 .../src/main/resources/application.yaml            |  23 +++
 .../src/main/resources/log4j2.xml                  |  30 ++++
 .../agent-so11y-scenario/support-version.list      |  17 ++
 .../config/expectedData.yaml                       |   2 +-
 .../config/expectedData.yaml                       |   2 +-
 .../config/expectedData.yaml                       |   2 +-
 .../dbcp-2.x-scenario/config/expectedData.yaml     |   2 +-
 .../druid-1.x-scenario/config/expectedData.yaml    |   2 +-
 .../config/expectedData.yaml                       |   2 +-
 .../scenarios/h2-scenario/config/expectedData.yaml |   2 +-
 .../hikaricp-scenario/config/expectedData.yaml     |   2 +-
 .../config/expectedData.yaml                       |   2 +-
 .../config/expectedData.yaml                       |   2 +-
 .../config/expectedData.yaml                       |   2 +-
 .../config/expectedData.yaml                       |   2 +-
 64 files changed, 1340 insertions(+), 63 deletions(-)

diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml
index 2b63165d0d..f233bda2e4 100644
--- a/.github/actions/build/action.yml
+++ b/.github/actions/build/action.yml
@@ -56,7 +56,7 @@ runs:
         ./mvnw -q --batch-mode clean package -Dmaven.test.skip || \
         ./mvnw -q --batch-mode clean package -Dmaven.test.skip
         echo "::endgroup::"
-    - uses: actions/upload-artifact@v2
+    - uses: actions/upload-artifact@v4
       name: Upload Agent
       with:
         name: skywalking-agent
@@ -89,7 +89,7 @@ runs:
         docker save -o test-containers/skywalking-agent-test-jvm-1.0.0.tgz skywalking/agent-test-jvm:1.0.0
         docker save -o test-containers/skywalking-agent-test-tomcat-1.0.0.tgz skywalking/agent-test-tomcat:1.0.0
         echo "::endgroup::"
-    - uses: actions/upload-artifact@v2
+    - uses: actions/upload-artifact@v4
       name: Upload Test Containers
       with:
         name: test-tools
diff --git a/.github/actions/run/action.yml b/.github/actions/run/action.yml
index 02fdb8503c..c0d5ba1172 100644
--- a/.github/actions/run/action.yml
+++ b/.github/actions/run/action.yml
@@ -25,11 +25,11 @@ inputs:
 runs:
   using: "composite"
   steps:
-    - uses: actions/download-artifact@v2
+    - uses: actions/download-artifact@v4
       with:
         name: skywalking-agent
         path: skywalking-agent
-    - uses: actions/download-artifact@v2
+    - uses: actions/download-artifact@v4
       with:
         name: test-tools
     - name: Load Test Containers
@@ -53,7 +53,7 @@ runs:
         echo "::group::Run Plugin Test ${{ inputs.test_case }}"
         bash test/plugin/run.sh ${{ inputs.test_case }}
         echo "::endgroup::"
-    - uses: actions/upload-artifact@v2
+    - uses: actions/upload-artifact@v4
       name: Upload Agent
       if: always()
       with:
diff --git a/.github/workflows/plugins-test.0.yaml b/.github/workflows/plugins-test.0.yaml
index 57cec68cf8..19127048b5 100644
--- a/.github/workflows/plugins-test.0.yaml
+++ b/.github/workflows/plugins-test.0.yaml
@@ -53,6 +53,7 @@ jobs:
       matrix:
         case:
           - activemq-scenario
+          - agent-so11y-scenario
           - apm-toolkit-trace-scenario
           - apm-toolkit-tracer-scenario
           - armeria-0.96minus-scenario
diff --git a/.github/workflows/publish-docker.yaml b/.github/workflows/publish-docker.yaml
index be696af980..704c05ad86 100644
--- a/.github/workflows/publish-docker.yaml
+++ b/.github/workflows/publish-docker.yaml
@@ -47,7 +47,7 @@ jobs:
           java-version: 17
       - name: Build Agent
         run: make build
-      - uses: actions/upload-artifact@v2
+      - uses: actions/upload-artifact@v4
         name: Upload Agent
         with:
           name: skywalking-agent
@@ -71,7 +71,7 @@ jobs:
       - uses: actions/checkout@v2
         with:
           submodules: true
-      - uses: actions/download-artifact@v2
+      - uses: actions/download-artifact@v4
         with:
           name: skywalking-agent
           path: skywalking-agent
diff --git a/CHANGES.md b/CHANGES.md
index 8a31625dc9..f2534d9be3 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -6,6 +6,7 @@ Release Notes.
 ------------------
 
 * Upgrade nats plugin to support 2.16.5
+* Add agent self-observability.
 
 
 All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/222?closed=1)
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManager.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManager.java
index fe90d979cf..1da79e9cce 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManager.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManager.java
@@ -26,6 +26,7 @@ import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
 import org.apache.skywalking.apm.agent.core.logging.api.ILog;
 import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
 import org.apache.skywalking.apm.agent.core.sampling.SamplingService;
+import org.apache.skywalking.apm.agent.core.so11y.AgentSo11y;
 import org.apache.skywalking.apm.util.StringUtil;
 
 import static org.apache.skywalking.apm.agent.core.conf.Config.Agent.OPERATION_NAME_THRESHOLD;
@@ -52,6 +53,7 @@ public class ContextManager implements BootService {
                 if (LOGGER.isDebugEnable()) {
                     LOGGER.debug("No operation name, ignore this trace.");
                 }
+                AgentSo11y.measureTracingContextCreation(forceSampling, true);
                 context = new IgnoredTracerContext();
             } else {
                 if (EXTEND_SERVICE == null) {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManagerExtendService.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManagerExtendService.java
index 49faebdc0c..560d57c660 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManagerExtendService.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManagerExtendService.java
@@ -33,6 +33,7 @@ import org.apache.skywalking.apm.agent.core.remote.GRPCChannelListener;
 import org.apache.skywalking.apm.agent.core.remote.GRPCChannelManager;
 import org.apache.skywalking.apm.agent.core.remote.GRPCChannelStatus;
 import org.apache.skywalking.apm.agent.core.sampling.SamplingService;
+import org.apache.skywalking.apm.agent.core.so11y.AgentSo11y;
 import org.apache.skywalking.apm.util.StringUtil;
 
 @DefaultImplementor
@@ -81,17 +82,22 @@ public class ContextManagerExtendService implements BootService, GRPCChannelList
          * Don't trace anything if the backend is not available.
          */
         if (!Config.Agent.KEEP_TRACING && GRPCChannelStatus.DISCONNECT.equals(status)) {
+            AgentSo11y.measureTracingContextCreation(forceSampling, true);
             return new IgnoredTracerContext();
         }
 
         int suffixIdx = operationName.lastIndexOf(".");
         if (suffixIdx > -1 && ignoreSuffixSet.contains(operationName.substring(suffixIdx))) {
+            AgentSo11y.measureTracingContextCreation(forceSampling, true);
             context = new IgnoredTracerContext();
         } else {
             SamplingService samplingService = ServiceManager.INSTANCE.findService(SamplingService.class);
             if (forceSampling || samplingService.trySampling(operationName)) {
+                AgentSo11y.measureTracingContextCreation(forceSampling, false);
                 context = new TracingContext(operationName, spanLimitWatcher);
             } else {
+                AgentSo11y.measureTracingContextCreation(false, true);
+                AgentSo11y.measureLeakedTracingContext(true);
                 context = new IgnoredTracerContext();
             }
         }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/IgnoredTracerContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/IgnoredTracerContext.java
index b91258ea6a..8bf57ee064 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/IgnoredTracerContext.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/IgnoredTracerContext.java
@@ -23,6 +23,7 @@ import java.util.List;
 import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
 import org.apache.skywalking.apm.agent.core.context.trace.NoopSpan;
 import org.apache.skywalking.apm.agent.core.profile.ProfileStatusContext;
+import org.apache.skywalking.apm.agent.core.so11y.AgentSo11y;
 
 /**
  * The <code>IgnoredTracerContext</code> represent a context should be ignored. So it just maintains the stack with an
@@ -116,6 +117,7 @@ public class IgnoredTracerContext implements AbstractTracerContext {
     public boolean stopSpan(AbstractSpan span) {
         stackDepth--;
         if (stackDepth == 0) {
+            AgentSo11y.measureTracingContextCompletion(true);
             ListenerManager.notifyFinish(this);
         }
         return stackDepth == 0;
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java
index cffdbb2d38..cc1faa9af7 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java
@@ -43,6 +43,7 @@ import org.apache.skywalking.apm.agent.core.logging.api.ILog;
 import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
 import org.apache.skywalking.apm.agent.core.profile.ProfileStatusContext;
 import org.apache.skywalking.apm.agent.core.profile.ProfileTaskExecutionService;
+import org.apache.skywalking.apm.agent.core.so11y.AgentSo11y;
 import org.apache.skywalking.apm.util.StringUtil;
 
 import static org.apache.skywalking.apm.agent.core.conf.Config.Agent.CLUSTER;
@@ -460,7 +461,12 @@ public class TracingContext implements AbstractTracerContext {
             }
 
             if (isFinishedInMainThread && (!isRunningInAsyncMode || asyncSpanCounter == 0)) {
-                TraceSegment finishedSegment = segment.finish(isLimitMechanismWorking());
+                boolean limitMechanismWorking = isLimitMechanismWorking();
+                if (limitMechanismWorking) {
+                    AgentSo11y.measureLeakedTracingContext(false);
+                }
+                AgentSo11y.measureTracingContextCompletion(false);
+                TraceSegment finishedSegment = segment.finish(limitMechanismWorking);
                 TracingContext.ListenerManager.notifyFinish(finishedSegment);
                 running = false;
             }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefine.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefine.java
index 949f8d5813..c53e54f0fa 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefine.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefine.java
@@ -43,6 +43,10 @@ import java.util.List;
 public abstract class AbstractClassEnhancePluginDefine {
     private static final ILog LOGGER = LogManager.getLogger(AbstractClassEnhancePluginDefine.class);
 
+    /**
+     * plugin name defined in skywalking-plugin.def
+     */
+    private String pluginName;
     /**
      * New field name.
      */
@@ -199,4 +203,17 @@ public abstract class AbstractClassEnhancePluginDefine {
      * @return collections of {@link InstanceMethodsInterceptV2Point}
      */
     public abstract StaticMethodsInterceptV2Point[] getStaticMethodsInterceptV2Points();
+
+    /**
+     * plugin name should be set after create PluginDefine instance
+     *
+     * @param pluginName key defined in skywalking-plugin.def
+     */
+    protected void setPluginName(final String pluginName) {
+        this.pluginName = pluginName;
+    }
+
+    public String getPluginName() {
+        return pluginName;
+    }
 }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/PluginBootstrap.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/PluginBootstrap.java
index 7d54eebd73..75c9edc6e0 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/PluginBootstrap.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/PluginBootstrap.java
@@ -65,6 +65,7 @@ public class PluginBootstrap {
                 LOGGER.debug("loading plugin class {}.", pluginDefine.getDefineClass());
                 AbstractClassEnhancePluginDefine plugin = (AbstractClassEnhancePluginDefine) Class.forName(pluginDefine.getDefineClass(), true, AgentClassLoader
                     .getDefault()).newInstance();
+                plugin.setPluginName(pluginDefine.getName());
                 plugins.add(plugin);
             } catch (Throwable t) {
                 LOGGER.error(t, "load plugin [{}] failure.", pluginDefine.getDefineClass());
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/BootstrapInstrumentBoost.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/BootstrapInstrumentBoost.java
index 523340a401..f5875a7616 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/BootstrapInstrumentBoost.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/BootstrapInstrumentBoost.java
@@ -71,6 +71,9 @@ public class BootstrapInstrumentBoost {
         "org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.InstanceMethodsAroundInterceptorV2",
         "org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.StaticMethodsAroundInterceptorV2",
         "org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.MethodInvocationContext",
+
+        //SO11Y
+        "org.apache.skywalking.apm.agent.core.so11y.bootstrap.BootstrapPluginSo11y"
     };
 
     private static String INSTANCE_METHOD_DELEGATE_TEMPLATE = "org.apache.skywalking.apm.agent.core.plugin.bootstrap.template.InstanceMethodInterTemplate";
@@ -162,11 +165,14 @@ public class BootstrapInstrumentBoost {
                 for (InstanceMethodsInterceptPoint point : define.getInstanceMethodsInterceptPoints()) {
                     if (point.isOverrideArgs()) {
                         generateDelegator(
-                            classesTypeMap, typePool, INSTANCE_METHOD_WITH_OVERRIDE_ARGS_DELEGATE_TEMPLATE, point
-                                .getMethodsInterceptor());
+                            classesTypeMap, typePool, define.getPluginName(),
+                            INSTANCE_METHOD_WITH_OVERRIDE_ARGS_DELEGATE_TEMPLATE, point.getMethodsInterceptor()
+                        );
                     } else {
                         generateDelegator(
-                            classesTypeMap, typePool, INSTANCE_METHOD_DELEGATE_TEMPLATE, point.getMethodsInterceptor());
+                            classesTypeMap, typePool, define.getPluginName(),
+                            INSTANCE_METHOD_DELEGATE_TEMPLATE, point.getMethodsInterceptor()
+                        );
                     }
                 }
             }
@@ -174,7 +180,9 @@ public class BootstrapInstrumentBoost {
             if (Objects.nonNull(define.getConstructorsInterceptPoints())) {
                 for (ConstructorInterceptPoint point : define.getConstructorsInterceptPoints()) {
                     generateDelegator(
-                        classesTypeMap, typePool, CONSTRUCTOR_DELEGATE_TEMPLATE, point.getConstructorInterceptor());
+                        classesTypeMap, typePool, define.getPluginName(),
+                        CONSTRUCTOR_DELEGATE_TEMPLATE, point.getConstructorInterceptor()
+                    );
                 }
             }
 
@@ -182,11 +190,14 @@ public class BootstrapInstrumentBoost {
                 for (StaticMethodsInterceptPoint point : define.getStaticMethodsInterceptPoints()) {
                     if (point.isOverrideArgs()) {
                         generateDelegator(
-                            classesTypeMap, typePool, STATIC_METHOD_WITH_OVERRIDE_ARGS_DELEGATE_TEMPLATE, point
-                                .getMethodsInterceptor());
+                            classesTypeMap, typePool, define.getPluginName(),
+                            STATIC_METHOD_WITH_OVERRIDE_ARGS_DELEGATE_TEMPLATE, point.getMethodsInterceptor()
+                        );
                     } else {
                         generateDelegator(
-                            classesTypeMap, typePool, STATIC_METHOD_DELEGATE_TEMPLATE, point.getMethodsInterceptor());
+                            classesTypeMap, typePool, define.getPluginName(),
+                            STATIC_METHOD_DELEGATE_TEMPLATE, point.getMethodsInterceptor()
+                        );
                     }
                 }
             }
@@ -202,14 +213,14 @@ public class BootstrapInstrumentBoost {
             if (Objects.nonNull(define.getInstanceMethodsInterceptV2Points())) {
                 for (InstanceMethodsInterceptV2Point point : define.getInstanceMethodsInterceptV2Points()) {
                     if (point.isOverrideArgs()) {
-                        generateDelegator(classesTypeMap, typePool,
-                                          INSTANCE_METHOD_V2_WITH_OVERRIDE_ARGS_DELEGATE_TEMPLATE,
-                                          point.getMethodsInterceptorV2()
+                        generateDelegator(
+                            classesTypeMap, typePool, define.getPluginName(),
+                            INSTANCE_METHOD_V2_WITH_OVERRIDE_ARGS_DELEGATE_TEMPLATE, point.getMethodsInterceptorV2()
                         );
                     } else {
                         generateDelegator(
-                            classesTypeMap, typePool, INSTANCE_METHOD_V2_DELEGATE_TEMPLATE,
-                            point.getMethodsInterceptorV2()
+                            classesTypeMap, typePool, define.getPluginName(),
+                            INSTANCE_METHOD_V2_DELEGATE_TEMPLATE, point.getMethodsInterceptorV2()
                         );
                     }
                 }
@@ -218,14 +229,14 @@ public class BootstrapInstrumentBoost {
             if (Objects.nonNull(define.getStaticMethodsInterceptV2Points())) {
                 for (StaticMethodsInterceptV2Point point : define.getStaticMethodsInterceptV2Points()) {
                     if (point.isOverrideArgs()) {
-                        generateDelegator(classesTypeMap, typePool,
-                                          STATIC_METHOD_V2_WITH_OVERRIDE_ARGS_DELEGATE_TEMPLATE,
-                                          point.getMethodsInterceptorV2()
+                        generateDelegator(
+                            classesTypeMap, typePool, define.getPluginName(),
+                            STATIC_METHOD_V2_WITH_OVERRIDE_ARGS_DELEGATE_TEMPLATE, point.getMethodsInterceptorV2()
                         );
                     } else {
                         generateDelegator(
-                            classesTypeMap, typePool, STATIC_METHOD_V2_DELEGATE_TEMPLATE,
-                            point.getMethodsInterceptorV2()
+                            classesTypeMap, typePool, define.getPluginName(),
+                            STATIC_METHOD_V2_DELEGATE_TEMPLATE, point.getMethodsInterceptorV2()
                         );
                     }
                 }
@@ -245,7 +256,7 @@ public class BootstrapInstrumentBoost {
      *                          pre-defined in SkyWalking agent core.
      */
     private static void generateDelegator(Map<String, byte[]> classesTypeMap, TypePool typePool,
-        String templateClassName, String methodsInterceptor) {
+        String pluginName, String templateClassName, String methodsInterceptor) {
         String internalInterceptorName = internalDelegate(methodsInterceptor);
         try {
             TypeDescription templateTypeDescription = typePool.describe(templateClassName).resolve();
@@ -253,6 +264,8 @@ public class BootstrapInstrumentBoost {
             DynamicType.Unloaded interceptorType = new ByteBuddy().redefine(templateTypeDescription, ClassFileLocator.ForClassLoader
                 .of(BootstrapInstrumentBoost.class.getClassLoader()))
                                                                   .name(internalInterceptorName)
+                                                                  .field(named("PLUGIN_NAME"))
+                                                                  .value(pluginName)
                                                                   .field(named("TARGET_INTERCEPTOR"))
                                                                   .value(methodsInterceptor)
                                                                   .make();
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/ConstructorInterTemplate.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/ConstructorInterTemplate.java
index 756d03f299..06b7e8132e 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/ConstructorInterTemplate.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/ConstructorInterTemplate.java
@@ -25,6 +25,7 @@ import org.apache.skywalking.apm.agent.core.plugin.bootstrap.IBootstrapLog;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.BootstrapInterRuntimeAssist;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
+import org.apache.skywalking.apm.agent.core.so11y.bootstrap.BootstrapPluginSo11y;
 
 /**
  * --------CLASS TEMPLATE---------
@@ -37,6 +38,12 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceC
  * This class wouldn't be loaded in real env. This is a class template for dynamic class generation.
  */
 public class ConstructorInterTemplate {
+
+    private static final String INTERCEPTOR_TYPE = "constructor";
+    /**
+     * This field is never set in the template, but has value in the runtime.
+     */
+    private static String PLUGIN_NAME;
     /**
      * This field is never set in the template, but has value in the runtime.
      */
@@ -44,6 +51,7 @@ public class ConstructorInterTemplate {
 
     private static InstanceConstructorInterceptor INTERCEPTOR;
     private static IBootstrapLog LOGGER;
+    private static BootstrapPluginSo11y PLUGIN_SO11Y;
 
     /**
      * Intercept the target constructor.
@@ -53,6 +61,8 @@ public class ConstructorInterTemplate {
      */
     @RuntimeType
     public static void intercept(@This Object obj, @AllArguments Object[] allArguments) {
+        long interceptorTimeCost = 0L;
+        long startTime = System.nanoTime();
         try {
             prepare();
 
@@ -64,7 +74,10 @@ public class ConstructorInterTemplate {
             INTERCEPTOR.onConstruct(targetObject, allArguments);
         } catch (Throwable t) {
             LOGGER.error("ConstructorInter failure.", t);
+            PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
         }
+        interceptorTimeCost += System.nanoTime() - startTime;
+        PLUGIN_SO11Y.duration(interceptorTimeCost);
     }
 
     /**
@@ -79,6 +92,7 @@ public class ConstructorInterTemplate {
                 if (logger != null) {
                     LOGGER = logger;
 
+                    PLUGIN_SO11Y = BootstrapInterRuntimeAssist.getSO11Y(loader);
                     INTERCEPTOR = BootstrapInterRuntimeAssist.createInterceptor(loader, TARGET_INTERCEPTOR, LOGGER);
                 }
             } else {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/InstanceMethodInterTemplate.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/InstanceMethodInterTemplate.java
index ef70a5722b..62a0c8fac9 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/InstanceMethodInterTemplate.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/InstanceMethodInterTemplate.java
@@ -30,6 +30,7 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.Bootstrap
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.agent.core.so11y.bootstrap.BootstrapPluginSo11y;
 
 /**
  * --------CLASS TEMPLATE---------
@@ -42,6 +43,12 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInt
  * This class wouldn't be loaded in real env. This is a class template for dynamic class generation.
  */
 public class InstanceMethodInterTemplate {
+
+    private static final String INTERCEPTOR_TYPE = "inst";
+    /**
+     * This field is never set in the template, but has value in the runtime.
+     */
+    private static String PLUGIN_NAME;
     /**
      * This field is never set in the template, but has value in the runtime.
      */
@@ -49,6 +56,7 @@ public class InstanceMethodInterTemplate {
 
     private static InstanceMethodsAroundInterceptor INTERCEPTOR;
     private static IBootstrapLog LOGGER;
+    private static BootstrapPluginSo11y PLUGIN_SO11Y;
 
     /**
      * Intercept the target instance method.
@@ -68,6 +76,8 @@ public class InstanceMethodInterTemplate {
 
         prepare();
 
+        long interceptorTimeCost = 0L;
+        long startTimeOfMethodBeforeInter = System.nanoTime();
         MethodInterceptResult result = new MethodInterceptResult();
         try {
             if (INTERCEPTOR != null) {
@@ -77,7 +87,9 @@ public class InstanceMethodInterTemplate {
             if (LOGGER != null) {
                 LOGGER.error(t, "class[{}] before method[{}] intercept failure", obj.getClass(), method.getName());
             }
+            PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
         }
+        interceptorTimeCost += System.nanoTime() - startTimeOfMethodBeforeInter;
 
         Object ret = null;
         try {
@@ -87,6 +99,7 @@ public class InstanceMethodInterTemplate {
                 ret = zuper.call();
             }
         } catch (Throwable t) {
+            long startTimeOfMethodHandleExceptionInter = System.nanoTime();
             try {
                 if (INTERCEPTOR != null) {
                     INTERCEPTOR.handleMethodException(targetObject, method, allArguments, method.getParameterTypes(), t);
@@ -95,9 +108,12 @@ public class InstanceMethodInterTemplate {
                 if (LOGGER != null) {
                     LOGGER.error(t2, "class[{}] handle method[{}] exception failure", obj.getClass(), method.getName());
                 }
+                PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodHandleExceptionInter;
             throw t;
         } finally {
+            long startTimeOfMethodAfterInter = System.nanoTime();
             try {
                 if (INTERCEPTOR != null) {
                     ret = INTERCEPTOR.afterMethod(targetObject, method, allArguments, method.getParameterTypes(), ret);
@@ -106,8 +122,11 @@ public class InstanceMethodInterTemplate {
                 if (LOGGER != null) {
                     LOGGER.error(t, "class[{}] after method[{}] intercept failure", obj.getClass(), method.getName());
                 }
+                PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodAfterInter;
         }
+        PLUGIN_SO11Y.duration(interceptorTimeCost);
 
         return ret;
     }
@@ -124,6 +143,7 @@ public class InstanceMethodInterTemplate {
                 if (logger != null) {
                     LOGGER = logger;
 
+                    PLUGIN_SO11Y = BootstrapInterRuntimeAssist.getSO11Y(loader);
                     INTERCEPTOR = BootstrapInterRuntimeAssist.createInterceptor(loader, TARGET_INTERCEPTOR, LOGGER);
                 }
             } else {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/InstanceMethodInterWithOverrideArgsTemplate.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/InstanceMethodInterWithOverrideArgsTemplate.java
index 1ba0464de0..16053055d3 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/InstanceMethodInterWithOverrideArgsTemplate.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/InstanceMethodInterWithOverrideArgsTemplate.java
@@ -30,6 +30,7 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedI
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.OverrideCallable;
+import org.apache.skywalking.apm.agent.core.so11y.bootstrap.BootstrapPluginSo11y;
 
 /**
  * --------CLASS TEMPLATE---------
@@ -42,6 +43,12 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.OverrideC
  * This class wouldn't be loaded in real env. This is a class template for dynamic class generation.
  */
 public class InstanceMethodInterWithOverrideArgsTemplate {
+
+    private static final String INTERCEPTOR_TYPE = "inst";
+    /**
+     * This field is never set in the template, but has value in the runtime.
+     */
+    private static String PLUGIN_NAME;
     /**
      * This field is never set in the template, but has value in the runtime.
      */
@@ -49,6 +56,7 @@ public class InstanceMethodInterWithOverrideArgsTemplate {
 
     private static InstanceMethodsAroundInterceptor INTERCEPTOR;
     private static IBootstrapLog LOGGER;
+    private static BootstrapPluginSo11y PLUGIN_SO11Y;
 
     /**
      * Intercept the target instance method.
@@ -68,6 +76,8 @@ public class InstanceMethodInterWithOverrideArgsTemplate {
 
         prepare();
 
+        long interceptorTimeCost = 0L;
+        long startTimeOfMethodBeforeInter = System.nanoTime();
         MethodInterceptResult result = new MethodInterceptResult();
         try {
             if (INTERCEPTOR != null) {
@@ -77,7 +87,9 @@ public class InstanceMethodInterWithOverrideArgsTemplate {
             if (LOGGER != null) {
                 LOGGER.error(t, "class[{}] before method[{}] intercept failure", obj.getClass(), method.getName());
             }
+            PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
         }
+        interceptorTimeCost += System.nanoTime() - startTimeOfMethodBeforeInter;
 
         Object ret = null;
         try {
@@ -87,6 +99,7 @@ public class InstanceMethodInterWithOverrideArgsTemplate {
                 ret = zuper.call(allArguments);
             }
         } catch (Throwable t) {
+            long startTimeOfMethodHandleExceptionInter = System.nanoTime();
             try {
                 if (INTERCEPTOR != null) {
                     INTERCEPTOR.handleMethodException(targetObject, method, allArguments, method.getParameterTypes(), t);
@@ -95,9 +108,12 @@ public class InstanceMethodInterWithOverrideArgsTemplate {
                 if (LOGGER != null) {
                     LOGGER.error(t2, "class[{}] handle method[{}] exception failure", obj.getClass(), method.getName());
                 }
+                PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodHandleExceptionInter;
             throw t;
         } finally {
+            long startTimeOfMethodAfterInter = System.nanoTime();
             try {
                 if (INTERCEPTOR != null) {
                     ret = INTERCEPTOR.afterMethod(targetObject, method, allArguments, method.getParameterTypes(), ret);
@@ -106,8 +122,11 @@ public class InstanceMethodInterWithOverrideArgsTemplate {
                 if (LOGGER != null) {
                     LOGGER.error(t, "class[{}] after method[{}] intercept failure", obj.getClass(), method.getName());
                 }
+                PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodAfterInter;
         }
+        PLUGIN_SO11Y.duration(interceptorTimeCost);
 
         return ret;
     }
@@ -124,6 +143,7 @@ public class InstanceMethodInterWithOverrideArgsTemplate {
                 if (logger != null) {
                     LOGGER = logger;
 
+                    PLUGIN_SO11Y = BootstrapInterRuntimeAssist.getSO11Y(loader);
                     INTERCEPTOR = BootstrapInterRuntimeAssist.createInterceptor(loader, TARGET_INTERCEPTOR, LOGGER);
                 }
             } else {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/StaticMethodInterTemplate.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/StaticMethodInterTemplate.java
index a4caf96528..e32b1fc554 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/StaticMethodInterTemplate.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/StaticMethodInterTemplate.java
@@ -28,6 +28,7 @@ import org.apache.skywalking.apm.agent.core.plugin.bootstrap.IBootstrapLog;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.BootstrapInterRuntimeAssist;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.so11y.bootstrap.BootstrapPluginSo11y;
 
 /**
  * --------CLASS TEMPLATE---------
@@ -40,6 +41,12 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMet
  * This class wouldn't be loaded in real env. This is a class template for dynamic class generation.
  */
 public class StaticMethodInterTemplate {
+
+    private static final String INTERCEPTOR_TYPE = "static";
+    /**
+     * This field is never set in the template, but has value in the runtime.
+     */
+    private static String PLUGIN_NAME;
     /**
      * This field is never set in the template, but has value in the runtime.
      */
@@ -47,6 +54,7 @@ public class StaticMethodInterTemplate {
 
     private static StaticMethodsAroundInterceptor INTERCEPTOR;
     private static IBootstrapLog LOGGER;
+    private static BootstrapPluginSo11y PLUGIN_SO11Y;
 
     /**
      * Intercept the target static method.
@@ -64,6 +72,8 @@ public class StaticMethodInterTemplate {
         @SuperCall Callable<?> zuper) throws Throwable {
         prepare();
 
+        long interceptorTimeCost = 0L;
+        long startTimeOfMethodBeforeInter = System.nanoTime();
         MethodInterceptResult result = new MethodInterceptResult();
         try {
             if (INTERCEPTOR != null) {
@@ -71,7 +81,9 @@ public class StaticMethodInterTemplate {
             }
         } catch (Throwable t) {
             LOGGER.error(t, "class[{}] before static method[{}] intercept failure", clazz, method.getName());
+            PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
         }
+        interceptorTimeCost += System.nanoTime() - startTimeOfMethodBeforeInter;
 
         Object ret = null;
         try {
@@ -81,23 +93,31 @@ public class StaticMethodInterTemplate {
                 ret = zuper.call();
             }
         } catch (Throwable t) {
+            long startTimeOfMethodHandleExceptionInter = System.nanoTime();
             try {
                 if (INTERCEPTOR != null) {
                     INTERCEPTOR.handleMethodException(clazz, method, allArguments, method.getParameterTypes(), t);
                 }
             } catch (Throwable t2) {
                 LOGGER.error(t2, "class[{}] handle static method[{}] exception failure", clazz, method.getName(), t2.getMessage());
+                PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodHandleExceptionInter;
             throw t;
         } finally {
+            long startTimeOfMethodAfterInter = System.nanoTime();
             try {
                 if (INTERCEPTOR != null) {
                     ret = INTERCEPTOR.afterMethod(clazz, method, allArguments, method.getParameterTypes(), ret);
                 }
             } catch (Throwable t) {
                 LOGGER.error(t, "class[{}] after static method[{}] intercept failure:{}", clazz, method.getName(), t.getMessage());
+                PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodAfterInter;
         }
+        PLUGIN_SO11Y.duration(interceptorTimeCost);
+
         return ret;
     }
 
@@ -113,6 +133,7 @@ public class StaticMethodInterTemplate {
                 if (logger != null) {
                     LOGGER = logger;
 
+                    PLUGIN_SO11Y = BootstrapInterRuntimeAssist.getSO11Y(loader);
                     INTERCEPTOR = BootstrapInterRuntimeAssist.createInterceptor(loader, TARGET_INTERCEPTOR, LOGGER);
                 }
             } else {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/StaticMethodInterWithOverrideArgsTemplate.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/StaticMethodInterWithOverrideArgsTemplate.java
index 6dd7ac0b00..c182878148 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/StaticMethodInterWithOverrideArgsTemplate.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/StaticMethodInterWithOverrideArgsTemplate.java
@@ -28,6 +28,7 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.Bootstrap
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.OverrideCallable;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.so11y.bootstrap.BootstrapPluginSo11y;
 
 /**
  * --------CLASS TEMPLATE---------
@@ -40,6 +41,12 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMet
  * This class wouldn't be loaded in real env. This is a class template for dynamic class generation.
  */
 public class StaticMethodInterWithOverrideArgsTemplate {
+
+    private static final String INTERCEPTOR_TYPE = "static";
+    /**
+     * This field is never set in the template, but has value in the runtime.
+     */
+    private static String PLUGIN_NAME;
     /**
      * This field is never set in the template, but has value in the runtime.
      */
@@ -47,6 +54,7 @@ public class StaticMethodInterWithOverrideArgsTemplate {
 
     private static StaticMethodsAroundInterceptor INTERCEPTOR;
     private static IBootstrapLog LOGGER;
+    private static BootstrapPluginSo11y PLUGIN_SO11Y;
 
     /**
      * Intercept the target static method.
@@ -64,6 +72,8 @@ public class StaticMethodInterWithOverrideArgsTemplate {
         @Morph OverrideCallable zuper) throws Throwable {
         prepare();
 
+        long interceptorTimeCost = 0L;
+        long startTimeOfMethodBeforeInter = System.nanoTime();
         MethodInterceptResult result = new MethodInterceptResult();
         try {
             if (INTERCEPTOR != null) {
@@ -71,7 +81,9 @@ public class StaticMethodInterWithOverrideArgsTemplate {
             }
         } catch (Throwable t) {
             LOGGER.error(t, "class[{}] before static method[{}] intercept failure", clazz, method.getName());
+            PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
         }
+        interceptorTimeCost += System.nanoTime() - startTimeOfMethodBeforeInter;
 
         Object ret = null;
         try {
@@ -81,23 +93,31 @@ public class StaticMethodInterWithOverrideArgsTemplate {
                 ret = zuper.call(allArguments);
             }
         } catch (Throwable t) {
+            long startTimeOfMethodHandleExceptionInter = System.nanoTime();
             try {
                 if (INTERCEPTOR != null) {
                     INTERCEPTOR.handleMethodException(clazz, method, allArguments, method.getParameterTypes(), t);
                 }
             } catch (Throwable t2) {
                 LOGGER.error(t2, "class[{}] handle static method[{}] exception failure", clazz, method.getName(), t2.getMessage());
+                PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodHandleExceptionInter;
             throw t;
         } finally {
+            long startTimeOfMethodAfterInter = System.nanoTime();
             try {
                 if (INTERCEPTOR != null) {
                     ret = INTERCEPTOR.afterMethod(clazz, method, allArguments, method.getParameterTypes(), ret);
                 }
             } catch (Throwable t) {
                 LOGGER.error(t, "class[{}] after static method[{}] intercept failure:{}", clazz, method.getName(), t.getMessage());
+                PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodAfterInter;
         }
+        PLUGIN_SO11Y.duration(interceptorTimeCost);
+
         return ret;
     }
 
@@ -113,6 +133,7 @@ public class StaticMethodInterWithOverrideArgsTemplate {
                 if (logger != null) {
                     LOGGER = logger;
 
+                    PLUGIN_SO11Y = BootstrapInterRuntimeAssist.getSO11Y(loader);
                     INTERCEPTOR = BootstrapInterRuntimeAssist.createInterceptor(loader, TARGET_INTERCEPTOR, LOGGER);
                 }
             } else {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/v2/InstanceMethodInterV2Template.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/v2/InstanceMethodInterV2Template.java
index 88be482f5f..92be67f5f8 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/v2/InstanceMethodInterV2Template.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/v2/InstanceMethodInterV2Template.java
@@ -29,12 +29,18 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.Bootstrap
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.InstanceMethodsAroundInterceptorV2;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.MethodInvocationContext;
+import org.apache.skywalking.apm.agent.core.so11y.bootstrap.BootstrapPluginSo11y;
 
 /**
  * This class wouldn't be loaded in real env. This is a class template for dynamic class generation.
  */
 public class InstanceMethodInterV2Template {
 
+    private static final String INTERCEPTOR_TYPE = "inst";
+    /**
+     * This field is never set in the template, but has value in the runtime.
+     */
+    private static String PLUGIN_NAME;
     /**
      * This field is never set in the template, but has value in the runtime.
      */
@@ -42,6 +48,7 @@ public class InstanceMethodInterV2Template {
 
     private static InstanceMethodsAroundInterceptorV2 INTERCEPTOR;
     private static IBootstrapLog LOGGER;
+    private static BootstrapPluginSo11y PLUGIN_SO11Y;
 
     /**
      * Intercept the target instance method.
@@ -61,6 +68,8 @@ public class InstanceMethodInterV2Template {
 
         prepare();
 
+        long interceptorTimeCost = 0L;
+        long startTimeOfMethodBeforeInter = System.nanoTime();
         MethodInvocationContext context = new MethodInvocationContext();
         try {
             if (INTERCEPTOR != null) {
@@ -70,7 +79,9 @@ public class InstanceMethodInterV2Template {
             if (LOGGER != null) {
                 LOGGER.error(t, "class[{}] before method[{}] intercept failure", obj.getClass(), method.getName());
             }
+            PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
         }
+        interceptorTimeCost += System.nanoTime() - startTimeOfMethodBeforeInter;
 
         Object ret = null;
         try {
@@ -80,6 +91,7 @@ public class InstanceMethodInterV2Template {
                 ret = zuper.call();
             }
         } catch (Throwable t) {
+            long startTimeOfMethodHandleExceptionInter = System.nanoTime();
             try {
                 if (INTERCEPTOR != null) {
                     INTERCEPTOR.handleMethodException(targetObject, method, allArguments, method.getParameterTypes(), t, context);
@@ -88,9 +100,12 @@ public class InstanceMethodInterV2Template {
                 if (LOGGER != null) {
                     LOGGER.error(t2, "class[{}] handle method[{}] exception failure", obj.getClass(), method.getName());
                 }
+                PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodHandleExceptionInter;
             throw t;
         } finally {
+            long startTimeOfMethodAfterInter = System.nanoTime();
             try {
                 if (INTERCEPTOR != null) {
                     ret = INTERCEPTOR.afterMethod(targetObject, method, allArguments, method.getParameterTypes(), ret, context);
@@ -99,8 +114,11 @@ public class InstanceMethodInterV2Template {
                 if (LOGGER != null) {
                     LOGGER.error(t, "class[{}] after method[{}] intercept failure", obj.getClass(), method.getName());
                 }
+                PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodAfterInter;
         }
+        PLUGIN_SO11Y.duration(interceptorTimeCost);
 
         return ret;
     }
@@ -117,6 +135,7 @@ public class InstanceMethodInterV2Template {
                 if (logger != null) {
                     LOGGER = logger;
 
+                    PLUGIN_SO11Y = BootstrapInterRuntimeAssist.getSO11Y(loader);
                     INTERCEPTOR = BootstrapInterRuntimeAssist.createInterceptor(loader, TARGET_INTERCEPTOR, LOGGER);
                 }
             } else {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/v2/InstanceMethodInterV2WithOverrideArgsTemplate.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/v2/InstanceMethodInterV2WithOverrideArgsTemplate.java
index 83fc8a9711..b027f086d3 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/v2/InstanceMethodInterV2WithOverrideArgsTemplate.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/v2/InstanceMethodInterV2WithOverrideArgsTemplate.java
@@ -30,11 +30,18 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedI
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.OverrideCallable;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.InstanceMethodsAroundInterceptorV2;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.MethodInvocationContext;
+import org.apache.skywalking.apm.agent.core.so11y.bootstrap.BootstrapPluginSo11y;
 
 /**
  * This class wouldn't be loaded in real env. This is a class template for dynamic class generation.
  */
 public class InstanceMethodInterV2WithOverrideArgsTemplate {
+
+    private static final String INTERCEPTOR_TYPE = "inst";
+    /**
+     * This field is never set in the template, but has value in the runtime.
+     */
+    private static String PLUGIN_NAME;
     /**
      * This field is never set in the template, but has value in the runtime.
      */
@@ -42,6 +49,7 @@ public class InstanceMethodInterV2WithOverrideArgsTemplate {
 
     private static InstanceMethodsAroundInterceptorV2 INTERCEPTOR;
     private static IBootstrapLog LOGGER;
+    private static BootstrapPluginSo11y PLUGIN_SO11Y;
 
     /**
      * Intercept the target instance method.
@@ -61,6 +69,8 @@ public class InstanceMethodInterV2WithOverrideArgsTemplate {
 
         prepare();
 
+        long interceptorTimeCost = 0L;
+        long startTimeOfMethodBeforeInter = System.nanoTime();
         MethodInvocationContext context = new MethodInvocationContext();
         try {
             if (INTERCEPTOR != null) {
@@ -70,7 +80,9 @@ public class InstanceMethodInterV2WithOverrideArgsTemplate {
             if (LOGGER != null) {
                 LOGGER.error(t, "class[{}] before method[{}] intercept failure", obj.getClass(), method.getName());
             }
+            PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
         }
+        interceptorTimeCost += System.nanoTime() - startTimeOfMethodBeforeInter;
 
         Object ret = null;
         try {
@@ -80,6 +92,7 @@ public class InstanceMethodInterV2WithOverrideArgsTemplate {
                 ret = zuper.call(allArguments);
             }
         } catch (Throwable t) {
+            long startTimeOfMethodHandleExceptionInter = System.nanoTime();
             try {
                 if (INTERCEPTOR != null) {
                     INTERCEPTOR.handleMethodException(targetObject, method, allArguments, method.getParameterTypes(), t, context);
@@ -88,9 +101,12 @@ public class InstanceMethodInterV2WithOverrideArgsTemplate {
                 if (LOGGER != null) {
                     LOGGER.error(t2, "class[{}] handle method[{}] exception failure", obj.getClass(), method.getName());
                 }
+                PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodHandleExceptionInter;
             throw t;
         } finally {
+            long startTimeOfMethodAfterInter = System.nanoTime();
             try {
                 if (INTERCEPTOR != null) {
                     ret = INTERCEPTOR.afterMethod(targetObject, method, allArguments, method.getParameterTypes(), ret, context);
@@ -99,8 +115,11 @@ public class InstanceMethodInterV2WithOverrideArgsTemplate {
                 if (LOGGER != null) {
                     LOGGER.error(t, "class[{}] after method[{}] intercept failure", obj.getClass(), method.getName());
                 }
+                PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodAfterInter;
         }
+        PLUGIN_SO11Y.duration(interceptorTimeCost);
 
         return ret;
     }
@@ -117,6 +136,7 @@ public class InstanceMethodInterV2WithOverrideArgsTemplate {
                 if (logger != null) {
                     LOGGER = logger;
 
+                    PLUGIN_SO11Y = BootstrapInterRuntimeAssist.getSO11Y(loader);
                     INTERCEPTOR = BootstrapInterRuntimeAssist.createInterceptor(loader, TARGET_INTERCEPTOR, LOGGER);
                 }
             } else {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/v2/StaticMethodInterV2Template.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/v2/StaticMethodInterV2Template.java
index 74cfb1e26a..4541716c2f 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/v2/StaticMethodInterV2Template.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/v2/StaticMethodInterV2Template.java
@@ -28,11 +28,18 @@ import org.apache.skywalking.apm.agent.core.plugin.bootstrap.IBootstrapLog;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.BootstrapInterRuntimeAssist;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.MethodInvocationContext;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.StaticMethodsAroundInterceptorV2;
+import org.apache.skywalking.apm.agent.core.so11y.bootstrap.BootstrapPluginSo11y;
 
 /**
  * This class wouldn't be loaded in real env. This is a class template for dynamic class generation.
  */
 public class StaticMethodInterV2Template {
+
+    private static final String INTERCEPTOR_TYPE = "static";
+    /**
+     * This field is never set in the template, but has value in the runtime.
+     */
+    private static String PLUGIN_NAME;
     /**
      * This field is never set in the template, but has value in the runtime.
      */
@@ -40,6 +47,7 @@ public class StaticMethodInterV2Template {
 
     private static StaticMethodsAroundInterceptorV2 INTERCEPTOR;
     private static IBootstrapLog LOGGER;
+    private static BootstrapPluginSo11y PLUGIN_SO11Y;
 
     /**
      * Intercept the target static method.
@@ -57,6 +65,8 @@ public class StaticMethodInterV2Template {
         @SuperCall Callable<?> zuper) throws Throwable {
         prepare();
 
+        long interceptorTimeCost = 0L;
+        long startTimeOfMethodBeforeInter = System.nanoTime();
         MethodInvocationContext context = new MethodInvocationContext();
         try {
             if (INTERCEPTOR != null) {
@@ -64,7 +74,9 @@ public class StaticMethodInterV2Template {
             }
         } catch (Throwable t) {
             LOGGER.error(t, "class[{}] before static method[{}] intercept failure", clazz, method.getName());
+            PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
         }
+        interceptorTimeCost += System.nanoTime() - startTimeOfMethodBeforeInter;
 
         Object ret = null;
         try {
@@ -74,23 +86,31 @@ public class StaticMethodInterV2Template {
                 ret = zuper.call();
             }
         } catch (Throwable t) {
+            long startTimeOfMethodHandleExceptionInter = System.nanoTime();
             try {
                 if (INTERCEPTOR != null) {
                     INTERCEPTOR.handleMethodException(clazz, method, allArguments, method.getParameterTypes(), t, context);
                 }
             } catch (Throwable t2) {
                 LOGGER.error(t2, "class[{}] handle static method[{}] exception failure", clazz, method.getName(), t2.getMessage());
+                PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodHandleExceptionInter;
             throw t;
         } finally {
+            long startTimeOfMethodAfterInter = System.nanoTime();
             try {
                 if (INTERCEPTOR != null) {
                     ret = INTERCEPTOR.afterMethod(clazz, method, allArguments, method.getParameterTypes(), ret, context);
                 }
             } catch (Throwable t) {
                 LOGGER.error(t, "class[{}] after static method[{}] intercept failure:{}", clazz, method.getName(), t.getMessage());
+                PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodAfterInter;
         }
+        PLUGIN_SO11Y.duration(interceptorTimeCost);
+
         return ret;
     }
 
@@ -106,6 +126,7 @@ public class StaticMethodInterV2Template {
                 if (logger != null) {
                     LOGGER = logger;
 
+                    PLUGIN_SO11Y = BootstrapInterRuntimeAssist.getSO11Y(loader);
                     INTERCEPTOR = BootstrapInterRuntimeAssist.createInterceptor(loader, TARGET_INTERCEPTOR, LOGGER);
                 }
             } else {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/v2/StaticMethodInterV2WithOverrideArgsTemplate.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/v2/StaticMethodInterV2WithOverrideArgsTemplate.java
index 09607882d7..9297f36582 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/v2/StaticMethodInterV2WithOverrideArgsTemplate.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/template/v2/StaticMethodInterV2WithOverrideArgsTemplate.java
@@ -28,11 +28,18 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.Bootstrap
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.OverrideCallable;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.MethodInvocationContext;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.StaticMethodsAroundInterceptorV2;
+import org.apache.skywalking.apm.agent.core.so11y.bootstrap.BootstrapPluginSo11y;
 
 /**
  * This class wouldn't be loaded in real env. This is a class template for dynamic class generation.
  */
 public class StaticMethodInterV2WithOverrideArgsTemplate {
+
+    private static final String INTERCEPTOR_TYPE = "static";
+    /**
+     * This field is never set in the template, but has value in the runtime.
+     */
+    private static String PLUGIN_NAME;
     /**
      * This field is never set in the template, but has value in the runtime.
      */
@@ -40,6 +47,7 @@ public class StaticMethodInterV2WithOverrideArgsTemplate {
 
     private static StaticMethodsAroundInterceptorV2 INTERCEPTOR;
     private static IBootstrapLog LOGGER;
+    private static BootstrapPluginSo11y PLUGIN_SO11Y;
 
     /**
      * Intercept the target static method.
@@ -57,6 +65,8 @@ public class StaticMethodInterV2WithOverrideArgsTemplate {
         @Morph OverrideCallable zuper) throws Throwable {
         prepare();
 
+        long interceptorTimeCost = 0L;
+        long startTimeOfMethodBeforeInter = System.nanoTime();
         MethodInvocationContext context = new MethodInvocationContext();
         try {
             if (INTERCEPTOR != null) {
@@ -64,7 +74,9 @@ public class StaticMethodInterV2WithOverrideArgsTemplate {
             }
         } catch (Throwable t) {
             LOGGER.error(t, "class[{}] before static method[{}] intercept failure", clazz, method.getName());
+            PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
         }
+        interceptorTimeCost += System.nanoTime() - startTimeOfMethodBeforeInter;
 
         Object ret = null;
         try {
@@ -74,23 +86,31 @@ public class StaticMethodInterV2WithOverrideArgsTemplate {
                 ret = zuper.call(allArguments);
             }
         } catch (Throwable t) {
+            long startTimeOfMethodHandleExceptionInter = System.nanoTime();
             try {
                 if (INTERCEPTOR != null) {
                     INTERCEPTOR.handleMethodException(clazz, method, allArguments, method.getParameterTypes(), t, context);
                 }
             } catch (Throwable t2) {
                 LOGGER.error(t2, "class[{}] handle static method[{}] exception failure", clazz, method.getName(), t2.getMessage());
+                PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodHandleExceptionInter;
             throw t;
         } finally {
+            long startTimeOfMethodAfterInter = System.nanoTime();
             try {
                 if (INTERCEPTOR != null) {
                     ret = INTERCEPTOR.afterMethod(clazz, method, allArguments, method.getParameterTypes(), ret, context);
                 }
             } catch (Throwable t) {
                 LOGGER.error(t, "class[{}] after static method[{}] intercept failure:{}", clazz, method.getName(), t.getMessage());
+                PLUGIN_SO11Y.error(PLUGIN_NAME, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodAfterInter;
         }
+        PLUGIN_SO11Y.duration(interceptorTimeCost);
+
         return ret;
     }
 
@@ -106,6 +126,7 @@ public class StaticMethodInterV2WithOverrideArgsTemplate {
                 if (logger != null) {
                     LOGGER = logger;
 
+                    PLUGIN_SO11Y = BootstrapInterRuntimeAssist.getSO11Y(loader);
                     INTERCEPTOR = BootstrapInterRuntimeAssist.createInterceptor(loader, TARGET_INTERCEPTOR, LOGGER);
                 }
             } else {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/BootstrapInterRuntimeAssist.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/BootstrapInterRuntimeAssist.java
index f667667a3e..9289391ccb 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/BootstrapInterRuntimeAssist.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/BootstrapInterRuntimeAssist.java
@@ -22,6 +22,7 @@ import java.io.PrintStream;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import org.apache.skywalking.apm.agent.core.plugin.bootstrap.IBootstrapLog;
+import org.apache.skywalking.apm.agent.core.so11y.bootstrap.BootstrapPluginSo11y;
 
 /**
  * This assist help all bootstrap class core interceptor.
@@ -29,6 +30,8 @@ import org.apache.skywalking.apm.agent.core.plugin.bootstrap.IBootstrapLog;
 public class BootstrapInterRuntimeAssist {
     private static final String AGENT_CLASSLOADER_DEFAULT = "org.apache.skywalking.apm.agent.core.plugin.loader.AgentClassLoader";
     private static final String DEFAULT_AGENT_CLASSLOADER_INSTANCE = "DEFAULT_LOADER";
+    private static final String SO11Y_BRIDGE_CLASS = "org.apache.skywalking.apm.agent.core.so11y.bootstrap.BootstrapPluginSo11yBridge";
+    private static final String SO11Y_BRIDGE_GET_SO11Y_METHOD = "getSo11y";
     private static final String LOG_MANAGER_CLASS = "org.apache.skywalking.apm.agent.core.plugin.bootstrap.BootstrapPluginLogBridge";
     private static final String LOG_MANAGER_GET_LOGGER_METHOD = "getLogger";
     private static final PrintStream OUT = System.out;
@@ -62,6 +65,17 @@ public class BootstrapInterRuntimeAssist {
         }
     }
 
+    public static BootstrapPluginSo11y getSO11Y(ClassLoader defaultAgentClassLoader) {
+        try {
+            Class<?> logManagerClass = Class.forName(SO11Y_BRIDGE_CLASS, true, defaultAgentClassLoader);
+            Method getLogger = logManagerClass.getMethod(SO11Y_BRIDGE_GET_SO11Y_METHOD);
+            return (BootstrapPluginSo11y) getLogger.invoke(null);
+        } catch (Exception e) {
+            e.printStackTrace(OUT);
+            return null;
+        }
+    }
+
     public static <T> T createInterceptor(ClassLoader defaultAgentClassLoader, String className, IBootstrapLog log) {
         try {
             Class<?> interceptor = Class.forName(className, true, defaultAgentClassLoader);
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java
index e1a1fa4261..f38ddfc5a8 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java
@@ -121,7 +121,7 @@ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePlugi
                 } else {
                     newClassBuilder = newClassBuilder.constructor(constructorInterceptPoint.getConstructorMatcher())
                                                      .intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.withDefaultConfiguration()
-                                                                                                                 .to(new ConstructorInter(constructorInterceptPoint
+                                                                                                                 .to(new ConstructorInter(getPluginName(), constructorInterceptPoint
                                                                                                                      .getConstructorInterceptor(), classLoader), delegateNamingResolver.resolve(constructorInterceptPoint))));
                 }
             }
@@ -150,7 +150,7 @@ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePlugi
                         newClassBuilder = newClassBuilder.method(junction)
                                                          .intercept(MethodDelegation.withDefaultConfiguration()
                                                                                     .withBinders(Morph.Binder.install(OverrideCallable.class))
-                                                                                    .to(new InstMethodsInterWithOverrideArgs(interceptor, classLoader), delegateNamingResolver.resolve(instanceMethodsInterceptPoint)));
+                                                                                    .to(new InstMethodsInterWithOverrideArgs(getPluginName(), interceptor, classLoader), delegateNamingResolver.resolve(instanceMethodsInterceptPoint)));
                     }
                 } else {
                     if (isBootstrapInstrumentation()) {
@@ -160,7 +160,7 @@ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePlugi
                     } else {
                         newClassBuilder = newClassBuilder.method(junction)
                                                          .intercept(MethodDelegation.withDefaultConfiguration()
-                                                                                    .to(new InstMethodsInter(interceptor, classLoader), delegateNamingResolver.resolve(instanceMethodsInterceptPoint)));
+                                                                                    .to(new InstMethodsInter(getPluginName(), interceptor, classLoader), delegateNamingResolver.resolve(instanceMethodsInterceptPoint)));
                     }
                 }
             }
@@ -202,7 +202,7 @@ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePlugi
                     newClassBuilder = newClassBuilder.method(isStatic().and(staticMethodsInterceptPoint.getMethodsMatcher()))
                                                      .intercept(MethodDelegation.withDefaultConfiguration()
                                                                                 .withBinders(Morph.Binder.install(OverrideCallable.class))
-                                                                                .to(new StaticMethodsInterWithOverrideArgs(interceptor), delegateNamingResolver.resolve(staticMethodsInterceptPoint)));
+                                                                                .to(new StaticMethodsInterWithOverrideArgs(getPluginName(), interceptor), delegateNamingResolver.resolve(staticMethodsInterceptPoint)));
                 }
             } else {
                 if (isBootstrapInstrumentation()) {
@@ -212,7 +212,7 @@ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePlugi
                 } else {
                     newClassBuilder = newClassBuilder.method(isStatic().and(staticMethodsInterceptPoint.getMethodsMatcher()))
                                                      .intercept(MethodDelegation.withDefaultConfiguration()
-                                                                                .to(new StaticMethodsInter(interceptor), delegateNamingResolver.resolve(staticMethodsInterceptPoint)));
+                                                                                .to(new StaticMethodsInter(getPluginName(), interceptor), delegateNamingResolver.resolve(staticMethodsInterceptPoint)));
                 }
             }
 
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ConstructorInter.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ConstructorInter.java
index 8a057df259..3a1063da03 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ConstructorInter.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/ConstructorInter.java
@@ -25,6 +25,7 @@ import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
 import org.apache.skywalking.apm.agent.core.plugin.PluginException;
 import org.apache.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoader;
 import org.apache.skywalking.apm.agent.core.logging.api.ILog;
+import org.apache.skywalking.apm.agent.core.so11y.AgentSo11y;
 
 /**
  * The actual byte-buddy's interceptor to intercept constructor methods. In this class, it provides a bridge between
@@ -33,6 +34,9 @@ import org.apache.skywalking.apm.agent.core.logging.api.ILog;
 public class ConstructorInter {
     private static final ILog LOGGER = LogManager.getLogger(ConstructorInter.class);
 
+    private static final String INTERCEPTOR_TYPE = "constructor";
+
+    private String pluginName;
     /**
      * An {@link InstanceConstructorInterceptor} This name should only stay in {@link String}, the real {@link Class}
      * type will trigger classloader failure. If you want to know more, please check on books about Classloader or
@@ -43,7 +47,8 @@ public class ConstructorInter {
     /**
      * @param constructorInterceptorClassName class full name.
      */
-    public ConstructorInter(String constructorInterceptorClassName, ClassLoader classLoader) throws PluginException {
+    public ConstructorInter(String pluginName, String constructorInterceptorClassName, ClassLoader classLoader) throws PluginException {
+        this.pluginName = pluginName;
         try {
             interceptor = InterceptorInstanceLoader.load(constructorInterceptorClassName, classLoader);
         } catch (Throwable t) {
@@ -59,13 +64,17 @@ public class ConstructorInter {
      */
     @RuntimeType
     public void intercept(@This Object obj, @AllArguments Object[] allArguments) {
+        long interceptorTimeCost = 0L;
+        long startTime = System.nanoTime();
         try {
             EnhancedInstance targetObject = (EnhancedInstance) obj;
 
             interceptor.onConstruct(targetObject, allArguments);
         } catch (Throwable t) {
             LOGGER.error("ConstructorInter failure.", t);
+            AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
         }
-
+        interceptorTimeCost += System.nanoTime() - startTime;
+        AgentSo11y.durationOfInterceptor(interceptorTimeCost);
     }
 }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/InstMethodsInter.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/InstMethodsInter.java
index 81ebfb1b78..581b854de3 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/InstMethodsInter.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/InstMethodsInter.java
@@ -29,6 +29,7 @@ import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
 import org.apache.skywalking.apm.agent.core.plugin.PluginException;
 import org.apache.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoader;
 import org.apache.skywalking.apm.agent.core.logging.api.ILog;
+import org.apache.skywalking.apm.agent.core.so11y.AgentSo11y;
 
 /**
  * The actual byte-buddy's interceptor to intercept class instance methods. In this class, it provides a bridge between
@@ -37,6 +38,9 @@ import org.apache.skywalking.apm.agent.core.logging.api.ILog;
 public class InstMethodsInter {
     private static final ILog LOGGER = LogManager.getLogger(InstMethodsInter.class);
 
+    private static final String INTERCEPTOR_TYPE = "inst";
+
+    private String pluginName;
     /**
      * An {@link InstanceMethodsAroundInterceptor} This name should only stay in {@link String}, the real {@link Class}
      * type will trigger classloader failure. If you want to know more, please check on books about Classloader or
@@ -47,7 +51,8 @@ public class InstMethodsInter {
     /**
      * @param instanceMethodsAroundInterceptorClassName class full name.
      */
-    public InstMethodsInter(String instanceMethodsAroundInterceptorClassName, ClassLoader classLoader) {
+    public InstMethodsInter(String pluginName, String instanceMethodsAroundInterceptorClassName, ClassLoader classLoader) {
+        this.pluginName = pluginName;
         try {
             interceptor = InterceptorInstanceLoader.load(instanceMethodsAroundInterceptorClassName, classLoader);
         } catch (Throwable t) {
@@ -71,12 +76,16 @@ public class InstMethodsInter {
         @Origin Method method) throws Throwable {
         EnhancedInstance targetObject = (EnhancedInstance) obj;
 
+        long interceptorTimeCost = 0L;
+        long startTimeOfMethodBeforeInter = System.nanoTime();
         MethodInterceptResult result = new MethodInterceptResult();
         try {
             interceptor.beforeMethod(targetObject, method, allArguments, method.getParameterTypes(), result);
         } catch (Throwable t) {
             LOGGER.error(t, "class[{}] before method[{}] intercept failure", obj.getClass(), method.getName());
+            AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
         }
+        interceptorTimeCost += System.nanoTime() - startTimeOfMethodBeforeInter;
 
         Object ret = null;
         try {
@@ -86,19 +95,27 @@ public class InstMethodsInter {
                 ret = zuper.call();
             }
         } catch (Throwable t) {
+            long startTimeOfMethodHandleExceptionInter = System.nanoTime();
             try {
                 interceptor.handleMethodException(targetObject, method, allArguments, method.getParameterTypes(), t);
             } catch (Throwable t2) {
                 LOGGER.error(t2, "class[{}] handle method[{}] exception failure", obj.getClass(), method.getName());
+                AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodHandleExceptionInter;
             throw t;
         } finally {
+            long startTimeOfMethodAfterInter = System.nanoTime();
             try {
                 ret = interceptor.afterMethod(targetObject, method, allArguments, method.getParameterTypes(), ret);
             } catch (Throwable t) {
                 LOGGER.error(t, "class[{}] after method[{}] intercept failure", obj.getClass(), method.getName());
+                AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodAfterInter;
         }
+        AgentSo11y.durationOfInterceptor(interceptorTimeCost);
+
         return ret;
     }
 }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/InstMethodsInterWithOverrideArgs.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/InstMethodsInterWithOverrideArgs.java
index 1bba49c177..fabe5094e3 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/InstMethodsInterWithOverrideArgs.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/InstMethodsInterWithOverrideArgs.java
@@ -28,6 +28,7 @@ import org.apache.skywalking.apm.agent.core.plugin.PluginException;
 import org.apache.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoader;
 import org.apache.skywalking.apm.agent.core.logging.api.ILog;
 import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
+import org.apache.skywalking.apm.agent.core.so11y.AgentSo11y;
 
 /**
  * The actual byte-buddy's interceptor to intercept class instance methods. In this class, it provides a bridge between
@@ -36,6 +37,9 @@ import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
 public class InstMethodsInterWithOverrideArgs {
     private static final ILog LOGGER = LogManager.getLogger(InstMethodsInterWithOverrideArgs.class);
 
+    private static final String INTERCEPTOR_TYPE = "inst";
+
+    private String pluginName;
     /**
      * An {@link InstanceMethodsAroundInterceptor} This name should only stay in {@link String}, the real {@link Class}
      * type will trigger classloader failure. If you want to know more, please check on books about Classloader or
@@ -46,7 +50,8 @@ public class InstMethodsInterWithOverrideArgs {
     /**
      * @param instanceMethodsAroundInterceptorClassName class full name.
      */
-    public InstMethodsInterWithOverrideArgs(String instanceMethodsAroundInterceptorClassName, ClassLoader classLoader) {
+    public InstMethodsInterWithOverrideArgs(String pluginName, String instanceMethodsAroundInterceptorClassName, ClassLoader classLoader) {
+        this.pluginName = pluginName;
         try {
             interceptor = InterceptorInstanceLoader.load(instanceMethodsAroundInterceptorClassName, classLoader);
         } catch (Throwable t) {
@@ -70,12 +75,16 @@ public class InstMethodsInterWithOverrideArgs {
         @Morph OverrideCallable zuper) throws Throwable {
         EnhancedInstance targetObject = (EnhancedInstance) obj;
 
+        long interceptorTimeCost = 0L;
+        long startTimeOfMethodBeforeInter = System.nanoTime();
         MethodInterceptResult result = new MethodInterceptResult();
         try {
             interceptor.beforeMethod(targetObject, method, allArguments, method.getParameterTypes(), result);
         } catch (Throwable t) {
             LOGGER.error(t, "class[{}] before method[{}] intercept failure", obj.getClass(), method.getName());
+            AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
         }
+        interceptorTimeCost += System.nanoTime() - startTimeOfMethodBeforeInter;
 
         Object ret = null;
         try {
@@ -85,19 +94,26 @@ public class InstMethodsInterWithOverrideArgs {
                 ret = zuper.call(allArguments);
             }
         } catch (Throwable t) {
+            long startTimeOfMethodHandleExceptionInter = System.nanoTime();
             try {
                 interceptor.handleMethodException(targetObject, method, allArguments, method.getParameterTypes(), t);
             } catch (Throwable t2) {
                 LOGGER.error(t2, "class[{}] handle method[{}] exception failure", obj.getClass(), method.getName());
+                AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodHandleExceptionInter;
             throw t;
         } finally {
+            long startTimeOfMethodAfterInter = System.nanoTime();
             try {
                 ret = interceptor.afterMethod(targetObject, method, allArguments, method.getParameterTypes(), ret);
             } catch (Throwable t) {
                 LOGGER.error(t, "class[{}] after method[{}] intercept failure", obj.getClass(), method.getName());
+                AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodAfterInter;
         }
+        AgentSo11y.durationOfInterceptor(interceptorTimeCost);
         return ret;
     }
 }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/StaticMethodsInter.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/StaticMethodsInter.java
index 6507118aaf..c1f3564dfe 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/StaticMethodsInter.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/StaticMethodsInter.java
@@ -27,6 +27,7 @@ import net.bytebuddy.implementation.bind.annotation.SuperCall;
 import org.apache.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoader;
 import org.apache.skywalking.apm.agent.core.logging.api.ILog;
 import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
+import org.apache.skywalking.apm.agent.core.so11y.AgentSo11y;
 
 /**
  * The actual byte-buddy's interceptor to intercept class static methods. In this class, it provides a bridge between
@@ -35,6 +36,9 @@ import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
 public class StaticMethodsInter {
     private static final ILog LOGGER = LogManager.getLogger(StaticMethodsInter.class);
 
+    private static final String INTERCEPTOR_TYPE = "static";
+
+    private String pluginName;
     /**
      * A class full name, and instanceof {@link StaticMethodsAroundInterceptor} This name should only stay in {@link
      * String}, the real {@link Class} type will trigger classloader failure. If you want to know more, please check on
@@ -47,7 +51,8 @@ public class StaticMethodsInter {
      *
      * @param staticMethodsAroundInterceptorClassName class full name.
      */
-    public StaticMethodsInter(String staticMethodsAroundInterceptorClassName) {
+    public StaticMethodsInter(String pluginName, String staticMethodsAroundInterceptorClassName) {
+        this.pluginName = pluginName;
         this.staticMethodsAroundInterceptorClassName = staticMethodsAroundInterceptorClassName;
     }
 
@@ -68,12 +73,16 @@ public class StaticMethodsInter {
         StaticMethodsAroundInterceptor interceptor = InterceptorInstanceLoader.load(staticMethodsAroundInterceptorClassName, clazz
             .getClassLoader());
 
+        long interceptorTimeCost = 0L;
+        long startTimeOfMethodBeforeInter = System.nanoTime();
         MethodInterceptResult result = new MethodInterceptResult();
         try {
             interceptor.beforeMethod(clazz, method, allArguments, method.getParameterTypes(), result);
         } catch (Throwable t) {
             LOGGER.error(t, "class[{}] before static method[{}] intercept failure", clazz, method.getName());
+            AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
         }
+        interceptorTimeCost += System.nanoTime() - startTimeOfMethodBeforeInter;
 
         Object ret = null;
         try {
@@ -83,19 +92,27 @@ public class StaticMethodsInter {
                 ret = zuper.call();
             }
         } catch (Throwable t) {
+            long startTimeOfMethodHandleExceptionInter = System.nanoTime();
             try {
                 interceptor.handleMethodException(clazz, method, allArguments, method.getParameterTypes(), t);
             } catch (Throwable t2) {
                 LOGGER.error(t2, "class[{}] handle static method[{}] exception failure", clazz, method.getName(), t2.getMessage());
+                AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodHandleExceptionInter;
             throw t;
         } finally {
+            long startTimeOfMethodAfterInter = System.nanoTime();
             try {
                 ret = interceptor.afterMethod(clazz, method, allArguments, method.getParameterTypes(), ret);
             } catch (Throwable t) {
                 LOGGER.error(t, "class[{}] after static method[{}] intercept failure:{}", clazz, method.getName(), t.getMessage());
+                AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodAfterInter;
         }
+        AgentSo11y.durationOfInterceptor(interceptorTimeCost);
+
         return ret;
     }
 }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/StaticMethodsInterWithOverrideArgs.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/StaticMethodsInterWithOverrideArgs.java
index 83e66e4bcd..23b136fdcf 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/StaticMethodsInterWithOverrideArgs.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/StaticMethodsInterWithOverrideArgs.java
@@ -26,6 +26,7 @@ import net.bytebuddy.implementation.bind.annotation.RuntimeType;
 import org.apache.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoader;
 import org.apache.skywalking.apm.agent.core.logging.api.ILog;
 import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
+import org.apache.skywalking.apm.agent.core.so11y.AgentSo11y;
 
 /**
  * The actual byte-buddy's interceptor to intercept class static methods. In this class, it provides a bridge between
@@ -34,6 +35,9 @@ import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
 public class StaticMethodsInterWithOverrideArgs {
     private static final ILog LOGGER = LogManager.getLogger(StaticMethodsInterWithOverrideArgs.class);
 
+    private static final String INTERCEPTOR_TYPE = "static";
+
+    private String pluginName;
     /**
      * A class full name, and instanceof {@link StaticMethodsAroundInterceptor} This name should only stay in {@link
      * String}, the real {@link Class} type will trigger classloader failure. If you want to know more, please check on
@@ -44,9 +48,11 @@ public class StaticMethodsInterWithOverrideArgs {
     /**
      * Set the name of {@link StaticMethodsInterWithOverrideArgs#staticMethodsAroundInterceptorClassName}
      *
+     * @param pluginName name of interceptor plugin
      * @param staticMethodsAroundInterceptorClassName class full name.
      */
-    public StaticMethodsInterWithOverrideArgs(String staticMethodsAroundInterceptorClassName) {
+    public StaticMethodsInterWithOverrideArgs(String pluginName, String staticMethodsAroundInterceptorClassName) {
+        this.pluginName = pluginName;
         this.staticMethodsAroundInterceptorClassName = staticMethodsAroundInterceptorClassName;
     }
 
@@ -67,12 +73,16 @@ public class StaticMethodsInterWithOverrideArgs {
         StaticMethodsAroundInterceptor interceptor = InterceptorInstanceLoader.load(staticMethodsAroundInterceptorClassName, clazz
             .getClassLoader());
 
+        long interceptorTimeCost = 0L;
+        long startTimeOfMethodBeforeInter = System.nanoTime();
         MethodInterceptResult result = new MethodInterceptResult();
         try {
             interceptor.beforeMethod(clazz, method, allArguments, method.getParameterTypes(), result);
         } catch (Throwable t) {
             LOGGER.error(t, "class[{}] before static method[{}] intercept failure", clazz, method.getName());
+            AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
         }
+        interceptorTimeCost += System.nanoTime() - startTimeOfMethodBeforeInter;
 
         Object ret = null;
         try {
@@ -82,19 +92,27 @@ public class StaticMethodsInterWithOverrideArgs {
                 ret = zuper.call(allArguments);
             }
         } catch (Throwable t) {
+            long startTimeOfMethodHandleExceptionInter = System.nanoTime();
             try {
                 interceptor.handleMethodException(clazz, method, allArguments, method.getParameterTypes(), t);
             } catch (Throwable t2) {
                 LOGGER.error(t2, "class[{}] handle static method[{}] exception failure", clazz, method.getName(), t2.getMessage());
+                AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodHandleExceptionInter;
             throw t;
         } finally {
+            long startTimeOfMethodAfterInter = System.nanoTime();
             try {
                 ret = interceptor.afterMethod(clazz, method, allArguments, method.getParameterTypes(), ret);
             } catch (Throwable t) {
                 LOGGER.error(t, "class[{}] after static method[{}] intercept failure:{}", clazz, method.getName(), t.getMessage());
+                AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodAfterInter;
         }
+        AgentSo11y.durationOfInterceptor(interceptorTimeCost);
+
         return ret;
     }
 }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/ClassEnhancePluginDefineV2.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/ClassEnhancePluginDefineV2.java
index 2436c2994b..8ea6cdfb99 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/ClassEnhancePluginDefineV2.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/ClassEnhancePluginDefineV2.java
@@ -87,7 +87,7 @@ public abstract class ClassEnhancePluginDefineV2 extends AbstractClassEnhancePlu
                         isStatic().and(staticMethodsInterceptV2Point.getMethodsMatcher()))
                                                      .intercept(MethodDelegation.withDefaultConfiguration()
                                                                                 .withBinders(Morph.Binder.install(OverrideCallable.class))
-                                                                                .to(new StaticMethodsInterV2WithOverrideArgs(interceptor), delegateNamingResolver.resolve(staticMethodsInterceptV2Point)));
+                                                                                .to(new StaticMethodsInterV2WithOverrideArgs(getPluginName(), interceptor), delegateNamingResolver.resolve(staticMethodsInterceptV2Point)));
                 }
             } else {
                 if (isBootstrapInstrumentation()) {
@@ -99,7 +99,7 @@ public abstract class ClassEnhancePluginDefineV2 extends AbstractClassEnhancePlu
                     newClassBuilder = newClassBuilder.method(
                         isStatic().and(staticMethodsInterceptV2Point.getMethodsMatcher()))
                                                      .intercept(MethodDelegation.withDefaultConfiguration()
-                                                                                .to(new StaticMethodsInterV2(interceptor), delegateNamingResolver.resolve(staticMethodsInterceptV2Point)));
+                                                                                .to(new StaticMethodsInterV2(getPluginName(), interceptor), delegateNamingResolver.resolve(staticMethodsInterceptV2Point)));
                 }
             }
 
@@ -151,7 +151,7 @@ public abstract class ClassEnhancePluginDefineV2 extends AbstractClassEnhancePlu
                 } else {
                     newClassBuilder = newClassBuilder.constructor(constructorInterceptPoint.getConstructorMatcher())
                                                      .intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.withDefaultConfiguration()
-                                                                                                                 .to(new ConstructorInter(constructorInterceptPoint
+                                                                                                                 .to(new ConstructorInter(getPluginName(), constructorInterceptPoint
                                                                                                                                               .getConstructorInterceptor(), classLoader), fieldNamingResolver.resolve(constructorInterceptPoint))));
                 }
             }
@@ -179,7 +179,7 @@ public abstract class ClassEnhancePluginDefineV2 extends AbstractClassEnhancePlu
                         newClassBuilder = newClassBuilder.method(junction)
                                                          .intercept(MethodDelegation.withDefaultConfiguration()
                                                                                     .withBinders(Morph.Binder.install(OverrideCallable.class))
-                                                                                    .to(new InstMethodsInterV2WithOverrideArgs(interceptor, classLoader), fieldNamingResolver.resolve(instanceMethodsInterceptV2Point)));
+                                                                                    .to(new InstMethodsInterV2WithOverrideArgs(getPluginName(), interceptor, classLoader), fieldNamingResolver.resolve(instanceMethodsInterceptV2Point)));
                     }
                 } else {
                     if (isBootstrapInstrumentation()) {
@@ -189,7 +189,7 @@ public abstract class ClassEnhancePluginDefineV2 extends AbstractClassEnhancePlu
                     } else {
                         newClassBuilder = newClassBuilder.method(junction)
                                                          .intercept(MethodDelegation.withDefaultConfiguration()
-                                                                                    .to(new InstMethodsInterV2(interceptor, classLoader), fieldNamingResolver.resolve(instanceMethodsInterceptV2Point)));
+                                                                                    .to(new InstMethodsInterV2(getPluginName(), interceptor, classLoader), fieldNamingResolver.resolve(instanceMethodsInterceptV2Point)));
                     }
                 }
             }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/InstMethodsInterV2.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/InstMethodsInterV2.java
index 8638980931..a46092ad92 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/InstMethodsInterV2.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/InstMethodsInterV2.java
@@ -29,6 +29,7 @@ import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
 import org.apache.skywalking.apm.agent.core.plugin.PluginException;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
 import org.apache.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoader;
+import org.apache.skywalking.apm.agent.core.so11y.AgentSo11y;
 
 /**
  * The actual byte-buddy's interceptor to intercept class instance methods. In this class, it provides a bridge between
@@ -37,9 +38,13 @@ import org.apache.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoa
 public class InstMethodsInterV2 {
     private static final ILog LOGGER = LogManager.getLogger(InstMethodsInterV2.class);
 
+    private static final String INTERCEPTOR_TYPE = "inst";
+
+    private String pluginName;
     private InstanceMethodsAroundInterceptorV2 interceptor;
 
-    public InstMethodsInterV2(String instanceMethodsAroundInterceptorClassName, ClassLoader classLoader) {
+    public InstMethodsInterV2(String pluginName, String instanceMethodsAroundInterceptorClassName, ClassLoader classLoader) {
+        this.pluginName = pluginName;
         try {
             interceptor = InterceptorInstanceLoader.load(instanceMethodsAroundInterceptorClassName, classLoader);
         } catch (Throwable t) {
@@ -52,12 +57,16 @@ public class InstMethodsInterV2 {
                             @Origin Method method) throws Throwable {
         EnhancedInstance targetObject = (EnhancedInstance) obj;
 
+        long interceptorTimeCost = 0L;
+        long startTimeOfMethodBeforeInter = System.nanoTime();
         MethodInvocationContext context = new MethodInvocationContext();
         try {
             interceptor.beforeMethod(targetObject, method, allArguments, method.getParameterTypes(), context);
         } catch (Throwable t) {
             LOGGER.error(t, "class[{}] before method[{}] intercept failure", obj.getClass(), method.getName());
+            AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
         }
+        interceptorTimeCost += System.nanoTime() - startTimeOfMethodBeforeInter;
 
         Object ret = null;
         try {
@@ -67,19 +76,27 @@ public class InstMethodsInterV2 {
                 ret = zuper.call();
             }
         } catch (Throwable t) {
+            long startTimeOfMethodHandleExceptionInter = System.nanoTime();
             try {
                 interceptor.handleMethodException(targetObject, method, allArguments, method.getParameterTypes(), t, context);
             } catch (Throwable t2) {
                 LOGGER.error(t2, "class[{}] handle method[{}] exception failure", obj.getClass(), method.getName());
+                AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodHandleExceptionInter;
             throw t;
         } finally {
+            long startTimeOfMethodAfterInter = System.nanoTime();
             try {
                 ret = interceptor.afterMethod(targetObject, method, allArguments, method.getParameterTypes(), ret, context);
             } catch (Throwable t) {
                 LOGGER.error(t, "class[{}] after method[{}] intercept failure", obj.getClass(), method.getName());
+                AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodAfterInter;
         }
+        AgentSo11y.durationOfInterceptor(interceptorTimeCost);
+
         return ret;
     }
 }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/InstMethodsInterV2WithOverrideArgs.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/InstMethodsInterV2WithOverrideArgs.java
index 5779a386f1..2a937c961a 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/InstMethodsInterV2WithOverrideArgs.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/InstMethodsInterV2WithOverrideArgs.java
@@ -30,6 +30,7 @@ import org.apache.skywalking.apm.agent.core.plugin.PluginException;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.OverrideCallable;
 import org.apache.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoader;
+import org.apache.skywalking.apm.agent.core.so11y.AgentSo11y;
 
 /**
  * The actual byte-buddy's interceptor to intercept class instance methods. In this class, it provides a bridge between
@@ -38,6 +39,9 @@ import org.apache.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoa
 public class InstMethodsInterV2WithOverrideArgs {
     private static final ILog LOGGER = LogManager.getLogger(InstMethodsInterV2WithOverrideArgs.class);
 
+    private static final String INTERCEPTOR_TYPE = "inst";
+
+    private String pluginName;
     /**
      * An {@link InstanceMethodsAroundInterceptorV2} This name should only stay in {@link String}, the real {@link Class}
      * type will trigger classloader failure. If you want to know more, please check on books about Classloader or
@@ -48,7 +52,8 @@ public class InstMethodsInterV2WithOverrideArgs {
     /**
      * @param instanceMethodsAroundInterceptorClassName class full name.
      */
-    public InstMethodsInterV2WithOverrideArgs(String instanceMethodsAroundInterceptorClassName, ClassLoader classLoader) {
+    public InstMethodsInterV2WithOverrideArgs(String pluginName, String instanceMethodsAroundInterceptorClassName, ClassLoader classLoader) {
+        this.pluginName = pluginName;
         try {
             interceptor = InterceptorInstanceLoader.load(instanceMethodsAroundInterceptorClassName, classLoader);
         } catch (Throwable t) {
@@ -72,12 +77,16 @@ public class InstMethodsInterV2WithOverrideArgs {
         @Morph OverrideCallable zuper) throws Throwable {
         EnhancedInstance targetObject = (EnhancedInstance) obj;
 
+        long interceptorTimeCost = 0L;
+        long startTimeOfMethodBeforeInter = System.nanoTime();
         MethodInvocationContext context = new MethodInvocationContext();
         try {
             interceptor.beforeMethod(targetObject, method, allArguments, method.getParameterTypes(), context);
         } catch (Throwable t) {
             LOGGER.error(t, "class[{}] before method[{}] intercept failure", obj.getClass(), method.getName());
+            AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
         }
+        interceptorTimeCost += System.nanoTime() - startTimeOfMethodBeforeInter;
 
         Object ret = null;
         try {
@@ -87,19 +96,27 @@ public class InstMethodsInterV2WithOverrideArgs {
                 ret = zuper.call(allArguments);
             }
         } catch (Throwable t) {
+            long startTimeOfMethodHandleExceptionInter = System.nanoTime();
             try {
                 interceptor.handleMethodException(targetObject, method, allArguments, method.getParameterTypes(), t, context);
             } catch (Throwable t2) {
                 LOGGER.error(t2, "class[{}] handle method[{}] exception failure", obj.getClass(), method.getName());
+                AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodHandleExceptionInter;
             throw t;
         } finally {
+            long startTimeOfMethodAfterInter = System.nanoTime();
             try {
                 ret = interceptor.afterMethod(targetObject, method, allArguments, method.getParameterTypes(), ret, context);
             } catch (Throwable t) {
                 LOGGER.error(t, "class[{}] after method[{}] intercept failure", obj.getClass(), method.getName());
+                AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodAfterInter;
         }
+        AgentSo11y.durationOfInterceptor(interceptorTimeCost);
+
         return ret;
     }
 }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/StaticMethodsInterV2.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/StaticMethodsInterV2.java
index 677ffa3697..add92b4fe1 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/StaticMethodsInterV2.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/StaticMethodsInterV2.java
@@ -27,6 +27,7 @@ import net.bytebuddy.implementation.bind.annotation.SuperCall;
 import org.apache.skywalking.apm.agent.core.logging.api.ILog;
 import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
 import org.apache.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoader;
+import org.apache.skywalking.apm.agent.core.so11y.AgentSo11y;
 
 /**
  * The actual byte-buddy's interceptor to intercept class instance methods. In this class, it provides a bridge between
@@ -35,6 +36,9 @@ import org.apache.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoa
 public class StaticMethodsInterV2 {
     private static final ILog LOGGER = LogManager.getLogger(StaticMethodsInterV2.class);
 
+    private static final String INTERCEPTOR_TYPE = "static";
+
+    private String pluginName;
     /**
      * A class full name, and instanceof {@link StaticMethodsAroundInterceptorV2} This name should only stay in {@link
      * String}, the real {@link Class} type will trigger classloader failure. If you want to know more, please check on
@@ -47,7 +51,8 @@ public class StaticMethodsInterV2 {
      *
      * @param staticMethodsAroundInterceptorClassName class full name.
      */
-    public StaticMethodsInterV2(String staticMethodsAroundInterceptorClassName) {
+    public StaticMethodsInterV2(String pluginName, String staticMethodsAroundInterceptorClassName) {
+        this.pluginName = pluginName;
         this.staticMethodsAroundInterceptorClassName = staticMethodsAroundInterceptorClassName;
     }
 
@@ -68,12 +73,16 @@ public class StaticMethodsInterV2 {
         StaticMethodsAroundInterceptorV2 interceptor = InterceptorInstanceLoader.load(staticMethodsAroundInterceptorClassName,
                                                                                       clazz.getClassLoader());
 
+        long interceptorTimeCost = 0L;
+        long startTimeOfMethodBeforeInter = System.nanoTime();
         MethodInvocationContext context = new MethodInvocationContext();
         try {
             interceptor.beforeMethod(clazz, method, allArguments, method.getParameterTypes(), context);
         } catch (Throwable t) {
             LOGGER.error(t, "class[{}] before static method[{}] intercept failure", clazz, method.getName());
+            AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
         }
+        interceptorTimeCost += System.nanoTime() - startTimeOfMethodBeforeInter;
 
         Object ret = null;
         try {
@@ -83,19 +92,27 @@ public class StaticMethodsInterV2 {
                 ret = zuper.call();
             }
         } catch (Throwable t) {
+            long startTimeOfMethodHandleExceptionInter = System.nanoTime();
             try {
                 interceptor.handleMethodException(clazz, method, allArguments, method.getParameterTypes(), t, context);
             } catch (Throwable t2) {
                 LOGGER.error(t2, "class[{}] handle static method[{}] exception failure", clazz, method.getName(), t2.getMessage());
+                AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodHandleExceptionInter;
             throw t;
         } finally {
+            long startTimeOfMethodAfterInter = System.nanoTime();
             try {
                 ret = interceptor.afterMethod(clazz, method, allArguments, method.getParameterTypes(), ret, context);
             } catch (Throwable t) {
                 LOGGER.error(t, "class[{}] after static method[{}] intercept failure:{}", clazz, method.getName(), t.getMessage());
+                AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodAfterInter;
         }
+        AgentSo11y.durationOfInterceptor(interceptorTimeCost);
+
         return ret;
     }
 }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/StaticMethodsInterV2WithOverrideArgs.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/StaticMethodsInterV2WithOverrideArgs.java
index e7d326b43a..0341e67d0d 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/StaticMethodsInterV2WithOverrideArgs.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/v2/StaticMethodsInterV2WithOverrideArgs.java
@@ -27,6 +27,7 @@ import org.apache.skywalking.apm.agent.core.logging.api.ILog;
 import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.OverrideCallable;
 import org.apache.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoader;
+import org.apache.skywalking.apm.agent.core.so11y.AgentSo11y;
 
 /**
  * The actual byte-buddy's interceptor to intercept class instance methods. In this class, it provides a bridge between
@@ -35,6 +36,9 @@ import org.apache.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoa
 public class StaticMethodsInterV2WithOverrideArgs {
     private static final ILog LOGGER = LogManager.getLogger(StaticMethodsInterV2WithOverrideArgs.class);
 
+    private static final String INTERCEPTOR_TYPE = "static";
+
+    private String pluginName;
     /**
      * A class full name, and instanceof {@link StaticMethodsAroundInterceptorV2} This name should only stay in {@link
      * String}, the real {@link Class} type will trigger classloader failure. If you want to know more, please check on
@@ -47,7 +51,8 @@ public class StaticMethodsInterV2WithOverrideArgs {
      *
      * @param staticMethodsAroundInterceptorClassName class full name.
      */
-    public StaticMethodsInterV2WithOverrideArgs(String staticMethodsAroundInterceptorClassName) {
+    public StaticMethodsInterV2WithOverrideArgs(String pluginName, String staticMethodsAroundInterceptorClassName) {
+        this.pluginName = pluginName;
         this.staticMethodsAroundInterceptorClassName = staticMethodsAroundInterceptorClassName;
     }
 
@@ -68,12 +73,16 @@ public class StaticMethodsInterV2WithOverrideArgs {
         StaticMethodsAroundInterceptorV2 interceptor = InterceptorInstanceLoader.load(staticMethodsAroundInterceptorClassName,
                                                                                       clazz.getClassLoader());
 
+        long interceptorTimeCost = 0L;
+        long startTimeOfMethodBeforeInter = System.nanoTime();
         MethodInvocationContext context = new MethodInvocationContext();
         try {
             interceptor.beforeMethod(clazz, method, allArguments, method.getParameterTypes(), context);
         } catch (Throwable t) {
             LOGGER.error(t, "class[{}] before static method[{}] intercept failure", clazz, method.getName());
+            AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
         }
+        interceptorTimeCost += System.nanoTime() - startTimeOfMethodBeforeInter;
 
         Object ret = null;
         try {
@@ -83,19 +92,27 @@ public class StaticMethodsInterV2WithOverrideArgs {
                 ret = zuper.call(allArguments);
             }
         } catch (Throwable t) {
+            long startTimeOfMethodHandleExceptionInter = System.nanoTime();
             try {
                 interceptor.handleMethodException(clazz, method, allArguments, method.getParameterTypes(), t, context);
             } catch (Throwable t2) {
                 LOGGER.error(t2, "class[{}] handle static method[{}] exception failure", clazz, method.getName(), t2.getMessage());
+                AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodHandleExceptionInter;
             throw t;
         } finally {
+            long startTimeOfMethodAfterInter = System.nanoTime();
             try {
                 ret = interceptor.afterMethod(clazz, method, allArguments, method.getParameterTypes(), ret, context);
             } catch (Throwable t) {
                 LOGGER.error(t, "class[{}] after static method[{}] intercept failure:{}", clazz, method.getName(), t.getMessage());
+                AgentSo11y.errorOfPlugin(pluginName, INTERCEPTOR_TYPE);
             }
+            interceptorTimeCost += System.nanoTime() - startTimeOfMethodAfterInter;
         }
+        AgentSo11y.durationOfInterceptor(interceptorTimeCost);
+
         return ret;
     }
 }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/so11y/AgentSo11y.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/so11y/AgentSo11y.java
new file mode 100644
index 0000000000..b1468f293a
--- /dev/null
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/so11y/AgentSo11y.java
@@ -0,0 +1,153 @@
+/*
+ * 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.so11y;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.skywalking.apm.agent.core.meter.Counter;
+import org.apache.skywalking.apm.agent.core.meter.Histogram;
+import org.apache.skywalking.apm.agent.core.meter.MeterFactory;
+
+/**
+ * Agent self-observability meters collect through skywalking native protocols
+ */
+public class AgentSo11y {
+
+    // A map to cache meter obj(s) for plugins. The key is the plugin name.
+    private static final Map<String, Counter> ERROR_COUNTER_CACHE = new ConcurrentHashMap<>();
+
+    // Steps of interceptor time cost histogram
+    private static final List<Double> TIME_COST_HISTOGRAM_STEPS = Arrays.asList(
+        1000d, 10000d, 50000d, 100000d, 300000d, 500000d,
+        1000000d, 5000000d, 10000000d, 20000000d, 50000000d, 100000000d
+    );
+
+    // context counter
+    private static Counter PROPAGATED_CONTEXT_COUNTER;
+    private static Counter SAMPLER_CONTEXT_COUNTER;
+    private static Counter FINISH_CONTEXT_COUNTER;
+
+    // ignore context counter
+    private static Counter PROPAGATED_IGNORE_CONTEXT_COUNTER;
+    private static Counter SAMPLER_IGNORE_CONTEXT_COUNTER;
+    private static Counter FINISH_IGNORE_CONTEXT_COUNTER;
+
+    // leaked context counter
+    private static Counter LEAKED_CONTEXT_COUNTER;
+    private static Counter LEAKED_IGNORE_CONTEXT_COUNTER;
+
+    // context perf histogram
+    private static Histogram INTERCEPTOR_TIME_COST;
+
+    public static void measureTracingContextCreation(boolean forceSampling, boolean ignoredTracingContext) {
+        if (forceSampling) {
+            if (ignoredTracingContext) {
+                if (PROPAGATED_IGNORE_CONTEXT_COUNTER == null) {
+                    PROPAGATED_IGNORE_CONTEXT_COUNTER = MeterFactory
+                        .counter("created_ignored_context_counter")
+                        .tag("created_by", "propagated")
+                        .build();
+                }
+                PROPAGATED_IGNORE_CONTEXT_COUNTER.increment(1);
+            } else {
+                if (PROPAGATED_CONTEXT_COUNTER == null) {
+                    PROPAGATED_CONTEXT_COUNTER = MeterFactory
+                        .counter("created_tracing_context_counter")
+                        .tag("created_by", "propagated")
+                        .build();
+                }
+                PROPAGATED_CONTEXT_COUNTER.increment(1);
+            }
+        } else {
+            if (ignoredTracingContext) {
+                if (SAMPLER_IGNORE_CONTEXT_COUNTER == null) {
+                    SAMPLER_IGNORE_CONTEXT_COUNTER = MeterFactory
+                        .counter("created_ignored_context_counter")
+                        .tag("created_by", "sampler")
+                        .build();
+                }
+                SAMPLER_IGNORE_CONTEXT_COUNTER.increment(1);
+            } else {
+                if (SAMPLER_CONTEXT_COUNTER == null) {
+                    SAMPLER_CONTEXT_COUNTER = MeterFactory
+                        .counter("created_tracing_context_counter")
+                        .tag("created_by", "sampler")
+                        .build();
+                }
+                SAMPLER_CONTEXT_COUNTER.increment(1);
+            }
+        }
+    }
+
+    public static void measureTracingContextCompletion(boolean ignoredTracingContext) {
+        if (ignoredTracingContext) {
+            if (FINISH_IGNORE_CONTEXT_COUNTER == null) {
+                FINISH_IGNORE_CONTEXT_COUNTER = MeterFactory.counter("finished_ignored_context_counter").build();
+            }
+            FINISH_IGNORE_CONTEXT_COUNTER.increment(1);
+        } else {
+            if (FINISH_CONTEXT_COUNTER == null) {
+                FINISH_CONTEXT_COUNTER = MeterFactory.counter("finished_tracing_context_counter").build();
+            }
+            FINISH_CONTEXT_COUNTER.increment(1);
+        }
+    }
+
+    public static void measureLeakedTracingContext(boolean ignoredTracingContext) {
+        if (ignoredTracingContext) {
+            if (LEAKED_IGNORE_CONTEXT_COUNTER == null) {
+                LEAKED_IGNORE_CONTEXT_COUNTER = MeterFactory
+                    .counter("possible_leaked_context_counter")
+                    .tag("source", "ignore")
+                    .build();
+            }
+            LEAKED_IGNORE_CONTEXT_COUNTER.increment(1);
+        } else {
+            if (LEAKED_CONTEXT_COUNTER == null) {
+                LEAKED_CONTEXT_COUNTER = MeterFactory
+                    .counter("possible_leaked_context_counter")
+                    .tag("source", "tracing")
+                    .build();
+            }
+            LEAKED_CONTEXT_COUNTER.increment(1);
+        }
+    }
+
+    public static void durationOfInterceptor(double timeCostInNanos) {
+        if (INTERCEPTOR_TIME_COST == null) {
+            INTERCEPTOR_TIME_COST = MeterFactory
+                .histogram("tracing_context_performance")
+                .steps(TIME_COST_HISTOGRAM_STEPS)
+                .build();
+        }
+        INTERCEPTOR_TIME_COST.addValue(timeCostInNanos);
+    }
+
+    public static void errorOfPlugin(String pluginName, String interType) {
+        Counter counter = ERROR_COUNTER_CACHE.computeIfAbsent(pluginName + interType, key -> MeterFactory
+            .counter("interceptor_error_counter")
+            .tag("plugin_name", pluginName)
+            .tag("inter_type", interType)
+            .build()
+        );
+        counter.increment(1);
+    }
+}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/so11y/bootstrap/BootstrapPluginSo11y.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/so11y/bootstrap/BootstrapPluginSo11y.java
new file mode 100644
index 0000000000..e0032ac7d3
--- /dev/null
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/so11y/bootstrap/BootstrapPluginSo11y.java
@@ -0,0 +1,25 @@
+/*
+ * 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.so11y.bootstrap;
+
+public interface BootstrapPluginSo11y {
+    void duration(double timeCostInNanos);
+
+    void error(String pluginName, String interType);
+}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/so11y/bootstrap/BootstrapPluginSo11yBridge.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/so11y/bootstrap/BootstrapPluginSo11yBridge.java
new file mode 100644
index 0000000000..2c9ac37600
--- /dev/null
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/so11y/bootstrap/BootstrapPluginSo11yBridge.java
@@ -0,0 +1,46 @@
+/*
+ * 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.so11y.bootstrap;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.BootstrapInterRuntimeAssist;
+import org.apache.skywalking.apm.agent.core.so11y.AgentSo11y;
+
+/**
+ * used by {@link BootstrapInterRuntimeAssist}
+ */
+@SuppressWarnings("unused")
+public class BootstrapPluginSo11yBridge implements BootstrapPluginSo11y {
+
+    public static BootstrapPluginSo11y getSo11y() {
+        return new BootstrapPluginSo11yBridge();
+    }
+
+    private BootstrapPluginSo11yBridge() {
+    }
+
+    @Override
+    public void duration(final double timeCostInNanos) {
+        AgentSo11y.durationOfInterceptor(timeCostInNanos);
+    }
+
+    @Override
+    public void error(final String pluginName, final String interType) {
+        AgentSo11y.errorOfPlugin(pluginName, interType);
+    }
+}
diff --git a/docs/en/setup/service-agent/java-agent/Agent-self-observability.md b/docs/en/setup/service-agent/java-agent/Agent-self-observability.md
new file mode 100644
index 0000000000..7efa7ee1b4
--- /dev/null
+++ b/docs/en/setup/service-agent/java-agent/Agent-self-observability.md
@@ -0,0 +1,16 @@
+# Agent Self Observability
+The Java Agent self-observability feature is built-in and used to measure the tracing performance and error statistics of plugins.
+
+It reports meters to SkyWalking oap through native meter protocol, OAP receives and analyzes meters, 
+which are ultimately presented on the [Java Agent self-observability dashboard](https://skywalking.apache.org/docs/main/next/en/setup/backend/dashboards-so11y-java-agent/).
+
+***Note: Java Agent self-observability dashboard is available since OAP 10.1.0***
+
+# Details of agent so11y meters
+- `created_tracing_context_counter` - Counter. The number of created tracing contexts. This includes a label=created_by(value=sampler,propagated). `created_by=propagated` means the agent created the context due to downstream service added sw8 header to trigger force sampling. `created_by=sampler` means the agent created this context by local sampler no matter which policy it uses.
+- `finished_tracing_context_counter` - Counter. The number of finished contexts. The gap between `finished_tracing_context_counter` and `created_tracing_context_counter` should be relatively stable, otherwise, the memory cost would be increased.
+- `created_ignored_context_counter` and `finished_ignored_context_counter`. Same concepts like `*_tracing_context_counter`.
+- `interceptor_error_counter` - Counter. The number of errors happened in the interceptor logic, with `label=plugin_name, inter_type(constructor, inst, static)`. We don't add interceptor names into labels in case of OOM. The number of plugins is only dozens, it is predictable, but the number of interceptors will be hundreds.
+- `possible_leaked_context_counter` - Counter. The number of detected leaked contexts. It should include the `label=source(value=tracing, ignore)`. When `source=tracing`, it is today's shadow tracing context. But now, it is measured.
+- `tracing_context_performance` - Histogram. For successfully finished tracing context, it measures every interceptor's time cost(by using nanoseconds), the buckets of the histogram are {1000, 10000, 50000, 100000, 300000, 500000,
+  1000000, 5000000, 10000000, 20000000, 50000000, 100000000}ns. This provides the performance behavior for the tracing operations.
\ No newline at end of file
diff --git a/docs/en/setup/service-agent/java-agent/Plugin-test.md b/docs/en/setup/service-agent/java-agent/Plugin-test.md
index e67c365672..c91402e6c5 100644
--- a/docs/en/setup/service-agent/java-agent/Plugin-test.md
+++ b/docs/en/setup/service-agent/java-agent/Plugin-test.md
@@ -107,7 +107,7 @@ File Name | Descriptions
 | startScript | Path of the start up script. Required in `type: jvm` only.
 | runningMode | Running mode with the optional plugin, options, `default`(default), `with_optional`, or `with_bootstrap`.
 | withPlugins | Plugin selector rule, e.g.:`apm-spring-annotation-plugin-*.jar`. Required for `runningMode=with_optional` or `runningMode=with_bootstrap`.
-| environment | Same as `docker-compose#environment`.
+| environment | Same as `docker-compose#environment` and also used as `docker run` environment variables.
 | depends_on | Same as `docker-compose#depends_on`.
 | dependencies | Same as `docker-compose#services`, `image`, `links`, `hostname`, `command`, `environment` and `depends_on` are supported.
 
diff --git a/docs/menu.yml b/docs/menu.yml
index 3964b059be..7bfc420672 100644
--- a/docs/menu.yml
+++ b/docs/menu.yml
@@ -88,7 +88,11 @@ catalog:
         path: "/en/setup/service-agent/java-agent/configuration-discovery"
       - name: "Advanced reporters"
         path: "/en/setup/service-agent/java-agent/advanced-reporters"
-      - name: "Plugin development guide"
+      - name: "Agent Self Observability"
+        path: "/en/setup/service-agent/java-agent/Agent-self-observability"
+      - name: "Plugin Test Guide"
+        path: "/en/setup/service-agent/java-agent/Plugin-test/"
+      - name: "Plugin Development Guide"
         path: "/en/setup/service-agent/java-agent/java-plugin-development-guide/"
       - name: "Java Agent Performance Test"
         path: "https://skyapmtest.github.io/Agent-Benchmarks/"
diff --git a/test/plugin/runner-helper/src/main/resources/compose-start-script.template b/test/plugin/runner-helper/src/main/resources/compose-start-script.template
index 6ee08de4b5..3ef6a15466 100644
--- a/test/plugin/runner-helper/src/main/resources/compose-start-script.template
+++ b/test/plugin/runner-helper/src/main/resources/compose-start-script.template
@@ -26,7 +26,7 @@ docker_container_name="${docker_container_name}_1"
 
 <#noparse>
 container_name="${project_name}_${docker_container_name}"
-docker-compose -p ${project_name} -f ${compose_file} up -d
+docker compose -p ${project_name} -f ${compose_file} up -d
 
 container_id=`docker ps -qf "name=${container_name}"`
 if [[ -z "${container_id}" ]]; then
@@ -38,8 +38,8 @@ else
     [[ $status -ne 0 ]] && docker logs ${container_id} >&2
     docker logs ${container_id} >${SCENARIO_HOME}/logs/container.log
 
-    docker-compose -p ${project_name} -f ${compose_file} kill
-    docker-compose -p ${project_name} -f ${compose_file} rm -f
+    docker compose -p ${project_name} -f ${compose_file} kill
+    docker compose -p ${project_name} -f ${compose_file} rm -f
 fi
 </#noparse>
 
diff --git a/test/plugin/runner-helper/src/main/resources/container-start-script.template b/test/plugin/runner-helper/src/main/resources/container-start-script.template
index 108fb0bf20..0f072afdf1 100644
--- a/test/plugin/runner-helper/src/main/resources/container-start-script.template
+++ b/test/plugin/runner-helper/src/main/resources/container-start-script.template
@@ -33,6 +33,11 @@ docker run -d \
         <#if debug_mode??>
         --env DEBUG_MODE=${debug_mode} \
         </#if>
+        <#if environments??>
+        <#list environments as env>
+        --env ${env} \
+        </#list>
+        </#if>
         -v ${agent_home}:/usr/local/skywalking/scenario/agent \
         -v ${scenario_home}:/usr/local/skywalking/scenario \
         -v ${jacoco_home}:/jacoco \
diff --git a/test/plugin/scenarios/agent-so11y-scenario/bin/startup.sh b/test/plugin/scenarios/agent-so11y-scenario/bin/startup.sh
new file mode 100644
index 0000000000..e4140338be
--- /dev/null
+++ b/test/plugin/scenarios/agent-so11y-scenario/bin/startup.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# 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.
+
+home="$(cd "$(dirname $0)"; pwd)"
+
+java -jar ${agent_opts} ${home}/../libs/agent-so11y-scenario.jar &
\ No newline at end of file
diff --git a/test/plugin/scenarios/agent-so11y-scenario/config/expectedData.yaml b/test/plugin/scenarios/agent-so11y-scenario/config/expectedData.yaml
new file mode 100644
index 0000000000..8e044e041f
--- /dev/null
+++ b/test/plugin/scenarios/agent-so11y-scenario/config/expectedData.yaml
@@ -0,0 +1,177 @@
+# 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.
+segmentItems:
+- serviceName: agent-so11y-scenario
+  segmentSize: gt 1
+  segments:
+  - segmentId: not null
+    spans:
+    - operationName: H2/JDBC/PreparedStatement/execute
+      parentSpanId: 0
+      spanId: 1
+      spanLayer: Database
+      startTime: gt 0
+      endTime: gt 0
+      componentId: 32
+      isError: false
+      spanType: Exit
+      peer: localhost:-1
+      tags:
+      - {key: db.type, value: H2}
+      - {key: db.instance, value: test}
+      - key: db.statement
+        value: "CREATE TABLE test_007(\nid VARCHAR(1) PRIMARY KEY, \nvalue VARCHAR(1)\
+          \ NOT NULL)"
+      skipAnalysis: 'false'
+    - operationName: H2/JDBC/CallableStatement/execute
+      parentSpanId: 0
+      spanId: 2
+      spanLayer: Database
+      startTime: gt 0
+      endTime: gt 0
+      componentId: 32
+      isError: false
+      spanType: Exit
+      peer: localhost:-1
+      tags:
+      - {key: db.type, value: H2}
+      - {key: db.instance, value: test}
+      - {key: db.statement, value: 'INSERT INTO test_007(id, value) VALUES(?,?)'}
+      skipAnalysis: 'false'
+    - operationName: H2/JDBC/Statement/execute
+      parentSpanId: 0
+      spanId: 3
+      spanLayer: Database
+      startTime: gt 0
+      endTime: gt 0
+      componentId: 32
+      isError: false
+      spanType: Exit
+      peer: localhost:-1
+      tags:
+      - {key: db.type, value: H2}
+      - {key: db.instance, value: test}
+      - {key: db.statement, value: DROP table test_007}
+      skipAnalysis: 'false'
+    - operationName: /agent-so11y-scenario/case/ignore.html
+      parentSpanId: 0
+      spanId: 4
+      spanLayer: Http
+      startTime: gt 0
+      endTime: gt 0
+      componentId: 66
+      isError: false
+      spanType: Exit
+      peer: localhost:8080
+      tags:
+        - {key: http.method, value: GET}
+        - {key: url, value: 'http://localhost:8080/agent-so11y-scenario/case/ignore.html'}
+        - {key: http.status_code, value: '200'}
+      skipAnalysis: 'false'
+    - operationName: /agent-so11y-scenario/case/propagated
+      parentSpanId: 0
+      spanId: 5
+      spanLayer: Http
+      startTime: gt 0
+      endTime: gt 0
+      componentId: 66
+      isError: false
+      spanType: Exit
+      peer: localhost:8080
+      tags:
+        - {key: http.method, value: GET}
+        - {key: url, value: 'http://localhost:8080/agent-so11y-scenario/case/propagated'}
+        - {key: http.status_code, value: '200'}
+      skipAnalysis: 'false'
+    - operationName: GET:/agent-so11y-scenario/case/agent-so11y-scenario
+      parentSpanId: -1
+      spanId: 0
+      spanLayer: Http
+      startTime: gt 0
+      endTime: gt 0
+      componentId: 1
+      isError: false
+      spanType: Entry
+      peer: ''
+      tags:
+      - {key: url, value: 'http://localhost:8080/agent-so11y-scenario/case/agent-so11y-scenario'}
+      - {key: http.method, value: GET}
+      - {key: http.status_code, value: '200'}
+      skipAnalysis: 'false'
+  - segmentId: not null
+    spans:
+    - operationName: GET:/agent-so11y-scenario/case/propagated
+      parentSpanId: -1
+      spanId: 0
+      spanLayer: Http
+      startTime: gt 0
+      endTime: gt 0
+      componentId: 1
+      isError: false
+      spanType: Entry
+      peer: ''
+      tags:
+      - {key: url, value: 'http://localhost:8080/agent-so11y-scenario/case/propagated'}
+      - {key: http.method, value: GET}
+      - {key: http.status_code, value: '200'}
+      skipAnalysis: 'false'
+      refs:
+      - {parentEndpoint: 'GET:/agent-so11y-scenario/case/agent-so11y-scenario', networkAddress: 'localhost:8080',
+        refType: CrossProcess, parentSpanId: 5, parentTraceSegmentId: not null,
+        parentServiceInstance: not null, parentService: agent-so11y-scenario,
+        traceId: not null}
+
+meterItems:
+- serviceName: agent-so11y-scenario
+  meterSize: ge 9
+  meters:
+  - meterId:
+      name: created_tracing_context_counter
+      tags:
+      - {name: created_by, value: propagated}
+    singleValue: 1.0
+  - meterId:
+      name: created_tracing_context_counter
+      tags:
+      - {name: created_by, value: sampler}
+    singleValue: 1.0
+  - meterId:
+      name: finished_tracing_context_counter
+      tags: []
+    singleValue: 2.0
+  - meterId:
+      name: created_ignored_context_counter
+      tags:
+      - {name: created_by, value: propagated}
+    singleValue: 1.0
+  - meterId:
+      name: created_ignored_context_counter
+      tags:
+      - {name: created_by, value: sampler}
+    singleValue: 1.0
+  - meterId:
+      name: finished_ignored_context_counter
+      tags: []
+    singleValue: 2.0
+  - meterId:
+      name: tracing_context_performance
+      tags: []
+    histogramBuckets: [0.0, 1000.0, 10000.0, 50000.0, 100000.0, 300000.0, 500000.0, 1000000.0, 5000000.0, 1.0E7, 2.0E7, 5.0E7, 1.0E8]
+  - meterId:
+      name: possible_leaked_context_counter
+      tags:
+      - {name: source, value: tracing}
+    singleValue: 1.0
diff --git a/test/plugin/scenarios/agent-so11y-scenario/configuration.yml b/test/plugin/scenarios/agent-so11y-scenario/configuration.yml
new file mode 100644
index 0000000000..7d9a31395c
--- /dev/null
+++ b/test/plugin/scenarios/agent-so11y-scenario/configuration.yml
@@ -0,0 +1,25 @@
+# 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.
+
+type: jvm
+entryService: http://localhost:8080/agent-so11y-scenario/case/agent-so11y-scenario
+healthCheck: http://localhost:8080/agent-so11y-scenario/case/healthCheck.html
+runningMode: with_bootstrap
+withPlugins: apm-jdk-http-plugin-*.jar
+startScript: ./bin/startup.sh
+environment:
+  - SW_AGENT_SPAN_LIMIT=6
+  - SW_METER_REPORT_INTERVAL=1
diff --git a/test/plugin/scenarios/agent-so11y-scenario/pom.xml b/test/plugin/scenarios/agent-so11y-scenario/pom.xml
new file mode 100644
index 0000000000..39095c57ad
--- /dev/null
+++ b/test/plugin/scenarios/agent-so11y-scenario/pom.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  ~
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <groupId>org.apache.skywalking.apm.testcase</groupId>
+    <artifactId>agent-so11y-scenario</artifactId>
+    <version>1.0.0</version>
+    <packaging>jar</packaging>
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <compiler.version>1.8</compiler.version>
+        <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
+        <test.framework.version>1.0.0</test.framework.version>
+        <h2.version>1.4.177</h2.version>
+        <spring.boot.version>2.5.6</spring.boot.version>
+        <lombok.version>1.18.20</lombok.version>
+    </properties>
+
+    <name>skywalking-agent-so11y-scenario</name>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring.boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-log4j2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>${lombok.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <version>${h2.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>agent-so11y-scenario</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring.boot.version}</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>${maven-compiler-plugin.version}</version>
+                <configuration>
+                    <source>${compiler.version}</source>
+                    <target>${compiler.version}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>assemble</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <descriptors>
+                                <descriptor>src/main/assembly/assembly.xml</descriptor>
+                            </descriptors>
+                            <outputDirectory>./target/</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/test/plugin/scenarios/agent-so11y-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/agent-so11y-scenario/src/main/assembly/assembly.xml
new file mode 100644
index 0000000000..abd3f9e799
--- /dev/null
+++ b/test/plugin/scenarios/agent-so11y-scenario/src/main/assembly/assembly.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  ~
+  -->
+<assembly
+    xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+    <formats>
+        <format>zip</format>
+    </formats>
+
+    <fileSets>
+        <fileSet>
+            <directory>./bin</directory>
+            <fileMode>0775</fileMode>
+        </fileSet>
+    </fileSets>
+
+    <files>
+        <file>
+            <source>${project.build.directory}/agent-so11y-scenario.jar</source>
+            <outputDirectory>./libs</outputDirectory>
+            <fileMode>0775</fileMode>
+        </file>
+    </files>
+</assembly>
diff --git a/test/plugin/scenarios/agent-so11y-scenario/src/main/java/org/apache/skywalking/apm/testcase/h2/Application.java b/test/plugin/scenarios/agent-so11y-scenario/src/main/java/org/apache/skywalking/apm/testcase/h2/Application.java
new file mode 100644
index 0000000000..e063f8d641
--- /dev/null
+++ b/test/plugin/scenarios/agent-so11y-scenario/src/main/java/org/apache/skywalking/apm/testcase/h2/Application.java
@@ -0,0 +1,30 @@
+/*
+ * 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.testcase.h2;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class, args);
+    }
+}
diff --git a/test/plugin/scenarios/agent-so11y-scenario/src/main/java/org/apache/skywalking/apm/testcase/h2/controller/CaseController.java b/test/plugin/scenarios/agent-so11y-scenario/src/main/java/org/apache/skywalking/apm/testcase/h2/controller/CaseController.java
new file mode 100644
index 0000000000..ee8760cb50
--- /dev/null
+++ b/test/plugin/scenarios/agent-so11y-scenario/src/main/java/org/apache/skywalking/apm/testcase/h2/controller/CaseController.java
@@ -0,0 +1,76 @@
+/*
+ * 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.testcase.h2.controller;
+
+import java.net.URL;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/case")
+@Log4j2
+public class CaseController {
+
+    private static final String SUCCESS = "Success";
+
+    private static final String CREATE_TABLE_SQL = "CREATE TABLE test_007(\n" +
+        "id VARCHAR(1) PRIMARY KEY, \n" +
+        "value VARCHAR(1) NOT NULL)";
+    private static final String INSERT_DATA_SQL = "INSERT INTO test_007(id, value) VALUES(?,?)";
+    private static final String DROP_TABLE_SQL = "DROP table test_007";
+
+    @RequestMapping("/healthCheck.html")
+    @ResponseBody
+    public String healthCheck() {
+        // your codes
+        return SUCCESS;
+    }
+
+    @RequestMapping("/agent-so11y-scenario")
+    @ResponseBody
+    public String testcase() throws Exception {
+        try (SQLExecutor sqlExecute = new SQLExecutor()) {
+            sqlExecute.createTable(CREATE_TABLE_SQL);
+            sqlExecute.insertData(INSERT_DATA_SQL, "1", "1");
+            sqlExecute.dropTable(DROP_TABLE_SQL);
+
+            // test bootstrap plugin & ignore context counter
+            new URL("http://localhost:8080/agent-so11y-scenario/case/ignore.html").getContent();
+            new URL("http://localhost:8080/agent-so11y-scenario/case/propagated").getContent();
+        } catch (Exception e) {
+            log.error("Failed to execute sql.", e);
+            throw e;
+        }
+        return SUCCESS;
+    }
+
+    @RequestMapping("/ignore.html")
+    @ResponseBody
+    public String ignorePath() {
+        return SUCCESS;
+    }
+
+    @RequestMapping("/propagated")
+    @ResponseBody
+    public String propagated() {
+        return SUCCESS;
+    }
+}
diff --git a/test/plugin/scenarios/agent-so11y-scenario/src/main/java/org/apache/skywalking/apm/testcase/h2/controller/SQLExecutor.java b/test/plugin/scenarios/agent-so11y-scenario/src/main/java/org/apache/skywalking/apm/testcase/h2/controller/SQLExecutor.java
new file mode 100644
index 0000000000..1f6e3b3463
--- /dev/null
+++ b/test/plugin/scenarios/agent-so11y-scenario/src/main/java/org/apache/skywalking/apm/testcase/h2/controller/SQLExecutor.java
@@ -0,0 +1,75 @@
+/*
+ * 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.testcase.h2.controller;
+
+import java.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+public class SQLExecutor implements AutoCloseable {
+
+    private static final String URL = "jdbc:h2:mem:test";
+    private static final String USERNAME = "root";
+    private static final String PASSWORD = "root";
+
+    private Connection connection;
+
+    public SQLExecutor() throws SQLException {
+        try {
+            Class.forName("org.h2.Driver");
+        } catch (ClassNotFoundException e) {
+            //
+        }
+        connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
+    }
+
+    public void createTable(String sql) throws SQLException {
+        PreparedStatement preparedStatement = connection.prepareStatement(sql);
+        preparedStatement.execute();
+        preparedStatement.close();
+    }
+
+    public void insertData(String sql, String id, String value) throws SQLException {
+        CallableStatement preparedStatement = connection.prepareCall(sql);
+        preparedStatement.setString(1, id);
+        preparedStatement.setString(2, value);
+        preparedStatement.execute();
+        preparedStatement.close();
+    }
+
+    public void dropTable(String sql) throws SQLException {
+        Statement preparedStatement = connection.createStatement();
+        preparedStatement.execute(sql);
+        preparedStatement.close();
+    }
+
+    public void closeConnection() throws SQLException {
+        if (this.connection != null) {
+            this.connection.close();
+        }
+    }
+
+    @Override
+    public void close() throws Exception {
+        closeConnection();
+    }
+}
diff --git a/test/plugin/scenarios/agent-so11y-scenario/src/main/resources/application.yaml b/test/plugin/scenarios/agent-so11y-scenario/src/main/resources/application.yaml
new file mode 100644
index 0000000000..8e987fed1a
--- /dev/null
+++ b/test/plugin/scenarios/agent-so11y-scenario/src/main/resources/application.yaml
@@ -0,0 +1,23 @@
+#
+# 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.
+#
+#
+server:
+  port: 8080
+  servlet:
+    context-path: /agent-so11y-scenario
+logging:
+  config: classpath:log4j2.xml
\ No newline at end of file
diff --git a/test/plugin/scenarios/agent-so11y-scenario/src/main/resources/log4j2.xml b/test/plugin/scenarios/agent-so11y-scenario/src/main/resources/log4j2.xml
new file mode 100644
index 0000000000..9849ed5a8a
--- /dev/null
+++ b/test/plugin/scenarios/agent-so11y-scenario/src/main/resources/log4j2.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  ~
+  -->
+<Configuration status="WARN">
+    <Appenders>
+        <Console name="Console" target="SYSTEM_ERR">
+            <PatternLayout charset="UTF-8" pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
+        </Console>
+    </Appenders>
+    <Loggers>
+        <Root level="WARN">
+            <AppenderRef ref="Console"/>
+        </Root>
+    </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/test/plugin/scenarios/agent-so11y-scenario/support-version.list b/test/plugin/scenarios/agent-so11y-scenario/support-version.list
new file mode 100644
index 0000000000..293331ad63
--- /dev/null
+++ b/test/plugin/scenarios/agent-so11y-scenario/support-version.list
@@ -0,0 +1,17 @@
+# 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.
+
+1.0.0
diff --git a/test/plugin/scenarios/apm-toolkit-trace-scenario/config/expectedData.yaml b/test/plugin/scenarios/apm-toolkit-trace-scenario/config/expectedData.yaml
index ab105a82ab..8c6b47877a 100644
--- a/test/plugin/scenarios/apm-toolkit-trace-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/apm-toolkit-trace-scenario/config/expectedData.yaml
@@ -492,7 +492,7 @@ segmentItems:
       skipAnalysis: 'true'
 meterItems:
 - serviceName: apm-toolkit-trace-scenario
-  meterSize: 8
+  meterSize: ge 8
   meters:
     - meterId:
         name: test_counter
diff --git a/test/plugin/scenarios/c3p0-0.9.0.x-0.9.1.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/c3p0-0.9.0.x-0.9.1.x-scenario/config/expectedData.yaml
index 545afa54ef..631a5bb4c3 100755
--- a/test/plugin/scenarios/c3p0-0.9.0.x-0.9.1.x-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/c3p0-0.9.0.x-0.9.1.x-scenario/config/expectedData.yaml
@@ -212,7 +212,7 @@ segmentItems:
         - {key: http.status_code, value: '200'}
 meterItems:
 - serviceName: c3p0-0.9.0.x-0.9.1.x-scenario
-  meterSize: 12
+  meterSize: ge 12
   meters:
   - meterId:
       name: datasource
diff --git a/test/plugin/scenarios/c3p0-0.9.2.x-0.10.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/c3p0-0.9.2.x-0.10.x-scenario/config/expectedData.yaml
index 68f931fa29..35d6453291 100755
--- a/test/plugin/scenarios/c3p0-0.9.2.x-0.10.x-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/c3p0-0.9.2.x-0.10.x-scenario/config/expectedData.yaml
@@ -212,7 +212,7 @@ segmentItems:
         - {key: http.status_code, value: '200'}
 meterItems:
 - serviceName: c3p0-0.9.2.x-0.10.x-scenario
-  meterSize: 12
+  meterSize: ge 12
   meters:
   - meterId:
       name: datasource
diff --git a/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml
index 7e21e55dd6..4e3cb7c03a 100755
--- a/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml
@@ -224,7 +224,7 @@ segmentItems:
         - {key: http.status_code, value: '200'}
 meterItems:
 - serviceName: dbcp-2.x-scenario
-  meterSize: 12
+  meterSize: ge 12
   meters:
   - meterId:
       name: datasource
diff --git a/test/plugin/scenarios/druid-1.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/druid-1.x-scenario/config/expectedData.yaml
index ca4a349b5b..fb32950056 100644
--- a/test/plugin/scenarios/druid-1.x-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/druid-1.x-scenario/config/expectedData.yaml
@@ -206,7 +206,7 @@ segmentItems:
       - {key: http.status_code, value: '200'}
 meterItems:
 - serviceName: druid-1.x-scenario
-  meterSize: 13
+  meterSize: ge 13
   meters:
   - meterId:
       name: datasource
diff --git a/test/plugin/scenarios/grizzly-2.3.x-4.x-workthreadpool-scenario/config/expectedData.yaml b/test/plugin/scenarios/grizzly-2.3.x-4.x-workthreadpool-scenario/config/expectedData.yaml
index da0f47c6ab..a635342f8b 100644
--- a/test/plugin/scenarios/grizzly-2.3.x-4.x-workthreadpool-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/grizzly-2.3.x-4.x-workthreadpool-scenario/config/expectedData.yaml
@@ -15,7 +15,7 @@
 # limitations under the License.
 meterItems:
   - serviceName: grizzly-2.3.x-4.x-workthreadpool-scenario
-    meterSize: 4
+    meterSize: ge 4
     meters:
       - meterId:
           name: thread_pool
diff --git a/test/plugin/scenarios/h2-scenario/config/expectedData.yaml b/test/plugin/scenarios/h2-scenario/config/expectedData.yaml
index d06c487e8a..c1420faf08 100644
--- a/test/plugin/scenarios/h2-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/h2-scenario/config/expectedData.yaml
@@ -98,7 +98,7 @@ segmentItems:
       skipAnalysis: 'false'
 meterItems:
   - serviceName: h2-scenario
-    meterSize: 5
+    meterSize: ge 5
     meters:
       - meterId:
           name: thread_pool
diff --git a/test/plugin/scenarios/hikaricp-scenario/config/expectedData.yaml b/test/plugin/scenarios/hikaricp-scenario/config/expectedData.yaml
index 75106a2a57..fbecf97a0a 100644
--- a/test/plugin/scenarios/hikaricp-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/hikaricp-scenario/config/expectedData.yaml
@@ -206,7 +206,7 @@ segmentItems:
       - {key: http.status_code, value: '200'}
 meterItems:
 - serviceName: hikaricp-scenario
-  meterSize: 15
+  meterSize: ge 15
   meters:
   - meterId:
       name: datasource
diff --git a/test/plugin/scenarios/jetty-11.x-thread-pool-scenario/config/expectedData.yaml b/test/plugin/scenarios/jetty-11.x-thread-pool-scenario/config/expectedData.yaml
index d911caaa10..ff04156c69 100644
--- a/test/plugin/scenarios/jetty-11.x-thread-pool-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/jetty-11.x-thread-pool-scenario/config/expectedData.yaml
@@ -15,7 +15,7 @@
 # limitations under the License.
 meterItems:
   - serviceName: jetty-11.x-thread-pool-scenario
-    meterSize: 5
+    meterSize: ge 5
     meters:
       - meterId:
           name: thread_pool
diff --git a/test/plugin/scenarios/jetty-thread-pool-scenario/config/expectedData.yaml b/test/plugin/scenarios/jetty-thread-pool-scenario/config/expectedData.yaml
index 00b0074a84..276fa97406 100644
--- a/test/plugin/scenarios/jetty-thread-pool-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/jetty-thread-pool-scenario/config/expectedData.yaml
@@ -15,7 +15,7 @@
 # limitations under the License.
 meterItems:
   - serviceName: jetty-thread-pool-scenario
-    meterSize: 5
+    meterSize: ge 5
     meters:
       - meterId:
           name: thread_pool
diff --git a/test/plugin/scenarios/tomcat-thread-pool-scenario/config/expectedData.yaml b/test/plugin/scenarios/tomcat-thread-pool-scenario/config/expectedData.yaml
index 6a4cd68333..c4cc8f9ddd 100644
--- a/test/plugin/scenarios/tomcat-thread-pool-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/tomcat-thread-pool-scenario/config/expectedData.yaml
@@ -15,7 +15,7 @@
 # limitations under the License.
 meterItems:
   - serviceName: tomcat-thread-pool-scenario
-    meterSize: 5
+    meterSize: ge 5
     meters:
       - meterId:
           name: thread_pool
diff --git a/test/plugin/scenarios/undertow-worker-thread-pool-scenario/config/expectedData.yaml b/test/plugin/scenarios/undertow-worker-thread-pool-scenario/config/expectedData.yaml
index 32d7928752..424a39aee8 100644
--- a/test/plugin/scenarios/undertow-worker-thread-pool-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/undertow-worker-thread-pool-scenario/config/expectedData.yaml
@@ -15,7 +15,7 @@
 # limitations under the License.
 meterItems:
   - serviceName: undertow-worker-thread-pool-scenario
-    meterSize: 5
+    meterSize: ge 5
     meters:
       - meterId:
           name: thread_pool