From 75364241659c28e64557a3edffd53b9a8ae46188 Mon Sep 17 00:00:00 2001 From: weixiang1862 <652048614@qq.com> Date: Sun, 15 Sep 2024 18:04:09 +0800 Subject: [PATCH] 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 + .../agent/core/context/ContextManager.java | 2 + .../context/ContextManagerExtendService.java | 6 + .../core/context/IgnoredTracerContext.java | 2 + .../agent/core/context/TracingContext.java | 8 +- .../AbstractClassEnhancePluginDefine.java | 17 ++ .../agent/core/plugin/PluginBootstrap.java | 1 + .../bootstrap/BootstrapInstrumentBoost.java | 49 +++-- .../template/ConstructorInterTemplate.java | 14 ++ .../template/InstanceMethodInterTemplate.java | 20 ++ ...ceMethodInterWithOverrideArgsTemplate.java | 20 ++ .../template/StaticMethodInterTemplate.java | 21 +++ ...icMethodInterWithOverrideArgsTemplate.java | 21 +++ .../v2/InstanceMethodInterV2Template.java | 19 ++ ...MethodInterV2WithOverrideArgsTemplate.java | 20 ++ .../v2/StaticMethodInterV2Template.java | 21 +++ ...MethodInterV2WithOverrideArgsTemplate.java | 21 +++ .../enhance/BootstrapInterRuntimeAssist.java | 14 ++ .../enhance/ClassEnhancePluginDefine.java | 10 +- .../interceptor/enhance/ConstructorInter.java | 13 +- .../interceptor/enhance/InstMethodsInter.java | 19 +- .../InstMethodsInterWithOverrideArgs.java | 18 +- .../enhance/StaticMethodsInter.java | 19 +- .../StaticMethodsInterWithOverrideArgs.java | 20 +- .../v2/ClassEnhancePluginDefineV2.java | 10 +- .../enhance/v2/InstMethodsInterV2.java | 19 +- .../InstMethodsInterV2WithOverrideArgs.java | 19 +- .../enhance/v2/StaticMethodsInterV2.java | 19 +- .../StaticMethodsInterV2WithOverrideArgs.java | 19 +- .../apm/agent/core/so11y/AgentSo11y.java | 153 +++++++++++++++ .../so11y/bootstrap/BootstrapPluginSo11y.java | 25 +++ .../bootstrap/BootstrapPluginSo11yBridge.java | 46 +++++ .../java-agent/Agent-self-observability.md | 16 ++ .../service-agent/java-agent/Plugin-test.md | 2 +- docs/menu.yml | 6 +- .../resources/compose-start-script.template | 6 +- .../resources/container-start-script.template | 5 + .../agent-so11y-scenario/bin/startup.sh | 21 +++ .../config/expectedData.yaml | 177 ++++++++++++++++++ .../agent-so11y-scenario/configuration.yml | 25 +++ .../scenarios/agent-so11y-scenario/pom.xml | 128 +++++++++++++ .../src/main/assembly/assembly.xml | 41 ++++ .../apm/testcase/h2/Application.java | 30 +++ .../h2/controller/CaseController.java | 76 ++++++++ .../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 +- .../config/expectedData.yaml | 2 +- .../config/expectedData.yaml | 2 +- .../config/expectedData.yaml | 2 +- .../h2-scenario/config/expectedData.yaml | 2 +- .../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(-) create mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/so11y/AgentSo11y.java create mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/so11y/bootstrap/BootstrapPluginSo11y.java create mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/so11y/bootstrap/BootstrapPluginSo11yBridge.java create mode 100644 docs/en/setup/service-agent/java-agent/Agent-self-observability.md create mode 100644 test/plugin/scenarios/agent-so11y-scenario/bin/startup.sh create mode 100644 test/plugin/scenarios/agent-so11y-scenario/config/expectedData.yaml create mode 100644 test/plugin/scenarios/agent-so11y-scenario/configuration.yml create mode 100644 test/plugin/scenarios/agent-so11y-scenario/pom.xml create mode 100644 test/plugin/scenarios/agent-so11y-scenario/src/main/assembly/assembly.xml create mode 100644 test/plugin/scenarios/agent-so11y-scenario/src/main/java/org/apache/skywalking/apm/testcase/h2/Application.java create mode 100644 test/plugin/scenarios/agent-so11y-scenario/src/main/java/org/apache/skywalking/apm/testcase/h2/controller/CaseController.java create mode 100644 test/plugin/scenarios/agent-so11y-scenario/src/main/java/org/apache/skywalking/apm/testcase/h2/controller/SQLExecutor.java create mode 100644 test/plugin/scenarios/agent-so11y-scenario/src/main/resources/application.yaml create mode 100644 test/plugin/scenarios/agent-so11y-scenario/src/main/resources/log4j2.xml create mode 100644 test/plugin/scenarios/agent-so11y-scenario/support-version.list 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.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 @@ private static AbstractTracerContext getOrCreate(String operationName, boolean f 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.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 AbstractTracerContext createTraceContext(String operationName, boolean fo * 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 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 IgnoredTracerContext represent a context should be ignored. So it just maintains the stack with an @@ -116,6 +117,7 @@ public AbstractSpan activeSpan() { 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.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 @@ private void finish() { } 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 @@ 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 boolean isBootstrapInstrumentation() { * @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 List loadPlugins() throws AgentPackageN 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 @@ private static boolean prepareJREInstrumentation(PluginFinder pluginFinder, 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 @@ private static boolean prepareJREInstrumentation(PluginFinder pluginFinder, 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 @@ private static boolean prepareJREInstrumentation(PluginFinder pluginFinder, 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 @@ private static boolean prepareJREInstrumentationV2(PluginFinder pluginFinder, 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 @@ private static boolean prepareJREInstrumentationV2(PluginFinder pluginFinder, 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 @@ private static boolean prepareJREInstrumentationV2(PluginFinder pluginFinder, * pre-defined in SkyWalking agent core. */ private static void generateDelegator(Map 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 @@ private static void generateDelegator(Map classesTypeMap, TypePo 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.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 @@ * 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 static void intercept(@This Object obj, @AllArguments Object[] allArgumen 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 @@ private static void prepare() { 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.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 @@ * 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 static Object intercept(@This Object obj, @AllArguments Object[] allArgum prepare(); + long interceptorTimeCost = 0L; + long startTimeOfMethodBeforeInter = System.nanoTime(); MethodInterceptResult result = new MethodInterceptResult(); try { if (INTERCEPTOR != null) { @@ -77,7 +87,9 @@ public static Object intercept(@This Object obj, @AllArguments Object[] allArgum 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 static Object intercept(@This Object obj, @AllArguments Object[] allArgum 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 static Object intercept(@This Object obj, @AllArguments Object[] allArgum 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 static Object intercept(@This Object obj, @AllArguments Object[] allArgum 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 @@ private static void prepare() { 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.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 @@ * 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 static Object intercept(@This Object obj, @AllArguments Object[] allArgum prepare(); + long interceptorTimeCost = 0L; + long startTimeOfMethodBeforeInter = System.nanoTime(); MethodInterceptResult result = new MethodInterceptResult(); try { if (INTERCEPTOR != null) { @@ -77,7 +87,9 @@ public static Object intercept(@This Object obj, @AllArguments Object[] allArgum 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 static Object intercept(@This Object obj, @AllArguments Object[] allArgum 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 static Object intercept(@This Object obj, @AllArguments Object[] allArgum 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 static Object intercept(@This Object obj, @AllArguments Object[] allArgum 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 @@ private static void prepare() { 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.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 @@ * 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 static Object intercept(@Origin Class clazz, @AllArguments Object[] al @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 static Object intercept(@Origin Class clazz, @AllArguments Object[] al } } 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 static Object intercept(@Origin Class clazz, @AllArguments Object[] al 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 @@ private static void prepare() { 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.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 @@ * 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 static Object intercept(@Origin Class clazz, @AllArguments Object[] al @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 static Object intercept(@Origin Class clazz, @AllArguments Object[] al } } 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 static Object intercept(@Origin Class clazz, @AllArguments Object[] al 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 @@ private static void prepare() { 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.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 static Object intercept(@This Object obj, @AllArguments Object[] allArgum prepare(); + long interceptorTimeCost = 0L; + long startTimeOfMethodBeforeInter = System.nanoTime(); MethodInvocationContext context = new MethodInvocationContext(); try { if (INTERCEPTOR != null) { @@ -70,7 +79,9 @@ public static Object intercept(@This Object obj, @AllArguments Object[] allArgum 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 static Object intercept(@This Object obj, @AllArguments Object[] allArgum 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 static Object intercept(@This Object obj, @AllArguments Object[] allArgum 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 static Object intercept(@This Object obj, @AllArguments Object[] allArgum 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 @@ private static void prepare() { 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.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 static Object intercept(@This Object obj, @AllArguments Object[] allArgum prepare(); + long interceptorTimeCost = 0L; + long startTimeOfMethodBeforeInter = System.nanoTime(); MethodInvocationContext context = new MethodInvocationContext(); try { if (INTERCEPTOR != null) { @@ -70,7 +80,9 @@ public static Object intercept(@This Object obj, @AllArguments Object[] allArgum 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 static Object intercept(@This Object obj, @AllArguments Object[] allArgum 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 static Object intercept(@This Object obj, @AllArguments Object[] allArgum 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 static Object intercept(@This Object obj, @AllArguments Object[] allArgum 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 @@ private static void prepare() { 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.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 static Object intercept(@Origin Class clazz, @AllArguments Object[] al @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 static Object intercept(@Origin Class clazz, @AllArguments Object[] al } } 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 static Object intercept(@Origin Class clazz, @AllArguments Object[] al 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 @@ private static void prepare() { 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.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 static Object intercept(@Origin Class clazz, @AllArguments Object[] al @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 static Object intercept(@Origin Class clazz, @AllArguments Object[] al } } 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 static Object intercept(@Origin Class clazz, @AllArguments Object[] al 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 @@ private static void prepare() { 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.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 @@ 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 static IBootstrapLog getLogger(ClassLoader defaultAgentClassLoader, Strin } } + 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 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 @@ protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription } 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 @@ protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription 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 @@ protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription } 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 @@ protected DynamicType.Builder enhanceClass(TypeDescription typeDescription, D 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 @@ protected DynamicType.Builder enhanceClass(TypeDescription typeDescription, D } 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.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 @@ 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 ConstructorInter(String constructorInterceptorClassName, ClassLoader clas */ @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.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 @@ 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 Object intercept(@This Object obj, @AllArguments Object[] allArguments, @ @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 Object intercept(@This Object obj, @AllArguments Object[] allArguments, @ 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.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 @@ 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 Object intercept(@This Object obj, @AllArguments Object[] allArguments, @ @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 Object intercept(@This Object obj, @AllArguments Object[] allArguments, @ 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 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 @@ 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 Object intercept(@Origin Class clazz, @AllArguments Object[] allArgume 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 Object intercept(@Origin Class clazz, @AllArguments Object[] allArgume 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 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 @@ 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 Object intercept(@Origin Class clazz, @AllArguments Object[] allArgume 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 Object intercept(@Origin Class clazz, @AllArguments Object[] allArgume 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 @@ protected DynamicType.Builder enhanceClass(TypeDescription typeDescription, 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 @@ protected DynamicType.Builder enhanceClass(TypeDescription typeDescription, 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 @@ protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription } 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 @@ protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription 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 @@ protected DynamicType.Builder enhanceInstance(TypeDescription typeDescription } 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.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 @@ 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 Object intercept(@This Object obj, @AllArguments Object[] allArguments, @ @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 Object intercept(@This Object obj, @AllArguments Object[] allArguments, @ 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.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 @@ 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 Object intercept(@This Object obj, @AllArguments Object[] allArguments, @ @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 Object intercept(@This Object obj, @AllArguments Object[] allArguments, @ 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 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 @@ 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 Object intercept(@Origin Class clazz, @AllArguments Object[] allArgume 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 Object intercept(@Origin Class clazz, @AllArguments Object[] allArgume 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.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 @@ 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 Object intercept(@Origin Class clazz, @AllArguments Object[] allArgume 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 Object intercept(@Origin Class clazz, @AllArguments Object[] allArgume 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 ERROR_COUNTER_CACHE = new ConcurrentHashMap<>(); + + // Steps of interceptor time cost histogram + private static final List 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 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 environments??> + <#list environments as env> + --env ${env} \ + + -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 @@ + + + + + org.apache.skywalking.apm.testcase + agent-so11y-scenario + 1.0.0 + jar + + 4.0.0 + + + UTF-8 + 1.8 + 3.8.1 + 1.0.0 + 1.4.177 + 2.5.6 + 1.18.20 + + + skywalking-agent-so11y-scenario + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + com.h2database + h2 + ${h2.version} + + + + + agent-so11y-scenario + + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + + repackage + + + + + + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${compiler.version} + ${compiler.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-assembly-plugin + + + assemble + package + + single + + + + src/main/assembly/assembly.xml + + ./target/ + + + + + + + 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 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ${project.build.directory}/agent-so11y-scenario.jar + ./libs + 0775 + + + 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 @@ + + + + + + + + + + + + + + \ 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