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)