背景
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