pinpoint 插件开发之一:牛刀小试,调整 gson 插件
欢迎访问我的 GitHub
这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
本篇概览
从本章开始我们一起来实战 pinpoint 插件开发,做一些实用的 pinpoint 插件,本着先易后难的原则,我们从修改现有插件开始吧;
准备工作
本次实战的操作环境是 win10 专业版,安装了 Docker Community Edition Version 17.09.0-ce-win33(13620);
编译环境,请参照《Docker下,极速体验编译pinpoint1.6.x分支》,我们会用这个容器编译构建修改过的插件,为了复制文件方便,我们启动容器使用以下命令:
参数-v c:/share:/usr/Downloads 表示将当前电脑的 c:/share 目录和容器的/usr/Downloads 目录建立映射,这样我们就能把容器里的文件复制出来了(记得先在 c 盘根目录下创建 share 目录);
pinpoint 的运行环境,请参照《Docker下,极速体验pinpoint1.6.3》,启动了三个容器,一个是 pinpoint 的 web server,还有两个是运行着 web 应用的 tomcat,运行环境运行成功后,我们可以在 pinpoint 的 web server 上看到 web 应用的服务调用链,为了复制文件方便,我们将 docker-compose.yml 文件中的每个容器也加上目录映射参数,整个 docker-compose.yml 内容如下:
可以看到每个容器的配置中都有 volumes 参数,对容器和当前电脑的目录做了映射;
pinpoint 对 Gson 类的监控
在之前的《Docker下,极速体验pinpoint1.6.3》一文中,我们在 tomcat 上部署了一个 web 应用,里面有这么一段代码:
上面的代码中用到了 Gson 类的 toJson 方法,由于 pinpoint1.6.3 是带有 Gson 插件的,所以执行此方法后在 pinpoint 的调用链跟踪列表中可以看到对 toJson 方法的调用,如下图,至于如何部署和执行这段代码,请参照《Docker下,极速体验pinpoint1.6.3》:
上图底部的红框中是对 Gson 的 toJson 方法的监控,可以看到这个节点已经不能展开了,难道 gson 插件不输出一些参数么?是本来就没有参数?还是参数没有显示?
分析源码
去 pinpoint 的 github 上看看,地址:https://github.com/naver/pinpoint;切到 1.6.x 分支,在 plugin 目录下可以看见 gson 插件的工程,如下图红框所示:
先看看实现这个插件拦截了 Gson 的 toJson 方法后做了什么,做的事情都封装在 ToJsonInterceptor.java 中:
上面的代码是 Gson 的 toJson 方法执行前做的事情:开启了一次追踪,我们再来看看 Gson 的 toJson 方法执行结束后做了什么:
注意这一句代码:
这表示 toJson 方法的返回值如果非空并且是 String 对象的时候,pinpoint 会记录一个参数 GsonPlugin.GSON_ANNOTATION_KEY_JSON_LENGTH,这个参数的值是 toJson 方法返回的字符串的长度;
已经记录了参数,但在 pinpoint 页面上却没有展示出来,我们去看看这个参数的定义吧:
GSON_ANNOTATION_KEY_JSON_LENGTH 是通过 AnnotationKeyFactory.of 方法创建的,我们跟踪这个方法,最终进入 DefaultAnnotationKey 的构造方法:
上述代码表示,如果我们不传入 VIEW_IN_RECORD_SET,那么 viewInRecordSet 就一直为 false,这就是导致 gson.json.length 参数在 pinpoint 中不显示的原因,要想让 gson.json.length 显示出来,只要在 AnnotationKeyFactory.of 方法的入参中加入 VIEW_IN_RECORD_SET 即可,接下来我们开始动手修改吧;
在编译环境修改源码
在命令行执行以下命令登录到编译环境的容器中:
修改这个文件:
找到下面这行代码:
改成下面这样,AnnotationKeyFactory.of 方法的入参从两个变成三个了:
修改完毕后保存文件,进入 pinpoint 工程目录/usr/local/work/pinpoint-1.6.x,执行以下命令开始编译:
编译完成后进入以下目录:
可以见到最新构建的 gson 插件,如下图黄框所示:
把这个文件复制到/usr/Downloads 目录,由于 pinpoint 运行环境的三个容器也建立了自己的/usr/Downloads 和 c:/share 目录的映射,所以它们也能立即访问这个文件了;
替换 pinpoint server 的 gson 插件
执行命令 docker exec -it pinpoint-server /bin/bash 进入 pinpoint server 容器;
执行以下命令替换原有的 gson 插件:
以上命令将 pinpoint-collector 和 pinpoint-web 两个容器的 gson 插件先删除,再把我们放在 c:/share 目录下最新的 gson 插件复制过去;
重启 collector 和 web 两个应用,执行以下命令:
替换 tomcat001 容器的 gson 插件
执行命令 docker exec -it tomcat001 /bin/bash 进入 tomcat001 容器;
执行以下命令替换原有的 gson 插件:
以上命令将 pinpoint agent 目录下的 gson 插件先删除,再把我们放在 c:/share 目录下最新的 gson 插件复制过去;
重启,由于 tomcat 是随着容器一起启动的,此处如果用 shutdown.sh 命令停止 tomcat 服务会导致容器退出,所以我们直接重启 tomcat001 容器吧;
执行 exit 退出容器;
在当前电脑的命令行执行 docker restart tomcat001 重启容器;
验证新的插件
验证前,请确保 web 应用已经按照《Docker下,极速体验pinpoint1.6.3》中的方式部署到了 tomcat001 和 tomcat002 上面;
浏览器访问:http://localhost:8081/pinpointtracedemo/tracegson?name=tom&age=11,这次访问会有一次 Gson 的 toJson 方法调用;
通过访问 pinpoint-server,看刚刚那次请求的追踪信息,如下图:
toJson 这个节点现在可以展开了,红框中就是新的节点,内容是我们修改过的 gson.json.length 参数,值是 23;
小结
至此,我们的第一次插件开发实战就结束了,小结本次插件开发过程:
修改插件源码;
编译构建成新的包;
新包替换 pingpoint server 上的 collector 和 web 应用中的旧包;
重启 pinpoint server 上的 collector 和 web server;
新包替换 pinpoint agent 上的旧包;
重启 agent 上的业务的 web server;
以上只是修改了原有插件,接下来的实战中,我们一起创建一个全新的插件,实现我们需要的功能;
欢迎关注 InfoQ:程序员欣宸
版权声明: 本文为 InfoQ 作者【程序员欣宸】的原创文章。
原文链接:【http://xie.infoq.cn/article/2f6b5957734f5729aa3998ae9】。文章转载请联系作者。
评论