讲透Pinpoint插件开发

什么是Pinpoint插件

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插件结构:

image.png

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:
image.png
( 非公开code与组件对应范围表)sql

再来讲说AnnotationKey,Annotation 是包含在 Span 和 SpanEvent 中的更详尽的数据,以键值对的形式存在,键就是AnnotationKey,值是基本类型,String或者byte[]mongodb

最后须要注意的是:ServiceType code和AnnotationKey code必须是全局唯一的json

插件开发步骤

开发Pinpoint插件主要分为如下四步:

  1. 实现TraceMetadataProvider
  2. 实现ProfilerPlugin
  3. 将TraceMetadataProvider与ProfilerPlugin实现配置到META-INF\services中的并打包插件
  4. 部署插件

插件开发演示

下面以开发一个demo插件为例,演示pinpoint插件的开发过程:

第一步:基于pinpoint源码项目,在“plugins”子模块下新建插件子模块

一、 将pinpoint源码在本地项目中导入并调试经过

image.png

二、 在Plugins模块下点击右键,New->Module新增子模块:

image.png

选择Maven类型,进入下一步,输入插件ArtifactId,由于是demo演示,因此这里咱们ArtifactId就叫:“pinpoint-demo-plugin”:

image.png

点击“下一步”->输入“Module_name”->点击“完成”:

image.png

第二步:编辑pom.xml,引入插件必要的依赖及配置

一、加入父工程依赖关系:

<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接口和TraceMetadataProvider接口

一、实现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负责具体的字节码加强逻辑:

image.png

image.png

最后,我只还须要编写拦截器的具体处理逻辑,拦截器的实现一般经过实现AroundInterceptor接口完成,这是一种简单的实现方式,能够用来实现咱们本身的处理逻辑,相似于Spring AOP机制。而作为pinpoint插件开发,大多状况下会与当前插件采集的应用调用相关,咱们能够经过继承SpanEventSimpleAroundInterceptorForPlugin的方式来实现拦截器,该类为抽象类,实现了AroundInterceptor接口并加入了链路跟踪等相关支持,继承此类后咱们须要实现doInBeforeTrace与doInAfterTrace方法,这两个方法相比AroundInterceptor接口中的before与after两个方法多出了SpanEventRecorder参数,利用该参数咱们能够在拦截器中实现链路跟踪上报等处理逻辑:

image.png

二、实现TraceMetadataProvider接口

该接口一样只有一个简单的setup方法,该方法有一个参数TraceMetadataSetupContext,利用参数对象能够在插件工做前“声明”应用类型、应用属性,声明的内容将结合ProfilerPlugin实现使用:

image.png

第四步:定义ProfilerPlugin与TraceMetadataProvider配置

在 “resource/META-INF/services” 目录下加入ProfilerPlguin与TraceMetadataProvider配置文件,注意文件名为固定写法,文件内容分别指向对应插件实现类:

image.png

第五步:使用maven将插件打成jar包

点击右方maven窗口,选择插件项目 -> Lifecycle -> install

image.png

注意:pinpoint源码项目是经过“plugins”父项统一打包,若是要单独打包插件,须要将“assembly.xml”复制一份到插件项目根目录下(pom.xml平级)

如何使用Pinpoint插件

打包的插件应放在agent的plugin目录,web和collector的WEB-INF/lib目录。咱们只需将插件打好的jar包加入到该目录下的plguin目录中,再将agent按javaagent的部署方式部署到对应采集节点,便可生效

以上插件开发中对demo项目的com.xxx.apm.demo1.DemoTargetClass.test()方法进行了采集,经过pinpoing-web服务能够跟踪到test()方法的执行了:

image.png

附录

官方插件列表:

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:
image.png

(官方公有code与组件对应表1)

image.png
(官方公有code与组件对应表2)

image.png(官方公有code与组件对应表3)

相关文章
相关标签/搜索