在上一章,我们通过了@Trace, @Tags, @Tag注解,对我们的方法进行了链路追踪. 但是它有这样三点不好:
而探针则在这三个问题上,得到了解决.我们接下来的demo,将会以Base64.encodeToString()
进行展示.
插件开发基本绕不过去的类,具体解释暂时懒得打了,建议直接看书的第十章,闲了后补
*Instrumentation 定义拦截的方式:
匹配类名 enhanceClass()
匹配构造方法 getConstructorsInterceptPoints()
匹配方法 getInstanceMethodsInterceptPoints()
/** * #3,告诉skywalking拦截哪些方法,并指定拦截器 * ClassEnhancePluginDefine 父类 * ClassInstanceMethodsEnhancePluginDefine 实例方法 * ClassStaticMethodsEnhancePluginDefine 静态方法 */
public class Base64Instrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String ENHANCE_CLASS = "org.apache.commons.codec.binary.Base64";
private static final String INTERCEPT_CLASS = "org.dfg.demo.sk.plugin.foo.Base64EncodeInterceptor";
@Override
protected ClassMatch enhanceClass() {
return NameMatch.byName(ENHANCE_CLASS);
}
/** * 拦截构造器 * * @return */
@Override
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return null;
}
/** * 拦截方法 * InstanceMethodsAroundInterceptor 实例方法 * InstanceConstructorInterceptor 构造方法 * StaticMethodsAroundInterceptor 静态方法 * * @return */
@Override
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
//拦截实例方法
return new InstanceMethodsInterceptPoint[]{
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
//拦截方法,支持多种匹配规则
return named("encodeToString")
// .and(takesArguments(1))
// .and(takesArguments(byte[].class))
;
}
@Override
public String getMethodsInterceptor() {
return INTERCEPT_CLASS;
}
@Override
public boolean isOverrideArgs() {
return false;
}
}
};
}
}
*Interceptor 定义拦截器实际方法
方法执行前 beforeMethod()
方法执行后 afterMethod()
方法发生异常 handleMethodException()
/** * #4,skywalking拦截到指定方法后回调 * 在这里面获取调用情况如方法、参数等,并记录span */
public class Base64EncodeInterceptor implements InstanceMethodsAroundInterceptor {
public static final OfficialComponent BASE64 = new OfficialComponent(301, "BASE64");
@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
//创建span
AbstractSpan span = ContextManager.createLocalSpan("base64.encode");
//设置组件类型
span.setComponent(BASE64);
//获取参数
byte[] param = (byte[]) allArguments[0];
//记录span tag
new StringTag("source").set(span, Arrays.toString(param));
//记录span
SpanLayer.asHttp(span);
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) throws Throwable {
if (ret != null) {
AbstractSpan span = ContextManager.activeSpan();
//span.errorOccurred();
new StringTag("result").set(span, String.valueOf(ret));
}
//结束span
ContextManager.stopSpan();
return ret;
}
@Override
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
AbstractSpan abstractSpan = ContextManager.activeSpan();
abstractSpan.log(t);
}
}
工程仍位于同一个demo中,skywalking-plugin-example
foo-plugin=org.dfg.demo.sk.plugin.foo.define.Base64Instrumentation
可以替换bytebuddy包路径,在pom.xml的节点下,非必须,只是demo中将打出来的jar包会传输到agent包中的plugin目录中
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
中 </goals>
<configuration>
<shadedArtifactAttached>false</shadedArtifactAttached>
<createDependencyReducedPom>false</createDependencyReducedPom>
<createSourcesJar>false</createSourcesJar>
<shadeSourcesContent>true</shadeSourcesContent>
<relocations>
<relocation>
<pattern>${shade.net.bytebuddy.source}</pattern>
<shadedPattern>${shade.net.bytebuddy.target}</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
如果替换了bytebuddy包路径,则无需手动复制.替换结果:
wanglh@dark:~/IdeaProjects/skywalking-plugin-example/apache-skywalking-apm-bin-es7/agent/plugins$ ls -al
总用量 2616
drwxr-xr-x 2 wanglh wanglh 12288 2月 5 20:58 .
drwxr-xr-x 9 wanglh wanglh 4096 2月 4 21:51 ..
-rw-r--r-- 1 wanglh wanglh 21274 2月 4 17:11 apm-activemq-5.x-plugin-8.3.0.jar
-rw-r--r-- 1 wanglh wanglh 13197 2月 4 17:11 apm-dubbo-plugin-8.3.0.jar
-rw-r--r-- 1 wanglh wanglh 28217 2月 4 17:11 apm-ehcache-2.x-plugin-8.3.0.jar
-rw-r--r-- 1 wanglh wanglh 6999 2月 5 20:58 skywalking-plugin-foo-1.0-SNAPSHOT.jar
wanglh@dark:~/IdeaProjects/skywalking-plugin-example/apache-skywalking-apm-bin-es7/agent/plugins$ ls -al *foo*
-rw-r--r-- 1 wanglh wanglh 6999 2月 5 20:58 skywalking-plugin-foo-1.0-SNAPSHOT.jar
wanglh@dark:~/IdeaProjects/skywalking-plugin-example/apache-skywalking-apm-bin-es7/agent/plugins$
可以观察到foo插件包的时间戳是最新的
与上一章相同的启动方式
方式不变,仍为:
curl http://localhost:8081/foo?p=a
已经可以看到新增的encode方法的链路
// 入口
//记录span tag
new StringTag("source").set(span, Arrays.toString(param));
//记录span
SpanLayer.asHttp(span);
// 出口
if (ret != null) {
AbstractSpan span = ContextManager.activeSpan();
//span.errorOccurred();
new StringTag("result").set(span, String.valueOf(ret));
}
//结束span
ContextManager.stopSpan();
以上是demo工程中,对该Span添加的Tag.
实际图也可以观察到生效了:
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/a17816876003/article/details/113703991
内容来源于网络,如有侵权,请联系作者删除!