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
#noparse>
diff --git a/test/plugin/runner-helper/src/main/resources/container-start-script.template b/test/plugin/runner-helper/src/main/resources/container-start-script.template
index 108fb0bf20..0f072afdf1 100644
--- a/test/plugin/runner-helper/src/main/resources/container-start-script.template
+++ b/test/plugin/runner-helper/src/main/resources/container-start-script.template
@@ -33,6 +33,11 @@ docker run -d \
<#if debug_mode??>
--env DEBUG_MODE=${debug_mode} \
#if>
+ <#if environments??>
+ <#list environments as env>
+ --env ${env} \
+ #list>
+ #if>
-v ${agent_home}:/usr/local/skywalking/scenario/agent \
-v ${scenario_home}:/usr/local/skywalking/scenario \
-v ${jacoco_home}:/jacoco \
diff --git a/test/plugin/scenarios/agent-so11y-scenario/bin/startup.sh b/test/plugin/scenarios/agent-so11y-scenario/bin/startup.sh
new file mode 100644
index 0000000000..e4140338be
--- /dev/null
+++ b/test/plugin/scenarios/agent-so11y-scenario/bin/startup.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+home="$(cd "$(dirname $0)"; pwd)"
+
+java -jar ${agent_opts} ${home}/../libs/agent-so11y-scenario.jar &
\ No newline at end of file
diff --git a/test/plugin/scenarios/agent-so11y-scenario/config/expectedData.yaml b/test/plugin/scenarios/agent-so11y-scenario/config/expectedData.yaml
new file mode 100644
index 0000000000..8e044e041f
--- /dev/null
+++ b/test/plugin/scenarios/agent-so11y-scenario/config/expectedData.yaml
@@ -0,0 +1,177 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+segmentItems:
+- serviceName: agent-so11y-scenario
+ segmentSize: gt 1
+ segments:
+ - segmentId: not null
+ spans:
+ - operationName: H2/JDBC/PreparedStatement/execute
+ parentSpanId: 0
+ spanId: 1
+ spanLayer: Database
+ startTime: gt 0
+ endTime: gt 0
+ componentId: 32
+ isError: false
+ spanType: Exit
+ peer: localhost:-1
+ tags:
+ - {key: db.type, value: H2}
+ - {key: db.instance, value: test}
+ - key: db.statement
+ value: "CREATE TABLE test_007(\nid VARCHAR(1) PRIMARY KEY, \nvalue VARCHAR(1)\
+ \ NOT NULL)"
+ skipAnalysis: 'false'
+ - operationName: H2/JDBC/CallableStatement/execute
+ parentSpanId: 0
+ spanId: 2
+ spanLayer: Database
+ startTime: gt 0
+ endTime: gt 0
+ componentId: 32
+ isError: false
+ spanType: Exit
+ peer: localhost:-1
+ tags:
+ - {key: db.type, value: H2}
+ - {key: db.instance, value: test}
+ - {key: db.statement, value: 'INSERT INTO test_007(id, value) VALUES(?,?)'}
+ skipAnalysis: 'false'
+ - operationName: H2/JDBC/Statement/execute
+ parentSpanId: 0
+ spanId: 3
+ spanLayer: Database
+ startTime: gt 0
+ endTime: gt 0
+ componentId: 32
+ isError: false
+ spanType: Exit
+ peer: localhost:-1
+ tags:
+ - {key: db.type, value: H2}
+ - {key: db.instance, value: test}
+ - {key: db.statement, value: DROP table test_007}
+ skipAnalysis: 'false'
+ - operationName: /agent-so11y-scenario/case/ignore.html
+ parentSpanId: 0
+ spanId: 4
+ spanLayer: Http
+ startTime: gt 0
+ endTime: gt 0
+ componentId: 66
+ isError: false
+ spanType: Exit
+ peer: localhost:8080
+ tags:
+ - {key: http.method, value: GET}
+ - {key: url, value: 'http://localhost:8080/agent-so11y-scenario/case/ignore.html'}
+ - {key: http.status_code, value: '200'}
+ skipAnalysis: 'false'
+ - operationName: /agent-so11y-scenario/case/propagated
+ parentSpanId: 0
+ spanId: 5
+ spanLayer: Http
+ startTime: gt 0
+ endTime: gt 0
+ componentId: 66
+ isError: false
+ spanType: Exit
+ peer: localhost:8080
+ tags:
+ - {key: http.method, value: GET}
+ - {key: url, value: 'http://localhost:8080/agent-so11y-scenario/case/propagated'}
+ - {key: http.status_code, value: '200'}
+ skipAnalysis: 'false'
+ - operationName: GET:/agent-so11y-scenario/case/agent-so11y-scenario
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: Http
+ startTime: gt 0
+ endTime: gt 0
+ componentId: 1
+ isError: false
+ spanType: Entry
+ peer: ''
+ tags:
+ - {key: url, value: 'http://localhost:8080/agent-so11y-scenario/case/agent-so11y-scenario'}
+ - {key: http.method, value: GET}
+ - {key: http.status_code, value: '200'}
+ skipAnalysis: 'false'
+ - segmentId: not null
+ spans:
+ - operationName: GET:/agent-so11y-scenario/case/propagated
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: Http
+ startTime: gt 0
+ endTime: gt 0
+ componentId: 1
+ isError: false
+ spanType: Entry
+ peer: ''
+ tags:
+ - {key: url, value: 'http://localhost:8080/agent-so11y-scenario/case/propagated'}
+ - {key: http.method, value: GET}
+ - {key: http.status_code, value: '200'}
+ skipAnalysis: 'false'
+ refs:
+ - {parentEndpoint: 'GET:/agent-so11y-scenario/case/agent-so11y-scenario', networkAddress: 'localhost:8080',
+ refType: CrossProcess, parentSpanId: 5, parentTraceSegmentId: not null,
+ parentServiceInstance: not null, parentService: agent-so11y-scenario,
+ traceId: not null}
+
+meterItems:
+- serviceName: agent-so11y-scenario
+ meterSize: ge 9
+ meters:
+ - meterId:
+ name: created_tracing_context_counter
+ tags:
+ - {name: created_by, value: propagated}
+ singleValue: 1.0
+ - meterId:
+ name: created_tracing_context_counter
+ tags:
+ - {name: created_by, value: sampler}
+ singleValue: 1.0
+ - meterId:
+ name: finished_tracing_context_counter
+ tags: []
+ singleValue: 2.0
+ - meterId:
+ name: created_ignored_context_counter
+ tags:
+ - {name: created_by, value: propagated}
+ singleValue: 1.0
+ - meterId:
+ name: created_ignored_context_counter
+ tags:
+ - {name: created_by, value: sampler}
+ singleValue: 1.0
+ - meterId:
+ name: finished_ignored_context_counter
+ tags: []
+ singleValue: 2.0
+ - meterId:
+ name: tracing_context_performance
+ tags: []
+ histogramBuckets: [0.0, 1000.0, 10000.0, 50000.0, 100000.0, 300000.0, 500000.0, 1000000.0, 5000000.0, 1.0E7, 2.0E7, 5.0E7, 1.0E8]
+ - meterId:
+ name: possible_leaked_context_counter
+ tags:
+ - {name: source, value: tracing}
+ singleValue: 1.0
diff --git a/test/plugin/scenarios/agent-so11y-scenario/configuration.yml b/test/plugin/scenarios/agent-so11y-scenario/configuration.yml
new file mode 100644
index 0000000000..7d9a31395c
--- /dev/null
+++ b/test/plugin/scenarios/agent-so11y-scenario/configuration.yml
@@ -0,0 +1,25 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+type: jvm
+entryService: http://localhost:8080/agent-so11y-scenario/case/agent-so11y-scenario
+healthCheck: http://localhost:8080/agent-so11y-scenario/case/healthCheck.html
+runningMode: with_bootstrap
+withPlugins: apm-jdk-http-plugin-*.jar
+startScript: ./bin/startup.sh
+environment:
+ - SW_AGENT_SPAN_LIMIT=6
+ - SW_METER_REPORT_INTERVAL=1
diff --git a/test/plugin/scenarios/agent-so11y-scenario/pom.xml b/test/plugin/scenarios/agent-so11y-scenario/pom.xml
new file mode 100644
index 0000000000..39095c57ad
--- /dev/null
+++ b/test/plugin/scenarios/agent-so11y-scenario/pom.xml
@@ -0,0 +1,128 @@
+
+
+
+
+ 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}
+ ${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
+
+
+
+
+
+
+ ./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