Pinpoint插件是pinpoint-agent的组成部分,pinpoint-agent经过对JVM字节码的修改实现对代码动做的采集,而具体的采集过程就是经过pinpoint插件来完成的。php
Pinpoint默认插件已有58个(1.8.3版本,见附录),根据插件名能够很快了解该插件针对采集的功能点。java
插件会对具体某类技术的“关键代码”进行动做采集,如:jdk-http插件会切入到sun.net.www.protocol.http.HttpURLConnection的connect方法中,这些“关键代码”使得其它全部上层框架组件的行为调用都能被pinpoint采集到。node
官方提供的插件使得java的大部分生态应用的行为都能经过简单部署后采集得到,但对于新技术的出现 、企业内部业务的数据、特殊业务需求等状况就须要有针对性的开发新插件来实现mysql
Pinpoint 插件由TraceMetadataProvider和ProfilerPlugin的实现组成,前者的实现给agent、collector、web三组件提供ServiceType和AnnotationKey,然后者的实现用于给agent使用,主要用来修改目标类、记录跟踪数据等操做。 web
那么ServiceType和AnnotationKey的做用是什么呢?其实每一个 Span 和 SpanEvent 都包含一个 ServiceType,这个ServiceType表示跟踪方法所属的库,以及跟踪它的Span和spanevent应该如何处理,并且ServiceType是非序列化传输的,为了尽可能压缩 Agent 到 Collector 数据包的大小,ServiceType 被设计成不是以序列化字符串的形式发送的,而是以整形数字发送的 (code 字段),这就须要创建一个映射关系,将 code 转换成对应的 ServiceType 实例,这个映射机制就是由 TraceMetadataProvider 负责的redis
若是要编写一个将被公开共享的插件,就必须联系pinpoint团队来得到分配的ServiceType code(官方已使用的ServiceType code见附录)spring
所以开发非共享的插件,可以使用如下范围code:
( 非公开code与组件对应范围表)sql
再来讲说AnnotationKey,Annotation 是包含在 Span 和 SpanEvent 中的更详尽的数据,以键值对的形式存在,键就是AnnotationKey,值是基本类型,String或者byte[]mongodb
最后须要注意的是:ServiceType code和AnnotationKey code必须是全局唯一的json
开发Pinpoint插件主要分为如下四步:
下面以开发一个demo插件为例,演示pinpoint插件的开发过程:
一、 将pinpoint源码在本地项目中导入并调试经过
二、 在Plugins模块下点击右键,New->Module新增子模块:
选择Maven类型,进入下一步,输入插件ArtifactId,由于是demo演示,因此这里咱们ArtifactId就叫:“pinpoint-demo-plugin”:
点击“下一步”->输入“Module_name”->点击“完成”:
一、加入父工程依赖关系:
<parent> <groupId>com.navercorp.pinpoint</groupId> <artifactId>pinpoint</artifactId> <relativePath>../..</relativePath> <version>1.8.3</version> </parent>
二、加入属性设置,设置编译使用的JDK目录,及编译的版本,因为官方推荐使用的是JDK8所以使用JDK8目录,但编译的版本考虑兼容性等缘由,采用1.6:
<properties> <jdk.version>1.6</jdk.version> <jdk.home>${env.JAVA_8_HOME}</jdk.home> <sniffer.artifactid>java18</sniffer.artifactid> </properties>
注意:pinpoint项目要成功跑起来,须要按官方要求配置“JAVA_6_HOME、JAVA_7_HOME、JAVA_8_HOME、JAVA_9_HOME”等环境变量
三、设置模块项目基本信息
<artifactId> pinpoint-demo-plugin </artifactId> <name>pinpoint-demo-plugin</name> <packaging>jar</packaging>
四、设置依赖管理:pinpoint-plugin-bom
<dependencyManagement> <dependencies> <dependency> <groupId>com.navercorp.pinpoint</groupId> <artifactId>pinpoint-plugin-bom</artifactId> <version>${project.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
五、设置项目依赖,可根据状况加入私人插件所需求的第三方依赖,另外插件默认须要依赖pinpoint-bootstrap-core提供基础支持
<dependencies> <dependency> <groupId>com.navercorp.pinpoint</groupId> <artifactId>pinpoint-bootstrap-core</artifactId> <scope>provided</scope> </dependency> ……… </dependencies>
一、实现ProfilerPlugin接口
该接口只有一个简单的setup方法,该方法有一个参数ProfilerPluginSetupContext,利用参数对象能够得到插件配置、增长应用类型发现器(ApplicationTypeDetector)。ApplicationTypeDetector接口是与TraceMetadataProvider接口配合使用的,TraceMetadataProvider负责定义新的应用类型(后面会说明),ApplicationTypeDetector负责定义告诉pinpoint怎么样经过应用的启动类察觉到当前当前应用的类型
在ProfilerPlugin实现逻辑中,咱们除了实现ProfilerPlugin接口之外,还能够同时实现TransformTemplateAware接口,pinpoint会检测到该实现,并为你注入TransformTemplate,TransformTemplate是pinpoint在进行类加载时为开发者提供的JVM字节码加强处理的入口,具体操做是经过调用它的transform方法并实现TransformCallback回调逻辑,pinpoint提供了字节码加强处理时的一些工具类API方便作处理,同时在处理过程当中引入了一个叫“拦截器(Interceptor)”的概念,结合工具类API来实现对字节码进行加强。故:TransformTemplate负责字节码加强的管控,Interceptor负责具体的字节码加强逻辑:
最后,我只还须要编写拦截器的具体处理逻辑,拦截器的实现一般经过实现AroundInterceptor接口完成,这是一种简单的实现方式,能够用来实现咱们本身的处理逻辑,相似于Spring AOP机制。而作为pinpoint插件开发,大多状况下会与当前插件采集的应用调用相关,咱们能够经过继承SpanEventSimpleAroundInterceptorForPlugin的方式来实现拦截器,该类为抽象类,实现了AroundInterceptor接口并加入了链路跟踪等相关支持,继承此类后咱们须要实现doInBeforeTrace与doInAfterTrace方法,这两个方法相比AroundInterceptor接口中的before与after两个方法多出了SpanEventRecorder参数,利用该参数咱们能够在拦截器中实现链路跟踪上报等处理逻辑:
二、实现TraceMetadataProvider接口
该接口一样只有一个简单的setup方法,该方法有一个参数TraceMetadataSetupContext,利用参数对象能够在插件工做前“声明”应用类型、应用属性,声明的内容将结合ProfilerPlugin实现使用:
在 “resource/META-INF/services” 目录下加入ProfilerPlguin与TraceMetadataProvider配置文件,注意文件名为固定写法,文件内容分别指向对应插件实现类:
点击右方maven窗口,选择插件项目 -> Lifecycle -> install
注意:pinpoint源码项目是经过“plugins”父项统一打包,若是要单独打包插件,须要将“assembly.xml”复制一份到插件项目根目录下(pom.xml平级)
打包的插件应放在agent的plugin目录,web和collector的WEB-INF/lib目录。咱们只需将插件打好的jar包加入到该目录下的plguin目录中,再将agent按javaagent的部署方式部署到对应采集节点,便可生效
以上插件开发中对demo项目的com.xxx.apm.demo1.DemoTargetClass.test()方法进行了采集,经过pinpoing-web服务能够跟踪到test()方法的执行了:
官方插件列表:
pinpoint-cassandra-driver-plugin | pinpoint-redis-plugin |
pinpoint-json-lib-plugin | pinpoint-thrift-plugin |
pinpoint-user-plugin | pinpoint-okhttp-plugin |
pinpoint-google-httpclient-plugin | pinpoint-vertx-plugin |
pinpoint-jetty-plugin | pinpoint-undertow-plugin |
pinpoint-spring-boot-plugin | pinpoint-kafka-plugin |
pinpoint-ibatis-plugin | pinpoint-node-js-plugin |
pinpoint-mybatis-plugin | pinpoint-commons-dbcp2-plugin |
pinpoint-log4j-plugin | pinpoint-jdk-http-plugin |
pinpoint-dubbo-plugin | pinpoint-tomcat-plugin |
pinpoint-cxf-plugin | pinpoint-grpc-plugin |
pinpoint-hystrix-plugin | pinpoint-spring-plugin |
pinpoint-rxjava-plugin | pinpoint-logback-plugin |
pinpoint-weblogic-plugin | pinpoint-activemq-client-plugin |
pinpoint-undertow-servlet-plugin | pinpoint-jboss-plugin |
pinpoint-fastjson-plugin | pinpoint-resin-plugin |
pinpoint-hbase-plugin | pinpoint-php-plugin |
pinpoint-jsp-plugin | pinpoint-akka-http-plugin |
pinpoint-rabbitmq-plugin | pinpoint-mongodb-driver-plugin |
pinpoint-druid-plugin | pinpoint-httpclient3-plugin |
pinpoint-openwhisk-plugin | pinpoint-ning-asynchttpclient-plugin |
pinpoint-httpclient4-plugin | pinpoint-resttemplate-plugin |
pinpoint-gson-plugin | pinpoint-netty-plugin |
pinpoint-cubrid-jdbc-driver-plugin | pinpoint-mysql-jdbc-driver-plugin |
pinpoint-mariadb-jdbc-driver-plugin | pinpoint-postgresql-jdbc-driver-plugin |
pinpoint-jtds-plugin | pinpoint-commons-dbcp-plugin |
pinpoint-oracle-jdbc-driver-plugin | pinpoint-hikaricp-plugin |
pinpoint-arcus-plugin | pinpoint-redis-lettuce-plugin |
pinpoint-websphere-plugin | pinpoint-jackson-plugin |
官方ServiceType code:
(官方公有code与组件对应表1)
(官方公有code与组件对应表2)
(官方公有code与组件对应表3)