Guide to Developing SkyWalking Java Agent with Byte Buddy and Plugin Implementation
This tutorial explains how to use Byte Buddy to build a JavaAgent for SkyWalking, debug and continuously integrate the agent, and develop custom SkyWalking plugins such as the kob scheduling framework, providing step‑by‑step code examples and configuration details for observability in Java backend services.
SkyWalking's Java probe is implemented with JavaAgent using Byte Buddy (alongside Javassist) and also includes .Net core and Node.js automatic probes as well as Istio service‑mesh monitoring; overall, SkyWalking is a multi‑language, multi‑scenario observability analysis platform designed for microservices, cloud‑native and container‑based architectures.
This article, based on SkyWalking 5.0.0‑RC2 and Byte Buddy 1.7.9, guides readers through using the SkyWalking Java probe and making the platform easily extensible for internal projects.
Byte Buddy implementation of JavaAgent project
Iterative methodology for JavaAgent projects
Debugging SkyWalking agent projects
SkyWalking plugin development practice
Resources for SkyWalking and Byte Buddy are provided at the end of the article.
1. Byte Buddy Implementation
If you are unfamiliar with JavaAgent, refer to the "JavaAgent Principles and Practice" article for a quick introduction.
Below is the Byte Buddy JavaAgent code that intercepts Spring MVC's DispatcherServlet.doDispatch method:
public class AgentMain {
public static void premain(String agentOps, Instrumentation instrumentation) {
new AgentBuilder.Default()
.type(ElementMatchers.named("org.springframework.web.servlet.DispatcherServlet"))
.transform((builder, type, classLoader, module) ->
builder.method(ElementMatchers.named("doDispatch"))
.intercept(MethodDelegation.to(DoDispatchInterceptor.class)))
.installOn(instrumentation);
}
}DispatcherServlet doDispatch interceptor implementation (similar to AOP):
public class DoDispatchInterceptor {
@RuntimeType
public static Object intercept(@Argument(0) HttpServletRequest request, @SuperCall Callable
callable) {
final StringBuilder in = new StringBuilder();
if (request.getParameterMap() != null && request.getParameterMap().size() > 0) {
request.getParameterMap().keySet().forEach(key ->
in.append("key=" + key + "_value=" + request.getParameter(key) + ","));
}
long agentStart = System.currentTimeMillis();
try {
return callable.call();
} catch (Exception e) {
System.out.println("Exception :" + e.getMessage());
return null;
} finally {
System.out.println("path:" + request.getRequestURI() + " 入参:" + in + " 耗时:" + (System.currentTimeMillis() - agentStart));
}
}
}Manifest (resources/META-INF/MANIFEST.MF):
Manifest-Version: 1.0
Premain-Class: com.z.test.agent.AgentMain
Can-Redefine-Classes: trueRelevant pom.xml dependencies and plugins:
dependencies
+net.bytebuddy.byte-buddy
+javax.servlet.javax.servlet-api *scope=provided
plugins
+maven-jar-plugin *manifestFile=src/main/resources/META-INF/MANIFEST.MF
+maven-shade-plugin *include:net.bytebuddy:byte-buddy:jar:
+maven-compiler-pluginSummary: With just a few dozen lines of code, you can record Spring MVC request paths, parameters, and execution time using Byte Buddy.
2. Continuous Iteration of JavaAgent
This section explains how to debug a JavaAgent and adopt continuous integration practices.
Project structure example (image omitted) and a minimal SpringBootWeb application:
@SpringBootApplication(scanBasePackages = {"com"})
public class TestBootWeb {
public static void main(String[] args) {
SpringApplication.run(TestBootWeb.class, args);
}
@RestController
public class ApiController {
@PostMapping("/ping")
public String ping(HttpServletRequest request) {
return "pong";
}
}
}Key steps for iterative development and CI:
1. Add VM option: -javaagent:${HOME}/Code/github/z_my_test/test-agent/target/test-agent-1.0-SNAPSHOT.jar=args
2. Before launch – add build step:
Working directory: ${HOME}/Code/github/incubator-skywalking
Command line: -T 1C -pl test-agent -am clean package -Denforcer.skip=true -Dmaven.test.skip=true -Dmaven.compile.fork=trueSummary: The described method enables fast iteration and integration of JavaAgent projects, and the demo web service can be enhanced by the agent.
3. SkyWalking Debug
To debug a JavaAgent, keep the agent code and the target application in the same workspace. Import the skywalking‑agent source as a new module in the IDE.
IDE configuration screenshots are omitted. Optimized compilation time can be reduced to about 30 seconds by using the following VM options and build commands (avoid the pre‑built dist jar):
1. VM options: -javaagent:-javaagent:${HOME}/Code/github/incubator-skywalking/skywalking-agent/skywalking-agent.jar
2. Before launch – add build step:
Working directory: ${HOME}/Code/github/incubator-skywalking
Command line: -T 1C -pl apm-sniffer/apm-sdk-plugin -amd clean package -Denforcer.skip=true -Dmaven.test.skip=true -Dmaven.compile.fork=true
3. Optionally comment out maven-checkstyle-plugin in the root pom to speed up compilation.4. Writing a SkyWalking Plugin for kob
The kob framework is a distributed job‑scheduling component used at the company. By writing a SkyWalking plugin for kob, you can collect real‑time execution traces of scheduled tasks.
Add a new module kob-plugin to apm-sdk-plugin pom:
<artifactId>apm-sdk-plugin</artifactId>
<modules>
<module>kob-plugin</module>
...
</modules>Define the plugin in resources/skywalking-plugin.def :
kob=org.apache.skywalking.apm.plugin.kob.KobInstrumentationInstrumentation class extending ClassInstanceMethodsEnhancePluginDefine :
public class KobInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String ENHANCE_CLASS = "com.ke.kob.client.spring.core.TaskDispatcher";
private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.kob.KobInterceptor";
@Override
protected ClassMatch enhanceClass() {
return NameMatch.byName(ENHANCE_CLASS);
}
@Override
protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return null;
}
@Override
protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher
getMethodsMatcher() {
return named("dispatcher1");
}
@Override
public String getMethodsInterceptor() {
return INTERCEPT_CLASS;
}
@Override
public boolean isOverrideArgs() {
return false;
}
}
};
}
}Interceptor implementing InstanceMethodsAroundInterceptor to create and stop spans:
public class KobInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class
[] argumentsTypes, MethodInterceptResult result) throws Throwable {
ContextCarrier contextCarrier = new ContextCarrier();
TaskContext context = (TaskContext) allArguments[0];
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
next.setHeadValue(JSON.toJSONString(context.getUserParam()));
}
AbstractSpan span = ContextManager.createEntrySpan("client:" + allArguments[1] + ",task:" + context.getTaskKey(), contextCarrier);
span.setComponent(ComponentsDefine.TRANSPORT_CLIENT);
SpanLayer.asRPCFramework(span);
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class
[] argumentsTypes, Object ret) throws Throwable {
ContextManager.stopSpan();
return ret;
}
@Override
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class
[] argumentsTypes, Throwable t) {
// optional exception handling
}
}Result: The operation name becomes "task execution node + method", enabling detailed tracing and alerting for the kob component.
5. Reference Links
1) Apache SkyWalking – https://github.com/apache/incubator-skywalking
2) Byte Buddy – https://github.com/raphw/byte-buddy
Additional recommended readings: "JavaAgent Principles and Practice" and "Introduction to the kob Distributed Scheduling Framework" (links omitted).
Beike Product & Technology
As Beike's official product and technology account, we are committed to building a platform for sharing Beike's product and technology insights, targeting internet/O2O developers and product professionals. We share high-quality original articles, tech salon events, and recruitment information weekly. Welcome to follow us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.