计算器快捷键(笔记本计算器快捷键)
608
2022-05-29
欢迎访问我的GitHub
这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
本篇概览
从本章开始我们一起来实战pinpoint插件开发,做一些实用的pinpoint插件,本着先易后难的原则,我们从修改现有插件开始吧;
准备工作
本次实战的操作环境是win10专业版,安装了Docker Community Edition Version 17.09.0-ce-win33(13620);
编译环境,请参照《Docker下,极速体验编译pinpoint1.6.x分支》,我们会用这个容器编译构建修改过的插件,为了复制文件方便,我们启动容器使用以下命令:
docker run --name=ppcompile001 -p 19003:22 -idt -v c:/share:/usr/Downloads bolingcavalry/jdk7-mvn339-pinpoint16x-compile:0.0.1
参数
-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内容如下:
version: '2' services: pinpoint-server: image: bolingcavalry/centos67-hbase126-pinpoint163-server:0.0.1 container_name: pinpoint-server ports: - "19001:22" - "28080:28080" volumes: - c:/share:/usr/Downloads restart: always tomcat001: image: bolingcavalry/centos67-pinpoint163-agent:0.0.1 container_name: tomcat001 links: - pinpoint-server:pinpointhost ports: - "8081:8080" environment: TOMCAT_SERVER_ID: tomcat001 PINPOINT_AGENT_ID: ppagent20171105001 PINPOINT_APPLICATION_NAME: app20171105001 volumes: - c:/share:/usr/Downloads restart: always tomcat002: image: bolingcavalry/centos67-pinpoint163-agent:0.0.1 container_name: tomcat002 depends_on: - tomcat001 links: - pinpoint-server:pinpointhost ports: - "8082:8080" environment: TOMCAT_SERVER_ID: tomcat002 PINPOINT_AGENT_ID: ppagent20171105002 PINPOINT_APPLICATION_NAME: app20171105002 volumes: - c:/share:/usr/Downloads restart: always
可以看到每个容器的配置中都有volumes参数,对容器和当前电脑的目录做了映射;
pinpoint对Gson类的监控
在之前的《Docker下,极速体验pinpoint1.6.3》一文中,我们在tomcat上部署了一个web应用,里面有这么一段代码:
public String tracegson(HttpServletRequest request, Model model) { String name = get(request, "name"); String age = get(request, "age"); Student student = new Student(); student.setName(name); student.setAge(Integer.valueOf(age)); Gson gson = new Gson(); String parseStr = gson.toJson(student, Student.class); logger.info("gson str [{}]", parseStr); return String.format("gson str : %s [%s]", parseStr, tag()); }
上面的代码中用到了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中:
@Override public void before(Object target) { if (logger.isDebugEnabled()) { logger.beforeInterceptor(target, null); } final Trace trace = traceContext.currentTraceObject(); if (trace == null) { return; } trace.traceBlockBegin(); }
上面的代码是Gson的toJson方法执行前做的事情:开启了一次追踪,我们再来看看Gson的toJson方法执行结束后做了什么:
@Override public void after(Object target, Object result, Throwable throwable) { if (logger.isDebugEnabled()) { logger.afterInterceptor(target, null, result, throwable); } final Trace trace = traceContext.currentTraceObject(); if (trace == null) { return; } try { SpanEventRecorder recorder = trace.currentSpanEventRecorder(); recorder.recordServiceType(GsonPlugin.GSON_SERVICE_TYPE); recorder.recordApi(descriptor); recorder.recordException(throwable); if (result != null && result instanceof String) { recorder.recordAttribute(GsonPlugin.GSON_ANNOTATION_KEY_JSON_LENGTH, ((String) result).length()); } } finally { trace.traceBlockEnd(); } }
注意这一句代码:
recorder.recordAttribute(GsonPlugin.GSON_ANNOTATION_KEY_JSON_LENGTH, ((String) result).length());
这表示toJson方法的返回值如果非空并且是String对象的时候,pinpoint会记录一个参数GsonPlugin.GSON_ANNOTATION_KEY_JSON_LENGTH,这个参数的值是toJson方法返回的字符串的长度;
已经记录了参数,但在pinpoint页面上却没有展示出来,我们去看看这个参数的定义吧:
public static final AnnotationKey GSON_ANNOTATION_KEY_JSON_LENGTH = AnnotationKeyFactory.of(9000, "gson.json.length");
GSON_ANNOTATION_KEY_JSON_LENGTH 是通过AnnotationKeyFactory.of方法创建的,我们跟踪这个方法,最终进入DefaultAnnotationKey的构造方法:
DefaultAnnotationKey(int code, String name, AnnotationKeyProperty... properties) { this.code = code; this.name = name; boolean viewInRecordSet = false; boolean errorApiMetadata = false; for (AnnotationKeyProperty property : properties) { switch (property) { case VIEW_IN_RECORD_SET: viewInRecordSet = true; break; case ERROR_API_METADATA: errorApiMetadata = true; break; } } this.viewInRecordSet = viewInRecordSet; this.errorApiMetadata = errorApiMetadata; }
上述代码表示,如果我们不传入VIEW_IN_RECORD_SET,那么viewInRecordSet就一直为false,这就是导致gson.json.length参数在pinpoint中不显示的原因,要想让gson.json.length显示出来,只要在AnnotationKeyFactory.of方法的入参中加入VIEW_IN_RECORD_SET即可,接下来我们开始动手修改吧;
在编译环境修改源码
在命令行执行以下命令登录到编译环境的容器中:
docker exec -it ppcompile001 /bin/bash
修改这个文件:
/usr/local/work/pinpoint-1.6.x/plugins/gson/src/main/java/com/navercorp/pinpoint/plugin/gson/GsonPlugin.java
找到下面这行代码:
public static final AnnotationKey GSON_ANNOTATION_KEY_JSON_LENGTH = AnnotationKeyFactory.of(9000, "gson.json.length");
改成下面这样,AnnotationKeyFactory.of方法的入参从两个变成三个了:
public static final AnnotationKey GSON_ANNOTATION_KEY_JSON_LENGTH = AnnotationKeyFactory.of(9000, "gson.json.length", com.navercorp.pinpoint.common.trace.AnnotationKeyProperty.VIEW_IN_RECORD_SET);
修改完毕后保存文件,进入pinpoint工程目录/usr/local/work/pinpoint-1.6.x,执行以下命令开始编译:
mvn install -Dmaven.test.skip=true -e
编译完成后进入以下目录:
/usr/local/work/pinpoint-1.6.x/plugins/gson/target
可以见到最新构建的gson插件,如下图黄框所示:
把这个文件复制到
/usr/Downloads
目录,由于pinpoint运行环境的三个容器也建立了自己的
/usr/Downloads
和
c:/share
目录的映射,所以它们也能立即访问这个文件了;
替换pinpoint server的gson插件
执行命令
docker exec -it pinpoint-server /bin/bash
进入pinpoint server容器;
执行以下命令替换原有的gson插件:
rm -f /usr/local/work/tomcat-collector/apache-tomcat-8.0.36/webapps/ROOT/WEB-INF/lib/pinpoint-gson-plugin-1.6.3-SNAPSHOT.jar cp /usr/Downloads/pinpoint-gson-plugin-1.6.3-SNAPSHOT.jar /usr/local/work/tomcat-collector/apache-tomcat-8.0.36/webapps/ROOT/WEB-INF/lib/ rm -f /usr/local/work/tomcat-web/apache-tomcat-8.0.36/webapps/ROOT/WEB-INF/lib/pinpoint-gson-plugin-1.6.3-SNAPSHOT.jar cp /usr/Downloads/pinpoint-gson-plugin-1.6.3-SNAPSHOT.jar /usr/local/work/tomcat-web/apache-tomcat-8.0.36/webapps/ROOT/WEB-INF/lib/
以上命令将pinpoint-collector和pinpoint-web两个容器的gson插件先删除,再把我们放在
c:/share
目录下最新的gson插件复制过去;
重启collector和web两个应用,执行以下命令:
/usr/local/work/tomcat-collector/apache-tomcat-8.0.36/bin/shutdown.sh /usr/local/work/tomcat-web/apache-tomcat-8.0.36/bin/shutdown.sh /usr/local/work/tomcat-collector/apache-tomcat-8.0.36/bin/startup.sh /usr/local/work/tomcat-web/apache-tomcat-8.0.36/bin/startup.sh
替换tomcat001容器的gson插件
执行命令
docker exec -it tomcat001 /bin/bash
进入tomcat001容器;
执行以下命令替换原有的gson插件:
rm -f /usr/local/work/pinpoint-agent-1.6.3/plugin/pinpoint-gson-plugin-1.6.3-SNAPSHOT.jar cp /usr/Downloads/pinpoint-gson-plugin-1.6.3-SNAPSHOT.jar /usr/local/work/pinpoint-agent-1.6.3/plugin/
以上命令将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;
以上只是修改了原有插件,接下来的实战中,我们一起创建一个全新的插件,实现我们需要的功能;
欢迎关注华为云博客:程序员欣宸
学习路上,你不孤单,欣宸原创一路相伴…
Java 分布式
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。