├── .gitignore
├── README.md
├── bom
└── pom.xml
├── collect
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── cn
│ │ │ └── bytes1024
│ │ │ └── hound
│ │ │ └── collect
│ │ │ ├── AgentCollector.java
│ │ │ ├── context
│ │ │ ├── ActiveTracerSpan.java
│ │ │ ├── ApplicationContext.java
│ │ │ ├── DefaultActiveTracerSpan.java
│ │ │ ├── DefaultApplicationContext.java
│ │ │ ├── DefaultReporter.java
│ │ │ └── DefaultTraceContext.java
│ │ │ ├── enhance
│ │ │ ├── DefaultEnhanceFactory.java
│ │ │ ├── DefaultEnhanceRuleChainProxy.java
│ │ │ ├── DefaultInterceptorFactory.java
│ │ │ ├── EnhanceFactory.java
│ │ │ ├── EnhanceRuleChainProxy.java
│ │ │ ├── InterceptorFactory.java
│ │ │ ├── delegation
│ │ │ │ ├── ConstructorInterceptDelegation.java
│ │ │ │ └── MethodsInterceptWithDelegation.java
│ │ │ └── rule
│ │ │ │ ├── AbstractEnhanceRule.java
│ │ │ │ ├── DefaultEnhanceRuleChain.java
│ │ │ │ ├── EnhanceConstructorRule.java
│ │ │ │ ├── EnhanceMethodRule.java
│ │ │ │ ├── EnhanceRule.java
│ │ │ │ ├── EnhanceRuleChain.java
│ │ │ │ ├── EnhanceSourceRule.java
│ │ │ │ └── EnhanceStaticMethodRule.java
│ │ │ ├── exception
│ │ │ ├── BaseException.java
│ │ │ ├── ConstructorException.java
│ │ │ └── NotFoundPluginLoader.java
│ │ │ ├── module
│ │ │ ├── CollectModuleFactory.java
│ │ │ ├── DefineModule.java
│ │ │ ├── ModuleFactory.java
│ │ │ └── providers
│ │ │ │ ├── AgentOptionProvider.java
│ │ │ │ ├── ApplicationContextProvider.java
│ │ │ │ ├── EnhanceFactoryProvider.java
│ │ │ │ ├── EnhanceRuleChainProxyProvider.java
│ │ │ │ ├── InterceptorFactoryProvider.java
│ │ │ │ ├── ServerReporterProvider.java
│ │ │ │ ├── SofaTracerProvider.java
│ │ │ │ ├── TraceContextProvider.java
│ │ │ │ └── TransferBufferProvider.java
│ │ │ └── processor
│ │ │ ├── AbstractProcessor.java
│ │ │ ├── AgentCollectProcessor.java
│ │ │ ├── MetricsCollectProcessor.java
│ │ │ └── Processor.java
│ └── resources
│ │ └── collect.properties
│ └── test
│ └── java
│ └── cn
│ └── bytes1024
│ └── hound
│ └── collect
│ └── test
│ ├── ConfigLoadingTest.java
│ └── NettyTimerWheelTest.java
├── commons
├── pom.xml
└── src
│ └── main
│ └── java
│ └── cn
│ └── bytes1024
│ └── hound
│ └── commons
│ ├── enums
│ ├── ProcessorStatus.java
│ └── ProcessorType.java
│ ├── option
│ ├── ConfigOption.java
│ ├── ConfigOptionDefine.java
│ └── DefaultConfigOption.java
│ └── util
│ ├── NamedThreadLocal.java
│ ├── RefClassUtil.java
│ ├── ThreadPoolUtils.java
│ └── TimerWheel.java
├── loader
├── pom.xml
└── src
│ └── main
│ └── java
│ └── cn
│ └── bytes1024
│ └── hound
│ └── loader
│ ├── ExtensionLoader.java
│ └── Holder.java
├── plugins
├── plugins-bom
│ └── pom.xml
├── plugins-define
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── cn
│ │ └── bytes1024
│ │ └── hound
│ │ └── plugins
│ │ └── define
│ │ ├── AbstractPluginDefine.java
│ │ ├── EnhanceContext.java
│ │ ├── EnhancedDefine.java
│ │ ├── InterceptContext.java
│ │ ├── InterceptContextFilter.java
│ │ ├── PluginDefine.java
│ │ ├── TraceContext.java
│ │ ├── filter
│ │ ├── DefaultTraceContextFilterOption.java
│ │ └── TraceContextFilterOption.java
│ │ └── interceptor
│ │ ├── ConstructorInterceptor.java
│ │ ├── IgnoreInterceptor.java
│ │ ├── InterceptorPluginAware.java
│ │ ├── MethodAroundInterceptor.java
│ │ ├── StaticMethodAroundInterceptor.java
│ │ └── supper
│ │ ├── AbstractConstructorInterceptor.java
│ │ ├── AbstractMethodAroundInterceptor.java
│ │ ├── AbstractTransmissionMethodAroundInterceptor.java
│ │ ├── RemoteTransmission.java
│ │ └── async
│ │ └── AbstractAsyncMethodAroundInterceptor.java
├── plugins-druid
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── cn
│ │ │ └── bytes1024
│ │ │ └── hound
│ │ │ └── plugins
│ │ │ └── druid
│ │ │ ├── DruidDataSourcePlugin.java
│ │ │ ├── DruidPooledConnectionPlugin.java
│ │ │ └── interceptor
│ │ │ └── DruidPluginInterceptor.java
│ │ └── resources
│ │ └── META-INF
│ │ └── plugins
│ │ └── cn.bytes1024.hound.plugins.define.PluginDefine
├── plugins-fastjson
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── cn
│ │ │ └── bytes1024
│ │ │ └── hound
│ │ │ └── plugins
│ │ │ └── fastjson
│ │ │ ├── FastJsonPlugin.java
│ │ │ └── interceptor
│ │ │ └── FastJsonMethodInterceptor.java
│ │ └── resources
│ │ └── META-INF
│ │ └── plugins
│ │ └── cn.bytes1024.hound.plugins.define.PluginDefine
├── plugins-gson
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── cn
│ │ │ └── bytes1024
│ │ │ └── hound
│ │ │ └── plugins
│ │ │ └── gson
│ │ │ ├── GsonPlugin.java
│ │ │ └── intercepotr
│ │ │ └── GsonMethodInterceptor.java
│ │ └── resources
│ │ └── META-INF
│ │ └── plugins
│ │ └── cn.bytes1024.hound.plugins.define.PluginDefine
├── plugins-httpclient
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── cn
│ │ │ └── bytes1024
│ │ │ └── hound
│ │ │ └── plugins
│ │ │ └── httpclient
│ │ │ ├── HttpClientPlugin.java
│ │ │ └── interceptor
│ │ │ └── HttpClientMethodInterceptor.java
│ │ └── resources
│ │ └── META-INF
│ │ └── plugins
│ │ └── cn.bytes1024.hound.plugins.define.PluginDefine
├── plugins-mybatis
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── cn
│ │ │ └── bytes1024
│ │ │ └── hound
│ │ │ └── plugins
│ │ │ └── mybatis
│ │ │ ├── MybatisAnnotationMethodPlugin.java
│ │ │ ├── MybatisBoundSqlPlugin.java
│ │ │ ├── MybatisPlugin.java
│ │ │ └── interceptor
│ │ │ ├── MybatisBoundSqlPluginInterceptor.java
│ │ │ └── MybatisPluginInterceptor.java
│ │ └── resources
│ │ └── META-INF
│ │ └── plugins
│ │ └── cn.bytes1024.hound.plugins.define.PluginDefine
├── plugins-mysql-jdbc
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── cn
│ │ │ └── bytes1024
│ │ │ └── hound
│ │ │ └── plugins
│ │ │ └── mysql
│ │ │ └── jdbc
│ │ │ ├── MysqlConnectionTransformerPlugin.java
│ │ │ ├── MysqlJdbcPlugin.java
│ │ │ ├── MysqlJdbcPreparedCallPlugin.java
│ │ │ ├── MysqlJdbcPreparedStatementPlugin.java
│ │ │ └── interceptor
│ │ │ ├── MysqlJdbcInterceptor.java
│ │ │ ├── MysqlJdbcPreparedCallInterceptor.java
│ │ │ └── MysqlJdbcPreparedStatementInterceptor.java
│ │ └── resources
│ │ └── META-INF
│ │ └── plugins
│ │ └── cn.bytes1024.hound.plugins.define.PluginDefine
├── plugins-okhttp
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── cn
│ │ │ └── bytes1024
│ │ │ └── hound
│ │ │ └── plugins
│ │ │ └── okhttp
│ │ │ ├── Containts.java
│ │ │ ├── OkHttpClientPlugin.java
│ │ │ ├── OkHttpRealCallPlugin.java
│ │ │ └── interceptor
│ │ │ ├── OkHttpClientMethodInterceptor.java
│ │ │ └── OkHttpRealCallMethodInterceptor.java
│ │ └── resources
│ │ └── META-INF
│ │ └── plugins
│ │ └── cn.bytes1024.hound.plugins.define.PluginDefine
├── plugins-spring
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── cn
│ │ │ └── bytes1024
│ │ │ └── hound
│ │ │ └── plugins
│ │ │ └── spring
│ │ │ ├── SpringBeanPlugin.java
│ │ │ ├── SpringExecutorExecutorsPlugin.java
│ │ │ ├── SpringWebMvcPlugin.java
│ │ │ └── interceptor
│ │ │ └── SpringPluginMethodInterceptor.java
│ │ └── resources
│ │ └── META-INF
│ │ └── plugins
│ │ └── cn.bytes1024.hound.plugins.define.PluginDefine
├── plugins-tomcat
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── cn
│ │ │ └── bytes1024
│ │ │ └── hound
│ │ │ └── plugins
│ │ │ └── tomcat
│ │ │ ├── Tomcat7xPlugin.java
│ │ │ └── interceptor
│ │ │ └── TomcatMethodInterceptor.java
│ │ └── resources
│ │ └── META-INF
│ │ └── plugins
│ │ └── cn.bytes1024.hound.plugins.define.PluginDefine
├── plugins-webflux
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── cn
│ │ │ └── bytes1024
│ │ │ └── hound
│ │ │ └── plugins
│ │ │ └── webflux
│ │ │ ├── WebFluxOnInboundNextPlugin.java
│ │ │ ├── WebFluxOnOutboundCompletePlugin.java
│ │ │ └── interceptor
│ │ │ ├── OnInboundNextMethodInterceptor.java
│ │ │ └── OnOutboundCompleteMethodInterceptor.java
│ │ └── resources
│ │ └── META-INF
│ │ └── plugins
│ │ └── cn.bytes1024.hound.plugins.define.PluginDefine
└── pom.xml
├── pom.xml
├── server
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── cn
│ │ └── bytes1024
│ │ └── hound
│ │ └── server
│ │ ├── ApplicationServer.java
│ │ └── api
│ │ └── IndexApi.java
│ └── resources
│ └── application.yml
└── transfers
├── pom.xml
├── transfers-bom
└── pom.xml
├── transfers-define
├── pom.xml
└── src
│ └── main
│ └── java
│ └── cn
│ └── bytes1024
│ └── hound
│ └── transfers
│ └── define
│ ├── DefineTransmitContent.java
│ ├── TransferDefine.java
│ ├── TransmitMetricsContent.java
│ ├── TransmitTraceContent.java
│ └── buffer
│ ├── DefaultTransferBuffer.java
│ ├── NotifyListener.java
│ └── TransferBuffer.java
└── transfers-web
├── pom.xml
└── src
└── main
├── java
└── cn
│ └── bytes1024
│ └── hound
│ └── transfers
│ └── web
│ ├── AbstractRestApiTransfer.java
│ └── OkHttpRestApiTransfer.java
└── resources
└── META-INF
└── plugins
└── cn.bytes1024.hound.transfers.define.TransferDefine
/.gitignore:
--------------------------------------------------------------------------------
1 | ## .gitignore for Grails 1.2 and 1.3
2 |
3 | # .gitignore for maven
4 | target/
5 | *.releaseBackup
6 |
7 | classes.*
8 |
9 | # web application files
10 | #/web-app/WEB-INF
11 |
12 | # IDE support files
13 | /.classpath
14 | /.launch
15 | /.project
16 | /.settings
17 | /*.launch
18 | /*.tmproj
19 | /ivy*
20 | /eclipse
21 |
22 | # default HSQL database files for production mode
23 | /prodDb.*
24 |
25 | # general HSQL database files
26 | *Db.properties
27 | *Db.script
28 |
29 | # logs
30 | /stacktrace.log
31 | /test/reports
32 | /logs
33 | *.log
34 | *.log.*
35 |
36 | # project release file
37 | /*.war
38 |
39 | # plugin release file
40 | /*.zip
41 | /*.zip.sha1
42 |
43 | # older plugin install locations
44 | /web-app/plugins
45 | /web-app/WEB-INF/classes
46 |
47 | # "temporary" build files
48 | target/
49 | out/
50 | build/
51 |
52 | # other
53 | *.iws
54 |
55 | #.gitignore for java
56 | *.class
57 |
58 | # Package Files #
59 | *.jar
60 | *.war
61 | *.ear
62 |
63 | ## .gitignore for eclipse
64 |
65 | *.pydevproject
66 | .project
67 | .metadata
68 | bin/**
69 | tmp/**
70 | tmp/**/*
71 | *.tmp
72 | *.bak
73 | *.swp
74 | *~.nib
75 | local.properties
76 | .classpath
77 | .settings/
78 | .loadpath
79 |
80 | # External tool builders
81 | .externalToolBuilders/
82 |
83 | # Locally stored "Eclipse launch configurations"
84 | *.launch
85 |
86 | # CDT-specific
87 | .cproject
88 |
89 | # PDT-specific
90 | .buildpath
91 |
92 | ## .gitignore for intellij
93 |
94 | *.iml
95 | *.ipr
96 | *.iws
97 | .idea/
98 |
99 | ## .gitignore for linux
100 | .*
101 | !.gitignore
102 | *~
103 |
104 | ## .gitignore for windows
105 |
106 | # Windows image file caches
107 | Thumbs.db
108 | ehthumbs.db
109 |
110 | # Folder config file
111 | Desktop.ini
112 |
113 | # Recycle Bin used on file shares
114 | $RECYCLE.BIN/
115 |
116 | ## .gitignore for mac os x
117 |
118 | .DS_Store
119 | .AppleDouble
120 | .LSOverride
121 | Icon
122 |
123 |
124 | # Thumbnails
125 | ._*
126 |
127 | # Files that might appear on external disk
128 | .Spotlight-V100
129 | .Trashes
130 |
131 | ## hack for graddle wrapper
132 | !wrapper/*.jar
133 | !**/wrapper/*.jar
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ##### 使用
2 | * 下载
3 | * TODO
4 | * 本地编译
5 | ```
6 | mvn clean package -Dmaven.test.skip=true
7 |
8 | //在 hound-collect 目录下面生成对应的jar文件
9 | //项目启动后面添加参数 -javaagent:xxx\collect.jar
10 | //config 配置目前用处不大
11 |
12 | ```
13 | * 本地测试预览
14 | ```$xslt
15 | 如下,目前使用的三个测试插件数据
16 | {"bizBaggage":{},"endTime":1562249883956,"operationName":"plugin-springBean","parentId":"0.1.1","sampled":true,"spanId":"0.1.1.1","startTime":1562249883951,"sysBaggage":{"method":"servce1","class":"com.example.demo.service.Service"},"traceId":"c0a89a011562249883949100217996"} 5 ms
17 | {"bizBaggage":{},"endTime":1562249883956,"operationName":"plugin-springWebmvc","parentId":"0.1","sampled":true,"spanId":"0.1.1","startTime":1562249883951,"sysBaggage":{"method":"test1","class":"com.example.demo.TestController"},"traceId":"c0a89a011562249883949100217996"} 5 ms
18 | {"bizBaggage":{},"endTime":1562249883960,"operationName":"plugin-tomcat","parentId":"0","sampled":true,"spanId":"0.1","startTime":1562249883949,"sysBaggage":{"method":"invoke","class":"org.apache.catalina.core.StandardHostValve"},"traceId":"c0a89a011562249883949100217996"} 11 ms
19 |
20 | ```
21 | ##### 系统设计
22 | 
23 |
24 | ##### 配置参数
25 | `-javaagent:collect.jar=collect.properties`
26 | ```
27 | #增强代码输出目录
28 | # agent.plugin.debug.path="E:\\"
29 |
30 | ##########################################################################
31 | ###探针编号
32 | ###
33 | bytes.hound.agent.id=agent1
34 | ###是否开启远程传输
35 | bytes.hound.transfer.enabled=true
36 | ###是否开启传输内容打印
37 | bytes.hound.transfer.content.show.enabled=true
38 | ###传输类型
39 | bytes.hound.transfer.type=web
40 | ###服务地址
41 | bytes.hound.transfer.web.address=http://127.0.0.1:8888/v1/transfer/receive
42 | #other config TODO...........
43 | ###########################################################################
44 |
45 | ```
46 |
47 | ##### 功能
48 | ##### [任务列表](https://github.com/bytes1024/hound/wiki/%E5%BC%80%E5%8F%91%E4%BB%BB%E5%8A%A1%E5%88%97%E8%A1%A8)
49 | ##### 支持插件
50 | 名称|版本|粒度
51 | |---|---|---|
52 | |tomcat|6+|粗|
53 | |webflux|5.0.0.release|粗|
54 | |okHttp|3.7.0|粗
55 | |spring|5.0.0.RELEASE|粗
56 | |httpClient|4.5.2|粗
57 | |dubbo|TODO|
58 | |gson|2.8.0|粗
59 | |fastjson|1.2.49|粗
60 | |jackson|TODO
61 | |hystrix|TODO
62 | |mybatis|3.5.2|粗
63 | |hibernate(jpa)|TODO
64 | |mysql-jdbc|TODO
65 | |redis-lettuce|TODO
66 | |spring-data-*(jpa,redis,es,....)|TODO
67 | |rabbitmq|TODO
68 | |rocketmq|TODO
69 | |mongodb|TODO
70 | |log4j|TODO
71 | |dbcp|TODO
72 | |druid|1.1.10|粗
73 | |hikaricp|TODO
74 | |TODO
75 | ##### [文档](https://github.com/bytes1024/hound/wiki)
76 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/AgentCollector.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect;
2 |
3 |
4 | import cn.bytes1024.hound.collect.module.CollectModuleFactory;
5 |
6 | import java.lang.instrument.Instrumentation;
7 |
8 | /**
9 | * 收集器探针
10 | *
11 | * @author 江浩
12 | */
13 | public class AgentCollector {
14 |
15 | /**
16 | * agent 拦截
17 | *
18 | * @param agentArgs
19 | * @param instrumentation
20 | */
21 | public static void premain(String agentArgs, Instrumentation instrumentation) {
22 | CollectModuleFactory applicationContextModuleFactory = new CollectModuleFactory();
23 | applicationContextModuleFactory.init(agentArgs, instrumentation);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/context/ActiveTracerSpan.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.context;
2 |
3 |
4 | import com.alipay.common.tracer.core.span.SofaTracerSpan;
5 |
6 | /**
7 | * 单个线程活跃span的操作信息
8 | *
9 | * LIFO 先进后出 栈原则操作
10 | *
11 | *
12 | * @author 江浩
13 | */
14 | public interface ActiveTracerSpan {
15 |
16 |
17 | /**
18 | * 添加在栈头部
19 | *
20 | * @param sofaTracerSpan
21 | */
22 | void addFirst(SofaTracerSpan sofaTracerSpan);
23 |
24 |
25 | /**
26 | * 当前线程执行长度
27 | *
28 | * @return : java.lang.Integer
29 | * @author 江浩
30 | */
31 | Integer size();
32 |
33 | /**
34 | * 最后一个提交的,LIFO 原则
35 | *
36 | * @return : com.alipay.common.tracer.core.span.SofaTracerSpan
37 | * @author 江浩
38 | */
39 | SofaTracerSpan peekFirst();
40 |
41 | /**
42 | * 停止最后一个提交信息
43 | *
44 | * @return : com.alipay.common.tracer.core.span.SofaTracerSpan
45 | * @author 江浩
46 | */
47 | SofaTracerSpan pollFirst();
48 | }
49 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/context/ApplicationContext.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.context;
2 |
3 | /**
4 | * 初始容器环境
5 | * @author 江浩
6 | */
7 | public interface ApplicationContext {
8 |
9 | /**
10 | * 容器启动
11 | * @return : void
12 | * @author 江浩
13 | */
14 | void start();
15 |
16 | /**
17 | * 容器关闭
18 | * @return : void
19 | * @author 江浩
20 | */
21 | void close();
22 | }
23 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/context/DefaultActiveTracerSpan.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.context;
2 |
3 | import com.alipay.common.tracer.core.span.SofaTracerSpan;
4 | import com.google.common.collect.Lists;
5 |
6 | import java.util.LinkedList;
7 | import java.util.Objects;
8 |
9 | /**
10 | * 线程默认活跃span 的实现
11 | *
12 | * @author 江浩
13 | */
14 | public class DefaultActiveTracerSpan implements ActiveTracerSpan {
15 |
16 | private LinkedList tracerSpans = Lists.newLinkedList();
17 |
18 |
19 | @Override
20 | public void addFirst(SofaTracerSpan sofaTracerSpan) {
21 | if (!Objects.isNull(sofaTracerSpan)) {
22 | tracerSpans.addFirst(sofaTracerSpan);
23 | }
24 | }
25 |
26 | @Override
27 | public Integer size() {
28 | return tracerSpans.size();
29 | }
30 |
31 | @Override
32 | public SofaTracerSpan peekFirst() {
33 | return tracerSpans.getFirst();
34 | }
35 |
36 | @Override
37 | public SofaTracerSpan pollFirst() {
38 | return tracerSpans.removeFirst();
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/context/DefaultApplicationContext.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.context;
2 |
3 | import cn.bytes1024.hound.collect.processor.Processor;
4 | import cn.bytes1024.hound.commons.option.ConfigOption;
5 | import cn.bytes1024.hound.commons.util.ThreadPoolUtils;
6 | import lombok.extern.slf4j.Slf4j;
7 | import org.apache.commons.collections.CollectionUtils;
8 |
9 | import java.util.List;
10 | import java.util.concurrent.CountDownLatch;
11 | import java.util.concurrent.ThreadPoolExecutor;
12 | import java.util.concurrent.TimeUnit;
13 |
14 | /**
15 | * 默认容器环境
16 | *
17 | * @author 江浩
18 | */
19 | @Slf4j
20 | public class DefaultApplicationContext implements ApplicationContext {
21 |
22 | private ConfigOption configOption;
23 |
24 | private List processors;
25 |
26 | private ThreadPoolExecutor poolExecutor = ThreadPoolUtils.newFixedThreadPool(3, DefaultApplicationContext.class.getName());
27 |
28 | public DefaultApplicationContext(ConfigOption configOption,
29 | List processors) {
30 | this.configOption = configOption;
31 | this.processors = processors;
32 | }
33 |
34 | @Override
35 | public void start() {
36 |
37 | if (CollectionUtils.isNotEmpty(processors)) {
38 |
39 | CountDownLatch countDownLatch = new CountDownLatch(this.processors.size());
40 |
41 | processors.forEach(handler -> poolExecutor.execute(() -> {
42 | try {
43 | handler.start(configOption, countDownLatch);
44 | } catch (Exception e) {
45 | e.printStackTrace();
46 | }
47 | }));
48 |
49 | try {
50 | countDownLatch.await(60, TimeUnit.SECONDS);
51 | } catch (InterruptedException e) {
52 | log.error("handler start error : {}", e);
53 | this.close();
54 | }
55 | }
56 |
57 | }
58 |
59 | @Override
60 | public void close() {
61 | if (CollectionUtils.isNotEmpty(processors)) {
62 | processors.forEach(Processor::destroy);
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/context/DefaultReporter.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.context;
2 |
3 | import cn.bytes1024.hound.commons.option.ConfigOption;
4 | import cn.bytes1024.hound.commons.option.ConfigOptionDefine;
5 | import cn.bytes1024.hound.transfers.define.DefineTransmitContent;
6 | import cn.bytes1024.hound.transfers.define.TransferDefine;
7 | import cn.bytes1024.hound.transfers.define.TransmitTraceContent;
8 | import cn.bytes1024.hound.transfers.define.buffer.NotifyListener;
9 | import cn.bytes1024.hound.transfers.define.buffer.TransferBuffer;
10 | import com.alipay.common.tracer.core.context.span.SofaTracerSpanContext;
11 | import com.alipay.common.tracer.core.reporter.facade.Reporter;
12 | import com.alipay.common.tracer.core.span.SofaTracerSpan;
13 | import lombok.extern.slf4j.Slf4j;
14 |
15 | import java.util.Objects;
16 |
17 | /**
18 | * 默认的上报器
19 | *
20 | * 1.上报器目前结合 {@link TransferBuffer} {@link NotifyListener} 使用
21 | *
22 | *
23 | * @author 江浩
24 | */
25 | @Slf4j
26 | public class DefaultReporter implements Reporter, NotifyListener {
27 |
28 | private TransferDefine transferDefine;
29 |
30 | private TransferBuffer transferBuffer;
31 |
32 | private ConfigOption configOption;
33 |
34 | public DefaultReporter(TransferDefine transferDefine, TransferBuffer transferBuffer, ConfigOption configOption) {
35 | this.transferDefine = transferDefine;
36 | this.transferBuffer = transferBuffer;
37 | this.configOption = configOption;
38 | if (Objects.nonNull(this.transferBuffer)) {
39 | log.info("缓冲器启动....");
40 | this.transferBuffer.register(this);
41 | }
42 | }
43 |
44 | @Override
45 | public String getReporterType() {
46 | return null;
47 | }
48 |
49 | @Override
50 | public void report(SofaTracerSpan sofaTracerSpan) {
51 |
52 | if (Objects.isNull(sofaTracerSpan)) {
53 | return;
54 | }
55 |
56 | SofaTracerSpanContext sofaTracerSpanContext = sofaTracerSpan.getSofaTracerSpanContext();
57 |
58 | TransmitTraceContent transmitTraceContent = new TransmitTraceContent()
59 | .setOperationName(sofaTracerSpan.getOperationName())
60 | .setTraceId(sofaTracerSpanContext.getTraceId())
61 | .setParentId(sofaTracerSpanContext.getParentId())
62 | .setSpanId(sofaTracerSpanContext.getSpanId())
63 | .setBizBaggage(sofaTracerSpanContext.getBizBaggage())
64 | .setSysBaggage(sofaTracerSpanContext.getSysBaggage())
65 | .setStartTime(sofaTracerSpan.getStartTime())
66 | .setEndTime(sofaTracerSpan.getEndTime())
67 | .setSampled(sofaTracerSpanContext.isSampled());
68 |
69 | if (ConfigOptionDefine.isOpenTransmitContentView(configOption)) {
70 | log.info("{}", transmitTraceContent);
71 | }
72 | if (Objects.nonNull(transferBuffer)) {
73 | this.transferBuffer.push(transmitTraceContent);
74 | }
75 | }
76 |
77 | @Override
78 | public void close() {
79 |
80 | }
81 |
82 | @Override
83 | public void notify(T message) {
84 | if (!Objects.isNull(transferDefine)) {
85 | this.transferDefine.transmit(configOption, message);
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/context/DefaultTraceContext.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.context;
2 |
3 | import cn.bytes1024.hound.commons.util.NamedThreadLocal;
4 | import cn.bytes1024.hound.plugins.define.InterceptContext;
5 | import cn.bytes1024.hound.plugins.define.TraceContext;
6 | import cn.bytes1024.hound.plugins.define.filter.TraceContextFilterOption;
7 | import com.alipay.common.tracer.core.SofaTracer;
8 | import com.alipay.common.tracer.core.context.span.SofaTracerSpanContext;
9 | import com.alipay.common.tracer.core.context.trace.SofaTracerThreadLocalTraceContext;
10 | import com.alipay.common.tracer.core.span.SofaTracerSpan;
11 | import lombok.Getter;
12 | import lombok.extern.slf4j.Slf4j;
13 |
14 | import java.util.EmptyStackException;
15 | import java.util.Objects;
16 |
17 | /**
18 | * 默认的追踪上线文
19 | *
20 | * @author 江浩
21 | */
22 | @Getter
23 | @Slf4j
24 | public class DefaultTraceContext extends SofaTracerThreadLocalTraceContext implements TraceContext, TraceContextFilterOption {
25 |
26 |
27 | private SofaTracer sofaTracer;
28 |
29 | /**
30 | * 当前线程中活跃的span信息
31 | *
32 | * @author 江浩
33 | */
34 | private final NamedThreadLocal activeTracerSpans = new NamedThreadLocal<>("activeTracerSpans");
35 |
36 | private TraceContextFilterOption traceContextFilterOption;
37 |
38 | public DefaultTraceContext(SofaTracer sofaTracer, TraceContextFilterOption traceContextFilterOption) {
39 | this.sofaTracer = sofaTracer;
40 | this.traceContextFilterOption = traceContextFilterOption;
41 | }
42 |
43 | @Override
44 | public SofaTracer getSofaTracer() {
45 | return this.sofaTracer;
46 | }
47 |
48 |
49 | @Override
50 | public SofaTracerSpan stopCurrentTracerSpan(InterceptContext interceptContext) {
51 | SofaTracerSpan sofaTracerSpan = this.pop();
52 | if (Objects.isNull(sofaTracerSpan)) {
53 | return null;
54 | }
55 |
56 | SofaTracerSpanContext sofaTracerSpanContext = sofaTracerSpan.getSofaTracerSpanContext();
57 |
58 | this.filterOption(sofaTracerSpanContext, interceptContext);
59 |
60 | sofaTracerSpanContext.addBizBaggage(interceptContext.getProps());
61 | sofaTracerSpan.finish();
62 |
63 | return sofaTracerSpan;
64 | }
65 |
66 |
67 | @Override
68 | public void push(SofaTracerSpan span) {
69 | if (span == null) {
70 | return;
71 | }
72 | //当前线程
73 | ActiveTracerSpan activeTracerSpan = activeTracerSpans.get();
74 | if (Objects.isNull(activeTracerSpan)) {
75 | activeTracerSpan = new DefaultActiveTracerSpan();
76 | activeTracerSpans.set(activeTracerSpan);
77 | }
78 | activeTracerSpan.addFirst(span);
79 | }
80 |
81 | @Override
82 | public SofaTracerSpan getCurrentSpan() throws EmptyStackException {
83 | if (this.isEmpty()) {
84 | return null;
85 | }
86 |
87 | ActiveTracerSpan activeTracerSpan = activeTracerSpans.get();
88 | if (Objects.isNull(activeTracerSpan)) {
89 | return null;
90 | }
91 | return activeTracerSpan.peekFirst();
92 | }
93 |
94 | @Override
95 | public SofaTracerSpan pop() throws EmptyStackException {
96 | if (this.isEmpty()) {
97 | return null;
98 | }
99 | ActiveTracerSpan activeTracerSpan = activeTracerSpans.get();
100 | if (Objects.isNull(activeTracerSpan)) {
101 | return null;
102 | }
103 |
104 | SofaTracerSpan sofaTracerSpan = activeTracerSpan.pollFirst();
105 | if (activeTracerSpan.size() <= 0) {
106 | activeTracerSpans.remove();
107 | }
108 | return sofaTracerSpan;
109 | }
110 |
111 | @Override
112 | public int getThreadLocalSpanSize() {
113 | ActiveTracerSpan activeTracerSpan = activeTracerSpans.get();
114 | return activeTracerSpan == null ? 0 : activeTracerSpan.size();
115 | }
116 |
117 | @Override
118 | public boolean isEmpty() {
119 | ActiveTracerSpan activeTracerSpan = activeTracerSpans.get();
120 | return activeTracerSpan == null || activeTracerSpan.size() <= 0;
121 | }
122 |
123 | @Override
124 | public void clear() {
125 | activeTracerSpans.remove();
126 | }
127 |
128 |
129 | @Override
130 | public void filterOption(SofaTracerSpanContext sofaTracerSpanContext, InterceptContext interceptContext) {
131 | this.traceContextFilterOption.filterOption(sofaTracerSpanContext, interceptContext);
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/enhance/DefaultEnhanceFactory.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.enhance;
2 |
3 | import cn.bytes1024.hound.collect.enhance.rule.DefaultEnhanceRuleChain;
4 | import cn.bytes1024.hound.collect.enhance.rule.EnhanceRule;
5 | import cn.bytes1024.hound.plugins.define.EnhanceContext;
6 | import lombok.extern.slf4j.Slf4j;
7 | import net.bytebuddy.dynamic.DynamicType;
8 | import org.apache.commons.collections.CollectionUtils;
9 |
10 | import java.util.List;
11 |
12 | /**
13 | * 默认method delegation构建工厂
14 | *
15 | * @author
16 | */
17 | @Slf4j
18 | public class DefaultEnhanceFactory implements EnhanceFactory {
19 |
20 |
21 | private List enhanceRules;
22 |
23 | private InterceptorFactory interceptorFactory;
24 |
25 |
26 | public DefaultEnhanceFactory(List enhanceRules, InterceptorFactory interceptorFactory) {
27 | this.enhanceRules = enhanceRules;
28 | this.interceptorFactory = interceptorFactory;
29 | }
30 |
31 |
32 | private DynamicType.Builder> enhance(DynamicType.Builder> builder, EnhanceContext enhanceContext) {
33 | return new DefaultEnhanceRuleChain(this.enhanceRules).enhance(builder, new DefaultEnhanceRuleOption(enhanceContext, this.interceptorFactory));
34 | }
35 |
36 | /**
37 | * 增强处理
38 | *
39 | * @param builder :
40 | * @param enhanceContexts :
41 | * @param index :
42 | * @return : net.bytebuddy.dynamic.DynamicType.Builder>
43 | * @author 江浩
44 | */
45 | private DynamicType.Builder> enhance(DynamicType.Builder> builder, List enhanceContexts, int index) {
46 | //#to long bug ?
47 | if (CollectionUtils.isEmpty(enhanceContexts) || index >= enhanceContexts.size()) {
48 | return builder;
49 | }
50 | EnhanceContext enhanceContext = enhanceContexts.get(index);
51 | builder = this.enhance(builder, enhanceContext);
52 | return enhance(builder, enhanceContexts, ++index);
53 | }
54 |
55 | @Override
56 | public DynamicType.Builder> enhance(DynamicType.Builder> builder, List enhanceContexts) {
57 |
58 | return this.enhance(builder, enhanceContexts, 0);
59 | }
60 |
61 |
62 | /**
63 | * callback
64 | */
65 | public static class DefaultEnhanceRuleOption implements EnhanceRule.EnhanceRuleOption {
66 |
67 | private InterceptorFactory interceptorFactory;
68 |
69 | private EnhanceContext enhanceContext;
70 |
71 |
72 | public DefaultEnhanceRuleOption(EnhanceContext enhanceContext,
73 | InterceptorFactory interceptorFactory) {
74 | this.interceptorFactory = interceptorFactory;
75 | this.enhanceContext = enhanceContext;
76 | }
77 |
78 | @Override
79 | public InterceptorFactory getInterceptorFactory() {
80 | return this.interceptorFactory;
81 | }
82 |
83 | @Override
84 | public EnhanceContext getEnhanceContext() {
85 | return this.enhanceContext;
86 | }
87 |
88 |
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/enhance/DefaultEnhanceRuleChainProxy.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.enhance;
2 |
3 | import cn.bytes1024.hound.collect.enhance.rule.DefaultEnhanceRuleChain;
4 | import cn.bytes1024.hound.collect.enhance.rule.EnhanceRule;
5 | import cn.bytes1024.hound.collect.enhance.rule.EnhanceRuleChain;
6 | import cn.bytes1024.hound.plugins.define.EnhanceContext;
7 | import lombok.extern.slf4j.Slf4j;
8 | import net.bytebuddy.dynamic.DynamicType;
9 | import org.apache.commons.collections.CollectionUtils;
10 |
11 | import java.util.List;
12 |
13 | /**
14 | * 增强链路代理
15 | *
16 | * @author
17 | */
18 | @Slf4j
19 | public class DefaultEnhanceRuleChainProxy implements EnhanceRuleChainProxy, EnhanceRuleChain {
20 |
21 |
22 | private List enhanceRules;
23 |
24 | private InterceptorFactory interceptorFactory;
25 |
26 | public DefaultEnhanceRuleChainProxy(List enhanceRules, InterceptorFactory interceptorFactory) {
27 | this.enhanceRules = enhanceRules;
28 | this.interceptorFactory = interceptorFactory;
29 | }
30 |
31 |
32 | private DynamicType.Builder> enhance(DynamicType.Builder> builder, EnhanceContext enhanceContext) {
33 | return this.enhance(builder, new DefaultEnhanceRuleOption(enhanceContext, this.interceptorFactory));
34 | }
35 |
36 | /**
37 | * 增强处理
38 | *
39 | * @param builder :
40 | * @param enhanceContexts :
41 | * @param index :
42 | * @return : net.bytebuddy.dynamic.DynamicType.Builder>
43 | * @author 江浩
44 | */
45 | private DynamicType.Builder> enhance(DynamicType.Builder> builder, List enhanceContexts, int index) {
46 | //#to long bug ?
47 | if (CollectionUtils.isEmpty(enhanceContexts) || index >= enhanceContexts.size()) {
48 | return builder;
49 | }
50 | EnhanceContext enhanceContext = enhanceContexts.get(index);
51 | builder = this.enhance(builder, enhanceContext);
52 | return enhance(builder, enhanceContexts, ++index);
53 | }
54 |
55 | @Override
56 | public DynamicType.Builder> enhance(DynamicType.Builder> builder, List enhanceContexts) {
57 |
58 | return this.enhance(builder, enhanceContexts, 0);
59 | }
60 |
61 | @Override
62 | public DynamicType.Builder> enhance(DynamicType.Builder> builder, EnhanceRule.EnhanceRuleOption enhanceRuleOption) {
63 | return new DefaultEnhanceRuleChain(this.enhanceRules).enhance(builder, enhanceRuleOption);
64 | }
65 |
66 |
67 | /**
68 | * callback
69 | */
70 | public static class DefaultEnhanceRuleOption implements EnhanceRule.EnhanceRuleOption {
71 |
72 | private InterceptorFactory interceptorFactory;
73 |
74 | private EnhanceContext enhanceContext;
75 |
76 | public DefaultEnhanceRuleOption(EnhanceContext enhanceContext,
77 | InterceptorFactory interceptorFactory) {
78 | this.interceptorFactory = interceptorFactory;
79 | this.enhanceContext = enhanceContext;
80 | }
81 |
82 | @Override
83 | public InterceptorFactory getInterceptorFactory() {
84 | return this.interceptorFactory;
85 | }
86 |
87 | @Override
88 | public EnhanceContext getEnhanceContext() {
89 | return this.enhanceContext;
90 | }
91 |
92 |
93 | }
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/enhance/DefaultInterceptorFactory.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.enhance;
2 |
3 | import cn.bytes1024.hound.collect.exception.ConstructorException;
4 | import cn.bytes1024.hound.plugins.define.EnhanceContext;
5 | import cn.bytes1024.hound.plugins.define.TraceContext;
6 | import cn.bytes1024.hound.plugins.define.interceptor.InterceptorPluginAware;
7 | import lombok.extern.slf4j.Slf4j;
8 | import org.apache.commons.lang3.ClassUtils;
9 |
10 | import java.lang.reflect.Constructor;
11 | import java.lang.reflect.Method;
12 | import java.util.Objects;
13 |
14 | /**
15 | * 默认拦截器处理
16 | *
17 | * @author 江浩
18 | */
19 | @Slf4j
20 | public class DefaultInterceptorFactory implements InterceptorFactory {
21 |
22 | private TraceContext traceContext;
23 |
24 | public DefaultInterceptorFactory(TraceContext traceContext) {
25 | this.traceContext = traceContext;
26 | }
27 |
28 | @Override
29 | public Object newInterceptorObject(EnhanceContext enhanceContext) {
30 |
31 | final String interceptorClassName = enhanceContext.getInterceptorClassName();
32 | final String pluginName = enhanceContext.getRefPluginName();
33 | try {
34 | Class> aClass = ClassUtils.getClass(interceptorClassName);
35 | Object object = null;
36 | try {
37 | Constructor> constructor = aClass.getDeclaredConstructor(TraceContext.class);
38 | object = constructor.newInstance(this.traceContext);
39 | invokeMethod(pluginName, aClass, object);
40 |
41 | } catch (NoSuchMethodException ignored) {
42 | }
43 | if (Objects.isNull(object)) {
44 | throw builder(interceptorClassName);
45 | }
46 |
47 | return object;
48 | } catch (Exception e) {
49 | throw builder(interceptorClassName);
50 | }
51 | }
52 |
53 | /**
54 | * invoker {@link InterceptorPluginAware#defineName(String)}
55 | *
56 | * @param pluginName :
57 | * @param aClass :
58 | * @param object :
59 | * @return : void
60 | * @author 江浩
61 | */
62 | private void invokeMethod(String pluginName, Class> aClass, Object object) {
63 |
64 | if (InterceptorPluginAware.class.isAssignableFrom(aClass)) {
65 | try {
66 | Method method = aClass.getMethod("defineName", String.class);
67 | method.invoke(object, pluginName);
68 | } catch (Exception ignored) {
69 | }
70 | }
71 | }
72 |
73 | private ConstructorException builder(String className) {
74 | return new ConstructorException(String.format("AroundInterceptor Constructor format: %s",
75 | className + "(com.support.monitor.agent.core.context.trace.TraceContext arg0)"));
76 | }
77 |
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/enhance/EnhanceFactory.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.enhance;
2 |
3 | import cn.bytes1024.hound.plugins.define.EnhanceContext;
4 | import net.bytebuddy.dynamic.DynamicType;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * 增强实现工厂
10 | *
11 | * @author 江浩
12 | */
13 | public interface EnhanceFactory {
14 |
15 | /**
16 | * 增强实现
17 | * @param builder :
18 | * @param enhanceContexts :
19 | * @return : net.bytebuddy.dynamic.DynamicType.Builder>
20 | * @author 江浩
21 | */
22 | DynamicType.Builder> enhance(DynamicType.Builder> builder, List enhanceContexts);
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/enhance/EnhanceRuleChainProxy.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.enhance;
2 |
3 | import cn.bytes1024.hound.collect.enhance.rule.EnhanceRule;
4 | import cn.bytes1024.hound.plugins.define.EnhanceContext;
5 | import net.bytebuddy.dynamic.DynamicType;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * 增强规则链路代理
11 | *
12 | * 1.该代理实现最终只会执行{@link cn.bytes1024.hound.collect.enhance.rule.EnhanceRuleChain#enhance(DynamicType.Builder, EnhanceRule.EnhanceRuleOption)}
13 | *
14 | *
15 | * @author 江浩
16 | */
17 | public interface EnhanceRuleChainProxy {
18 |
19 | /**
20 | * 增强实现
21 | *
22 | * @param builder :
23 | * @param enhanceContexts :
24 | * @return : net.bytebuddy.dynamic.DynamicType.Builder>
25 | * @author 江浩
26 | */
27 | DynamicType.Builder> enhance(DynamicType.Builder> builder, List enhanceContexts);
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/enhance/InterceptorFactory.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.enhance;
2 |
3 |
4 | import cn.bytes1024.hound.plugins.define.EnhanceContext;
5 |
6 | /**
7 | * @author admin
8 | */
9 | public interface InterceptorFactory {
10 |
11 |
12 | /**
13 | * 创建拦截器实体
14 | *
15 | * @param className :
16 | * @return : java.lang.Object
17 | * @author 江浩
18 | */
19 | Object newInterceptorObject(EnhanceContext className);
20 |
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/enhance/delegation/ConstructorInterceptDelegation.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.enhance.delegation;
2 |
3 | import cn.bytes1024.hound.plugins.define.EnhancedDefine;
4 | import cn.bytes1024.hound.plugins.define.interceptor.ConstructorInterceptor;
5 | import lombok.extern.slf4j.Slf4j;
6 | import net.bytebuddy.implementation.bind.annotation.AllArguments;
7 | import net.bytebuddy.implementation.bind.annotation.RuntimeType;
8 | import net.bytebuddy.implementation.bind.annotation.This;
9 |
10 | /**
11 | * @author 江浩
12 | */
13 | @Slf4j
14 | public class ConstructorInterceptDelegation {
15 |
16 | private ConstructorInterceptor constructorInterceptor;
17 |
18 | public ConstructorInterceptDelegation(ConstructorInterceptor constructorInterceptor) {
19 | this.constructorInterceptor = constructorInterceptor;
20 | }
21 |
22 | @RuntimeType
23 | public void intercept(@This Object obj,
24 | @AllArguments Object[] allArguments) {
25 | try {
26 | EnhancedDefine targetObject = (EnhancedDefine) obj;
27 | constructorInterceptor.onConstruct(targetObject, allArguments);
28 | } catch (Throwable t) {
29 | log.error("ConstructorInter failure.", t);
30 | }
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/enhance/delegation/MethodsInterceptWithDelegation.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.enhance.delegation;
2 |
3 | import cn.bytes1024.hound.plugins.define.InterceptContext;
4 | import cn.bytes1024.hound.plugins.define.interceptor.MethodAroundInterceptor;
5 | import lombok.extern.slf4j.Slf4j;
6 | import net.bytebuddy.implementation.bind.annotation.*;
7 |
8 | import java.lang.reflect.Method;
9 | import java.util.concurrent.Callable;
10 |
11 | /**
12 | * 方法拦截
13 | *
14 | * @author 江浩
15 | */
16 | @Slf4j
17 | public class MethodsInterceptWithDelegation {
18 |
19 | private MethodAroundInterceptor methodAroundInterceptor;
20 |
21 | public MethodsInterceptWithDelegation(MethodAroundInterceptor methodAroundInterceptor) {
22 | this.methodAroundInterceptor = methodAroundInterceptor;
23 | }
24 |
25 | @RuntimeType
26 | public Object intercept(
27 | @This Object object,
28 | @AllArguments Object[] allArguments,
29 | @SuperCall Callable> callable,
30 | @Origin Method method) {
31 |
32 | Object result = null;
33 | Throwable throwable = null;
34 | InterceptContext interceptContext = InterceptContext.builder()
35 | .target(object)
36 | .method(method)
37 | .args(allArguments)
38 | .build();
39 | try {
40 | methodAroundInterceptor.before(interceptContext);
41 | result = callable.call();
42 | } catch (Exception e) {
43 | throwable = e;
44 | } finally {
45 | interceptContext.setResult(result);
46 | interceptContext.setThrowable(throwable);
47 | methodAroundInterceptor.after(interceptContext);
48 | }
49 |
50 | return result;
51 | }
52 |
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/enhance/rule/AbstractEnhanceRule.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.enhance.rule;
2 |
3 | import cn.bytes1024.hound.collect.enhance.InterceptorFactory;
4 | import cn.bytes1024.hound.commons.util.RefClassUtil;
5 | import cn.bytes1024.hound.plugins.define.EnhanceContext;
6 | import lombok.extern.slf4j.Slf4j;
7 | import net.bytebuddy.dynamic.DynamicType;
8 |
9 | import java.util.Objects;
10 |
11 | /**
12 | * 增强链路默认增强对象应该参与所有的增强方式
13 | *
14 | * 具体是否增强应该由子类自行判断
15 | *
16 | *
17 | * @author 江浩
18 | */
19 | @Slf4j
20 | public abstract class AbstractEnhanceRule implements EnhanceRule {
21 |
22 | private Class rClass;
23 |
24 |
25 | public AbstractEnhanceRule() {
26 | rClass = RefClassUtil.getSuperClassGenricType(this.getClass(), 0);
27 | }
28 |
29 | @Override
30 | public DynamicType.Builder> enhance(EnhanceRuleChain chan, DynamicType.Builder> builder, EnhanceRuleOption enhanceRuleOption) {
31 | if (Objects.isNull(enhanceRuleOption)) {
32 | return builder;
33 | }
34 |
35 | try {
36 | InterceptorFactory interceptorFactory = enhanceRuleOption.getInterceptorFactory();
37 | EnhanceContext enhanceContext = enhanceRuleOption.getEnhanceContext();
38 |
39 | Object object = interceptorFactory.newInterceptorObject(enhanceContext);
40 |
41 | if (rClass.isAssignableFrom(object.getClass()) || need()) {
42 | DynamicType.Builder> newBuilder = this.enhanceDefine(builder, (R) object, enhanceContext);
43 | if (!Objects.isNull(newBuilder)) {
44 | builder = newBuilder;
45 | }
46 | }
47 | } catch (Exception e) {
48 | log.error("enhance error : {}", e);
49 | }
50 |
51 | return chan.enhance(builder, enhanceRuleOption);
52 | }
53 |
54 | /**
55 | * 默认增强方式
56 | *
57 | * @param builder :
58 | * @param interceptPoint
59 | * @param enhanceContext :
60 | * @return : net.bytebuddy.dynamic.DynamicType.Builder>
61 | * @author 江浩
62 | */
63 | protected abstract DynamicType.Builder> enhanceDefine(DynamicType.Builder> builder, R interceptPoint, EnhanceContext enhanceContext);
64 | }
65 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/enhance/rule/DefaultEnhanceRuleChain.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.enhance.rule;
2 |
3 | import net.bytebuddy.dynamic.DynamicType;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * 默认增强实现链路
9 | *
10 | * @author 江浩
11 | */
12 | public class DefaultEnhanceRuleChain implements EnhanceRuleChain {
13 |
14 | private int index;
15 | private List enhanceRules;
16 |
17 | public DefaultEnhanceRuleChain(List enhanceRules) {
18 | this.enhanceRules = enhanceRules;
19 | }
20 |
21 | public DefaultEnhanceRuleChain(DefaultEnhanceRuleChain parent, int index) {
22 | this.enhanceRules = parent.enhanceRules;
23 | this.index = index;
24 | }
25 |
26 |
27 | private DefaultEnhanceRuleChain chan() {
28 | return new DefaultEnhanceRuleChain(this, this.index + 1);
29 | }
30 |
31 |
32 | @Override
33 | public DynamicType.Builder> enhance(DynamicType.Builder> builder, EnhanceRule.EnhanceRuleOption enhanceRuleOption) {
34 | if (index < this.enhanceRules.size()) {
35 | return this.enhanceRules.get(index).enhance(chan(), builder, enhanceRuleOption);
36 | }
37 | //default builder
38 | return builder;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/enhance/rule/EnhanceConstructorRule.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.enhance.rule;
2 |
3 | import cn.bytes1024.hound.collect.enhance.delegation.ConstructorInterceptDelegation;
4 | import cn.bytes1024.hound.plugins.define.EnhanceContext;
5 | import cn.bytes1024.hound.plugins.define.interceptor.ConstructorInterceptor;
6 | import net.bytebuddy.dynamic.DynamicType;
7 | import net.bytebuddy.implementation.MethodDelegation;
8 | import net.bytebuddy.implementation.SuperMethodCall;
9 |
10 | /**
11 | * 构造器增强
12 | *
13 | * @author 江浩
14 | */
15 | public class EnhanceConstructorRule extends AbstractEnhanceRule {
16 |
17 | @Override
18 | protected DynamicType.Builder> enhanceDefine(DynamicType.Builder> builder, ConstructorInterceptor interceptPoint, EnhanceContext enhanceContext) {
19 |
20 | MethodDelegation methodDelegation = constructorDelegation(interceptPoint);
21 | return builder.constructor(enhanceContext.getMethodDescription()).intercept(SuperMethodCall.INSTANCE
22 | .andThen(methodDelegation)
23 | );
24 | }
25 |
26 | private MethodDelegation constructorDelegation(ConstructorInterceptor constructorInterceptor) {
27 | return
28 | MethodDelegation.withDefaultConfiguration()
29 | .to(new ConstructorInterceptDelegation(constructorInterceptor));
30 | }
31 |
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/enhance/rule/EnhanceMethodRule.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.enhance.rule;
2 |
3 | import cn.bytes1024.hound.collect.enhance.delegation.MethodsInterceptWithDelegation;
4 | import cn.bytes1024.hound.plugins.define.EnhanceContext;
5 | import cn.bytes1024.hound.plugins.define.interceptor.MethodAroundInterceptor;
6 | import net.bytebuddy.dynamic.DynamicType;
7 | import net.bytebuddy.implementation.MethodDelegation;
8 | import net.bytebuddy.matcher.ElementMatchers;
9 |
10 | import static net.bytebuddy.matcher.ElementMatchers.isStatic;
11 |
12 | /**
13 | * 方法增强的处理方式
14 | *
15 | * @author 江浩
16 | */
17 | public class EnhanceMethodRule extends AbstractEnhanceRule {
18 |
19 |
20 | @Override
21 | protected DynamicType.Builder> enhanceDefine(DynamicType.Builder> builder, MethodAroundInterceptor
22 | interceptPoint, EnhanceContext enhanceContext) {
23 | MethodDelegation methodDelegation = methodsWithDelegation(interceptPoint);
24 | return builder.method(ElementMatchers.not(isStatic()).and(enhanceContext.getMethodDescription())).intercept(methodDelegation);
25 |
26 | }
27 |
28 | /**
29 | * 方法委托处理
30 | *
31 | * @param methodsAroundInterceptor :
32 | * @return : net.bytebuddy.implementation.MethodDelegation
33 | * @author 江浩
34 | */
35 | private MethodDelegation methodsWithDelegation(MethodAroundInterceptor methodsAroundInterceptor) {
36 | return MethodDelegation.withDefaultConfiguration()
37 | // .withBinders(
38 | // Morph.Binder.install(DefaultCallable.class)
39 | // )
40 | .to(new MethodsInterceptWithDelegation(methodsAroundInterceptor));
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/enhance/rule/EnhanceRule.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.enhance.rule;
2 |
3 | import cn.bytes1024.hound.collect.enhance.InterceptorFactory;
4 | import cn.bytes1024.hound.plugins.define.EnhanceContext;
5 | import net.bytebuddy.dynamic.DynamicType;
6 |
7 | /**
8 | * 规则信息
9 | *
10 | * @author 江浩
11 | */
12 | public interface EnhanceRule {
13 |
14 |
15 | /**
16 | * 标识
17 | *
18 | * @author 江浩
19 | */
20 | class Key {
21 | public static final String SOURCE = "source";
22 | public static final String METHOD = "method";
23 | public static final String CONSTRUCTOR = "constructor";
24 | public static final String STATIC_METHOD = "static_method";
25 | }
26 |
27 | /**
28 | * 增强规则执行设置信息
29 | *
30 | * @author 江浩
31 | */
32 | interface EnhanceRuleOption {
33 |
34 | /**
35 | * 拦截器工厂
36 | *
37 | * @return : cn.bytes1024.hound.collect.enhance.InterceptorFactory
38 | * @author 江浩
39 | */
40 | InterceptorFactory getInterceptorFactory();
41 |
42 | /**
43 | * 获取增强上线文环境
44 | *
45 | * @return : cn.bytes1024.hound.plugins.define.EnhanceContext
46 | * @author 江浩
47 | */
48 | EnhanceContext getEnhanceContext();
49 |
50 | }
51 |
52 |
53 | /**
54 | * 增强规则实现
55 | *
56 | * @param chan :
57 | * @param builder
58 | * @param enhanceRuleOption :
59 | * @return : net.bytebuddy.dynamic.DynamicType.Builder>
60 | * @author 江浩
61 | */
62 | DynamicType.Builder> enhance(EnhanceRuleChain chan,
63 | DynamicType.Builder> builder,
64 | EnhanceRuleOption enhanceRuleOption);
65 |
66 | /**
67 | * 过滤掉
68 | *
69 | * @return : boolean
70 | * @author 江浩
71 | */
72 | default boolean need() {
73 | return false;
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/enhance/rule/EnhanceRuleChain.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.enhance.rule;
2 |
3 | import net.bytebuddy.dynamic.DynamicType;
4 |
5 | /**
6 | * @author 江浩
7 | */
8 | public interface EnhanceRuleChain {
9 |
10 | /**
11 | * 增强实现
12 | *
13 | * @param builder
14 | * @param enhanceRuleOption :
15 | * @return : net.bytebuddy.dynamic.DynamicType.Builder>
16 | * @author 江浩
17 | */
18 | DynamicType.Builder> enhance(DynamicType.Builder> builder, EnhanceRule.EnhanceRuleOption enhanceRuleOption);
19 | }
20 |
--------------------------------------------------------------------------------
/collect/src/main/java/cn/bytes1024/hound/collect/enhance/rule/EnhanceSourceRule.java:
--------------------------------------------------------------------------------
1 | package cn.bytes1024.hound.collect.enhance.rule;
2 |
3 | import cn.bytes1024.hound.plugins.define.EnhanceContext;
4 | import cn.bytes1024.hound.plugins.define.EnhancedDefine;
5 | import com.alipay.common.tracer.core.span.SofaTracerSpan;
6 | import net.bytebuddy.description.type.TypeList;
7 | import net.bytebuddy.dynamic.DynamicType;
8 | import net.bytebuddy.implementation.FieldAccessor;
9 |
10 | import java.util.Objects;
11 |
12 | import static net.bytebuddy.jar.asm.Opcodes.ACC_PRIVATE;
13 | import static net.bytebuddy.jar.asm.Opcodes.ACC_VOLATILE;
14 |
15 | /**
16 | * @author 江浩
17 | */
18 | public class EnhanceSourceRule extends AbstractEnhanceRule