Skip to content

Commit

Permalink
Add agent self-observability. (#716)
Browse files Browse the repository at this point in the history
  • Loading branch information
weixiang1862 authored Sep 15, 2024
1 parent aa24777 commit 7536424
Show file tree
Hide file tree
Showing 64 changed files with 1,340 additions and 63 deletions.
4 changes: 2 additions & 2 deletions .github/actions/build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions .github/actions/run/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/plugins-test.0.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ jobs:
matrix:
case:
- activemq-scenario
- agent-so11y-scenario
- apm-toolkit-trace-scenario
- apm-toolkit-tracer-scenario
- armeria-0.96minus-scenario
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish-docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <code>IgnoredTracerContext</code> represent a context should be ignored. So it just maintains the stack with an
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public List<AbstractClassEnhancePluginDefine> 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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -162,31 +165,39 @@ 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()
);
}
}
}

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()
);
}
}

if (Objects.nonNull(define.getStaticMethodsInterceptPoints())) {
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()
);
}
}
}
Expand All @@ -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()
);
}
}
Expand All @@ -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()
);
}
}
Expand All @@ -245,14 +256,16 @@ private static boolean prepareJREInstrumentationV2(PluginFinder pluginFinder,
* pre-defined in SkyWalking agent core.
*/
private static void generateDelegator(Map<String, byte[]> classesTypeMap, TypePool typePool,
String templateClassName, String methodsInterceptor) {
String pluginName, String templateClassName, String methodsInterceptor) {
String internalInterceptorName = internalDelegate(methodsInterceptor);
try {
TypeDescription templateTypeDescription = typePool.describe(templateClassName).resolve();

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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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---------
Expand All @@ -37,13 +38,20 @@
* 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.
*/
private static String TARGET_INTERCEPTOR;

private static InstanceConstructorInterceptor INTERCEPTOR;
private static IBootstrapLog LOGGER;
private static BootstrapPluginSo11y PLUGIN_SO11Y;

/**
* Intercept the target constructor.
Expand All @@ -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();

Expand All @@ -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);
}

/**
Expand All @@ -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 {
Expand Down
Loading

0 comments on commit 7536424

Please sign in to comment.