背景
skywaling 已经具备了通用组件的监控能力,但是对于业务系统应用是没有监控插件提供,需要自己实现插件。
本文监控springboot 程序的指定的方法
实现
被监控springboot 程序
package com.example.demo;
import java.util.Calendar;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@GetMapping("/hello")
public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
intercept("input");
return String.format("Hello %s!", name + " "+ Calendar.getInstance().getTimeInMillis());
}
public String intercept(String input) {
String replace = StringUtils.replace("oldString", "old","replaced");
System.out.println("intercept");
return "hello";
}
}
agent
agent define
定义了监控点
package com.skywalkingagent;
import static net.bytebuddy.matcher.ElementMatchers.named;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassEnhancePluginDefine;
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;
public class DemoInstrumentation extends ClassEnhancePluginDefine {
private static final String ENHANCE_CLASS = "com.example.demo.DemoApplication";
private static final String INTERCEPT_CLASS = "com.skywalkingagent.DemoInterceptor";
@Override
protected ClassMatch enhanceClass() {
System.out.println(this.getClass().getName() + "#enhanceClass");
return NameMatch.byName(ENHANCE_CLASS);
}
@Override
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[]{
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named("intercept");
}
@Override
public String getMethodsInterceptor() {
return INTERCEPT_CLASS;
}
@Override
public boolean isOverrideArgs() {
return false;
}
}
};
}
@Override
public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() {
return new StaticMethodsInterceptPoint[0];
}
}
agent interceptor
定义了在监控点的动作
package com.skywalkingagent;
import java.lang.reflect.Method;
import org.apache.skywalking.apm.agent.core.context.ContextManager;
import org.apache.skywalking.apm.agent.core.context.tag.StringTag;
import org.apache.skywalking.apm.agent.core.context.tag.Tags;
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
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.network.trace.component.ComponentsDefine;
public class DemoInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance enhancedInstance, Method method, Object[] objects,
Class<?>[] classes, MethodInterceptResult methodInterceptResult) throws Throwable {
System.out.println(this.getClass() + "#beforeMethod");
// 创建span(监控的开始),本质上是往ThreadLocal对象里面设值
AbstractSpan span = ContextManager.createLocalSpan("replace");
span.setComponent(ComponentsDefine.TOMCAT);
System.out.println("agent before method");
span.tag(new StringTag(1000, "params"), objects[0].toString());
// 指定该调用的layer,layer是个枚举
span.setLayer(SpanLayer.CACHE);
}
@Override
public Object afterMethod(EnhancedInstance enhancedInstance, Method method, Object[] objects,
Class<?>[] classes, Object o) throws Throwable {
System.out.println("afterMethod");
String retString = (String) o;
AbstractSpan span = ContextManager.activeSpan();
Tags.STATUS_CODE.set(span, "20000");
ContextManager.stopSpan();
return retString;
}
@Override
public void handleMethodException(EnhancedInstance enhancedInstance, Method method,
Object[] objects, Class<?>[] classes, Throwable throwable) {
}
}
resource/skywalking-plugin.def
demo-test-plugin=com.skywalkingagent.DemoInstrumentation
部署
编译的agent 工程jar 包放入到 plugins 目录下
启动程序
skywalking
${home}/bin/startup.sh
app
java -javaagent:agent/skywalking-agent.jar -jar demo/target/demo-0.0.1-SNAPSHOT.jar --server.port=9090
java -javaagent:/usr/local/skywalking/agent/skywalking-agent.jar -Dskywalking.agent.service_name=demo -Dskywalking.collector.backend_service=ip -jar xxx.jar