当现有skywalking无法满足现有统计需求时,需要自定义统计维度,或者对自研中间件进行监控,可以通过添加skywalking的插件来实现无侵入的添加功能
执行步骤:
- 创建一个自定义插件项目
- pom文件继承apm-sdk-plugin
- 继承ClassInstanceMethodsEnhancePluginDefine,用于设置需要拦截的类
- 实现InstanceMethodsAroundInterceptor,用于对拦截的类进行额外功能扩展
- 添加skywalking-plugin.def,指定插件拦截类路径,skywalking启动时会加载该类
- maven打包,并把打好的包放在agent\plugins目录下面
- 重启服务
(1)maven依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<parent> <groupId>org.apache.skywalking</groupId> <artifactId>apm-sdk-plugin</artifactId> <version>8.5.0</version> </parent>
<groupId>cn.aacopy.skywalking.plugin.plus</groupId> <artifactId>skywalking-plugin-plus</artifactId>
<properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <checkstyle.skip>true</checkstyle.skip> </properties>
</project>
|
(2)拦截类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| package cn.aacopy.skywalking.plugin.plus;
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.enhance.ClassInstanceMethodsEnhancePluginDefine; import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; import org.apache.skywalking.apm.agent.core.plugin.match.PrefixMatch;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
public class CountTestHandlerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
public static final String METHOD_INTERCEPTOR_CLASS = "cn.aacopy.skywalking.plugin.plus.CountTestHandlerMethodInterceptor"; @Override protected ClassMatch enhanceClass() { return PrefixMatch.nameStartsWith("cn.aacopy.test.simpleboot"); }
@Override public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { return new ConstructorInterceptPoint[0]; }
@Override public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { return new InstanceMethodsInterceptPoint[] { new InstanceMethodsInterceptPoint() { @Override public ElementMatcher<MethodDescription> getMethodsMatcher() { return nameStartsWith("fun"); }
@Override public String getMethodsInterceptor() { return METHOD_INTERCEPTOR_CLASS; }
@Override public boolean isOverrideArgs() { return false; } } }; } }
|
(3)拦截处理类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| package cn.aacopy.skywalking.plugin.plus;
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;
import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map;
public class CountTestHandlerMethodInterceptor implements InstanceMethodsAroundInterceptor {
private static Map<String, Long> count = new HashMap<>(); @Override public void beforeMethod(EnhancedInstance enhancedInstance, Method method, Object[] objects, Class<?>[] classes, MethodInterceptResult methodInterceptResult) throws Throwable { if(count.containsKey(method.getName())) { count.put(method.getName(), count.get(method.getName()) + 1); } else { count.put(method.getName(), 1L); } AbstractSpan span = ContextManager.createLocalSpan("CountTest:"+method.getName()); span.setComponent(ComponentsDefine.TOMCAT); span.tag(new StringTag(1000, "params"), objects[0].toString()); span.setLayer(SpanLayer.CACHE); }
@Override public Object afterMethod(EnhancedInstance enhancedInstance, Method method, Object[] objects, Class<?>[] classes, Object o) throws Throwable { System.out.println(method.getName() + "方法调用次数===========" + count.get(method.getName())); AbstractSpan span = ContextManager.activeSpan(); Tags.STATUS_CODE.set(span, String.valueOf(count.get(method.getName()))); ContextManager.stopSpan(); return o; }
@Override public void handleMethodException(EnhancedInstance enhancedInstance, Method method, Object[] objects, Class<?>[] classes, Throwable throwable) { ContextManager.activeSpan().log(throwable); } }
|
(4)skywalking-plugin.def
1
| count-test-plugin=cn.aacopy.skywalking.plugin.plus.CountTestHandlerInstrumentation
|
测试
随便写一个springboot工程,启动加入skywalkingagent包,访问接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| package cn.aacopy.test.simpleboot.controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;
@RestController public class TestController {
@GetMapping("/test1") public String test1Haha() { System.out.println("hahaha"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } return "hahah"; }
@GetMapping("/test2") public String test2Haha(@RequestParam String name) { System.out.println("hahaha2sssssssss"); try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } return "hihei" + name; }
@GetMapping("/test3") public String test3Haha1() { System.out.println("hihei123123213"); try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } return "hihei1232312322"; } }
|
访问效果:后台
skywalking控制台