Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
apache
SkyWalking
提交
a20d6ea2
S
SkyWalking
项目概览
apache
/
SkyWalking
上一次同步 大约 1 年
通知
302
Star
21345
Fork
6091
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
SkyWalking
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
a20d6ea2
编写于
10月 08, 2017
作者:
彭
彭勇升 Buddha
提交者:
GitHub
10月 08, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into feature/new-register-flow
上级
1f60db7e
8eed412b
变更
28
隐藏空白更改
内联
并排
Showing
28 changed file
with
1240 addition
and
49 deletion
+1240
-49
.gitignore
.gitignore
+1
-0
README.md
README.md
+1
-1
README_ZH.md
README_ZH.md
+1
-1
apm-network/src/main/java/org/skywalking/apm/network/trace/component/ComponentsDefine.java
...walking/apm/network/trace/component/ComponentsDefine.java
+7
-4
apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefine.java
...m/agent/core/plugin/AbstractClassEnhancePluginDefine.java
+4
-3
apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/EnhanceContext.java
.../org/skywalking/apm/agent/core/plugin/EnhanceContext.java
+34
-0
apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginFinder.java
...va/org/skywalking/apm/agent/core/plugin/PluginFinder.java
+12
-6
apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java
.../plugin/interceptor/enhance/ClassEnhancePluginDefine.java
+15
-7
apm-sniffer/apm-agent/pom.xml
apm-sniffer/apm-agent/pom.xml
+5
-0
apm-sniffer/apm-agent/src/main/java/org/skywalking/apm/agent/SkyWalkingAgent.java
...c/main/java/org/skywalking/apm/agent/SkyWalkingAgent.java
+15
-5
apm-sniffer/apm-sdk-plugin/pom.xml
apm-sniffer/apm-sdk-plugin/pom.xml
+1
-0
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/skywalking/apm/plugin/spring/mvc/AbstractMethodInteceptor.java
...lking/apm/plugin/spring/mvc/AbstractMethodInteceptor.java
+14
-19
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/skywalking/apm/plugin/spring/mvc/RequestMappingMethodInterceptor.java
...pm/plugin/spring/mvc/RequestMappingMethodInterceptor.java
+24
-0
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/skywalking/apm/plugin/spring/mvc/RestMappingMethodInterceptor.java
...g/apm/plugin/spring/mvc/RestMappingMethodInterceptor.java
+56
-0
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/skywalking/apm/plugin/spring/mvc/define/AbstractControllerInstrumentation.java
.../spring/mvc/define/AbstractControllerInstrumentation.java
+22
-3
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/test/java/org/skywalking/apm/plugin/spring/mvc/ControllerConstructorInterceptorTest.java
...ugin/spring/mvc/ControllerConstructorInterceptorTest.java
+107
-0
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/test/java/org/skywalking/apm/plugin/spring/mvc/PathMappingCacheTest.java
...kywalking/apm/plugin/spring/mvc/PathMappingCacheTest.java
+34
-0
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/test/java/org/skywalking/apm/plugin/spring/mvc/RequestMappingMethodInterceptorTest.java
...lugin/spring/mvc/RequestMappingMethodInterceptorTest.java
+157
-0
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/test/java/org/skywalking/apm/plugin/spring/mvc/RestMappingMethodInterceptorTest.java
...m/plugin/spring/mvc/RestMappingMethodInterceptorTest.java
+277
-0
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/test/java/org/skywalking/apm/plugin/spring/mvc/define/ControllerInstrumentationTest.java
...ugin/spring/mvc/define/ControllerInstrumentationTest.java
+62
-0
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/test/java/org/skywalking/apm/plugin/spring/mvc/define/RestControllerInstrumentationTest.java
.../spring/mvc/define/RestControllerInstrumentationTest.java
+45
-0
apm-sniffer/apm-sdk-plugin/spymemcached-2.x-plugin/pom.xml
apm-sniffer/apm-sdk-plugin/spymemcached-2.x-plugin/pom.xml
+35
-0
apm-sniffer/apm-sdk-plugin/spymemcached-2.x-plugin/src/main/java/org/skywalking/apm/plugin/spymemcached/v2/MemcachedConstructorWithInetSocketAddressListArgInterceptor.java
...edConstructorWithInetSocketAddressListArgInterceptor.java
+26
-0
apm-sniffer/apm-sdk-plugin/spymemcached-2.x-plugin/src/main/java/org/skywalking/apm/plugin/spymemcached/v2/MemcachedMethodInterceptor.java
...pm/plugin/spymemcached/v2/MemcachedMethodInterceptor.java
+42
-0
apm-sniffer/apm-sdk-plugin/spymemcached-2.x-plugin/src/main/java/org/skywalking/apm/plugin/spymemcached/v2/define/MemcachedInstrumentation.java
...ugin/spymemcached/v2/define/MemcachedInstrumentation.java
+82
-0
apm-sniffer/apm-sdk-plugin/spymemcached-2.x-plugin/src/main/resources/skywalking-plugin.def
...ached-2.x-plugin/src/main/resources/skywalking-plugin.def
+1
-0
apm-sniffer/apm-sdk-plugin/spymemcached-2.x-plugin/src/test/java/org/skywalking/apm/plugin/spymemcached/v2/MemcachedConstructorWithInetSocketAddressListArgInterceptorTest.java
...nstructorWithInetSocketAddressListArgInterceptorTest.java
+39
-0
apm-sniffer/apm-sdk-plugin/spymemcached-2.x-plugin/src/test/java/org/skywalking/apm/plugin/spymemcached/v2/MemcachedMethodInterceptorTest.java
...lugin/spymemcached/v2/MemcachedMethodInterceptorTest.java
+121
-0
未找到文件。
.gitignore
浏览文件 @
a20d6ea2
...
...
@@ -8,3 +8,4 @@ target/
.DS_Store
*~
packages/
**/dependency-reduced-pom.xml
README.md
浏览文件 @
a20d6ea2
...
...
@@ -59,7 +59,7 @@ This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDU
<img
src=
"https://sky-walking.github.io/page-resources/3.2.1/instance_health.png"
/>
-
JVM Detail.
<img
src=
"https://sky-walking.github.io/page-resources/3.2
.1
/instance_graph.png"
/>
<img
src=
"https://sky-walking.github.io/page-resources/3.2/instance_graph.png"
/>
-
Services Dependency Tree.
<img
src=
"https://sky-walking.github.io/page-resources/3.2.1/service_dependency_tree.png"
/>
...
...
README_ZH.md
浏览文件 @
a20d6ea2
...
...
@@ -60,7 +60,7 @@ This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDU
<img
src=
"https://sky-walking.github.io/page-resources/3.2.1/instance_health.png"
/>
-
JVM明细信息
<img
src=
"https://sky-walking.github.io/page-resources/3.2
.1
/instance_graph.png"
/>
<img
src=
"https://sky-walking.github.io/page-resources/3.2/instance_graph.png"
/>
-
服务依赖树.
<img
src=
"https://sky-walking.github.io/page-resources/3.2.1/service_dependency_tree.png"
/>
...
...
apm-network/src/main/java/org/skywalking/apm/network/trace/component/ComponentsDefine.java
浏览文件 @
a20d6ea2
...
...
@@ -43,8 +43,10 @@ public class ComponentsDefine {
public
static
final
OfficialComponent
JETTY_CLIENT
=
new
OfficialComponent
(
18
,
"JettyClient"
);
public
static
final
OfficialComponent
JETTY_SERVER
=
new
OfficialComponent
(
19
,
"JettyServer"
);
public
static
final
OfficialComponent
JETTY_SERVER
=
new
OfficialComponent
(
19
,
"JettyServer"
);
public
static
final
OfficialComponent
MEMCACHE
=
new
OfficialComponent
(
20
,
"Memcache"
);
private
static
ComponentsDefine
instance
=
new
ComponentsDefine
();
private
String
[]
components
;
...
...
@@ -54,7 +56,7 @@ public class ComponentsDefine {
}
public
ComponentsDefine
()
{
components
=
new
String
[
2
0
];
components
=
new
String
[
2
1
];
addComponent
(
TOMCAT
);
addComponent
(
HTTPCLIENT
);
addComponent
(
DUBBO
);
...
...
@@ -74,6 +76,7 @@ public class ComponentsDefine {
addComponent
(
NUTZ_HTTP
);
addComponent
(
JETTY_CLIENT
);
addComponent
(
JETTY_SERVER
);
addComponent
(
MEMCACHE
);
}
private
void
addComponent
(
OfficialComponent
component
)
{
...
...
@@ -87,4 +90,4 @@ public class ComponentsDefine {
return
components
[
componentId
];
}
}
}
}
\ No newline at end of file
apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefine.java
浏览文件 @
a20d6ea2
...
...
@@ -26,7 +26,7 @@ public abstract class AbstractClassEnhancePluginDefine {
* @throws PluginException, when set builder failure.
*/
public
DynamicType
.
Builder
<?>
define
(
String
transformClassName
,
DynamicType
.
Builder
<?>
builder
,
ClassLoader
classLoader
)
throws
PluginException
{
DynamicType
.
Builder
<?>
builder
,
ClassLoader
classLoader
,
EnhanceContext
context
)
throws
PluginException
{
String
interceptorDefineClassName
=
this
.
getClass
().
getName
();
if
(
StringUtil
.
isEmpty
(
transformClassName
))
{
...
...
@@ -53,15 +53,16 @@ public abstract class AbstractClassEnhancePluginDefine {
/**
* find origin class source code for interceptor
*/
DynamicType
.
Builder
<?>
newClassBuilder
=
this
.
enhance
(
transformClassName
,
builder
,
classLoader
);
DynamicType
.
Builder
<?>
newClassBuilder
=
this
.
enhance
(
transformClassName
,
builder
,
classLoader
,
context
);
context
.
initializationStageCompleted
();
logger
.
debug
(
"enhance class {} by {} completely."
,
transformClassName
,
interceptorDefineClassName
);
return
newClassBuilder
;
}
protected
abstract
DynamicType
.
Builder
<?>
enhance
(
String
enhanceOriginClassName
,
DynamicType
.
Builder
<?>
newClassBuilder
,
ClassLoader
classLoader
)
throws
PluginException
;
DynamicType
.
Builder
<?>
newClassBuilder
,
ClassLoader
classLoader
,
EnhanceContext
context
)
throws
PluginException
;
/**
* Define the {@link ClassMatch} for filtering class.
...
...
apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/EnhanceContext.java
0 → 100644
浏览文件 @
a20d6ea2
package
org.skywalking.apm.agent.core.plugin
;
/**
* The <code>EnhanceContext</code> represents the context or status for processing a class.
*
* Based on this context, the plugin core {@link org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassEnhancePluginDefine}
* knows how to process the specific steps for every particular plugin.
*
* @author wusheng
*/
public
class
EnhanceContext
{
private
boolean
isEnhanced
=
false
;
/**
* The object has already been enhanced or extended.
* e.g. added the new field, or implemented the new interface
*/
private
boolean
objectExtended
=
false
;
public
boolean
isEnhanced
()
{
return
isEnhanced
;
}
public
void
initializationStageCompleted
()
{
isEnhanced
=
true
;
}
public
boolean
isObjectExtended
()
{
return
objectExtended
;
}
public
void
extendObjectCompleted
()
{
objectExtended
=
true
;
}
}
apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginFinder.java
浏览文件 @
a20d6ea2
...
...
@@ -22,7 +22,7 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
* @author wusheng
*/
public
class
PluginFinder
{
private
final
Map
<
String
,
AbstractClassEnhancePluginDefine
>
nameMatchDefine
=
new
HashMap
<
String
,
AbstractClassEnhancePluginDefine
>();
private
final
Map
<
String
,
LinkedList
<
AbstractClassEnhancePluginDefine
>>
nameMatchDefine
=
new
HashMap
<
String
,
LinkedList
<
AbstractClassEnhancePluginDefine
>
>();
private
final
List
<
AbstractClassEnhancePluginDefine
>
signatureMatchDefine
=
new
LinkedList
<
AbstractClassEnhancePluginDefine
>();
public
PluginFinder
(
List
<
AbstractClassEnhancePluginDefine
>
plugins
)
{
...
...
@@ -35,28 +35,34 @@ public class PluginFinder {
if
(
match
instanceof
NameMatch
)
{
NameMatch
nameMatch
=
(
NameMatch
)
match
;
nameMatchDefine
.
put
(
nameMatch
.
getClassName
(),
plugin
);
LinkedList
<
AbstractClassEnhancePluginDefine
>
pluginDefines
=
nameMatchDefine
.
get
(
nameMatch
.
getClassName
());
if
(
pluginDefines
==
null
)
{
pluginDefines
=
new
LinkedList
<
AbstractClassEnhancePluginDefine
>();
nameMatchDefine
.
put
(
nameMatch
.
getClassName
(),
pluginDefines
);
}
pluginDefines
.
add
(
plugin
);
}
else
{
signatureMatchDefine
.
add
(
plugin
);
}
}
}
public
AbstractClassEnhancePluginDefine
find
(
TypeDescription
typeDescription
,
public
List
<
AbstractClassEnhancePluginDefine
>
find
(
TypeDescription
typeDescription
,
ClassLoader
classLoader
)
{
List
<
AbstractClassEnhancePluginDefine
>
matchedPlugins
=
new
LinkedList
<
AbstractClassEnhancePluginDefine
>();
String
typeName
=
typeDescription
.
getTypeName
();
if
(
nameMatchDefine
.
containsKey
(
typeName
))
{
return
nameMatchDefine
.
get
(
typeName
);
matchedPlugins
.
addAll
(
nameMatchDefine
.
get
(
typeName
)
);
}
for
(
AbstractClassEnhancePluginDefine
pluginDefine
:
signatureMatchDefine
)
{
IndirectMatch
match
=
(
IndirectMatch
)
pluginDefine
.
enhanceClass
();
if
(
match
.
isMatch
(
typeDescription
))
{
return
pluginDefine
;
matchedPlugins
.
add
(
pluginDefine
)
;
}
}
return
null
;
return
matchedPlugins
;
}
public
ElementMatcher
<?
super
TypeDescription
>
buildMatch
()
{
...
...
apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java
浏览文件 @
a20d6ea2
...
...
@@ -6,6 +6,7 @@ import net.bytebuddy.implementation.MethodDelegation;
import
net.bytebuddy.implementation.SuperMethodCall
;
import
net.bytebuddy.implementation.bind.annotation.Morph
;
import
org.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine
;
import
org.skywalking.apm.agent.core.plugin.EnhanceContext
;
import
org.skywalking.apm.agent.core.plugin.PluginException
;
import
org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint
;
import
org.skywalking.apm.agent.core.plugin.interceptor.EnhanceException
;
...
...
@@ -46,10 +47,11 @@ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePlugi
*/
@Override
protected
DynamicType
.
Builder
<?>
enhance
(
String
enhanceOriginClassName
,
DynamicType
.
Builder
<?>
newClassBuilder
,
ClassLoader
classLoader
)
throws
PluginException
{
DynamicType
.
Builder
<?>
newClassBuilder
,
ClassLoader
classLoader
,
EnhanceContext
context
)
throws
PluginException
{
newClassBuilder
=
this
.
enhanceClass
(
enhanceOriginClassName
,
newClassBuilder
,
classLoader
);
newClassBuilder
=
this
.
enhanceInstance
(
enhanceOriginClassName
,
newClassBuilder
,
classLoader
);
newClassBuilder
=
this
.
enhanceInstance
(
enhanceOriginClassName
,
newClassBuilder
,
classLoader
,
context
);
return
newClassBuilder
;
}
...
...
@@ -62,7 +64,8 @@ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePlugi
* @return new byte-buddy's builder for further manipulation.
*/
private
DynamicType
.
Builder
<?>
enhanceInstance
(
String
enhanceOriginClassName
,
DynamicType
.
Builder
<?>
newClassBuilder
,
ClassLoader
classLoader
)
throws
PluginException
{
DynamicType
.
Builder
<?>
newClassBuilder
,
ClassLoader
classLoader
,
EnhanceContext
context
)
throws
PluginException
{
ConstructorInterceptPoint
[]
constructorInterceptPoints
=
getConstructorsInterceptPoints
();
InstanceMethodsInterceptPoint
[]
instanceMethodsInterceptPoints
=
getInstanceMethodsInterceptPoints
();
...
...
@@ -83,16 +86,21 @@ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePlugi
}
/**
*
alter
class source code.<br/>
*
Manipulate
class source code.<br/>
*
* new class need:<br/>
* 1.Add field, name {@link #CONTEXT_ATTR_NAME}.
* 2.Add a field accessor for this field.
*
* And make sure the source codes manipulation only occurs once.
*
*/
newClassBuilder
=
newClassBuilder
.
defineField
(
CONTEXT_ATTR_NAME
,
Object
.
class
,
ACC_PRIVATE
)
.
implement
(
EnhancedInstance
.
class
)
.
intercept
(
FieldAccessor
.
ofField
(
CONTEXT_ATTR_NAME
));
if
(!
context
.
isObjectExtended
())
{
newClassBuilder
=
newClassBuilder
.
defineField
(
CONTEXT_ATTR_NAME
,
Object
.
class
,
ACC_PRIVATE
)
.
implement
(
EnhancedInstance
.
class
)
.
intercept
(
FieldAccessor
.
ofField
(
CONTEXT_ATTR_NAME
));
context
.
extendObjectCompleted
();
}
/**
* 2. enhance constructors
...
...
apm-sniffer/apm-agent/pom.xml
浏览文件 @
a20d6ea2
...
...
@@ -125,6 +125,11 @@
<artifactId>
apm-jetty-server-9.x-plugin
</artifactId>
<version>
${project.version}
</version>
</dependency>
<dependency>
<groupId>
org.skywalking
</groupId>
<artifactId>
apm-spymemcached-2.x-plugin
</artifactId>
<version>
${project.version}
</version>
</dependency>
<!-- activation -->
<dependency>
...
...
apm-sniffer/apm-agent/src/main/java/org/skywalking/apm/agent/SkyWalkingAgent.java
浏览文件 @
a20d6ea2
package
org.skywalking.apm.agent
;
import
java.lang.instrument.Instrumentation
;
import
java.util.List
;
import
net.bytebuddy.agent.builder.AgentBuilder
;
import
net.bytebuddy.description.type.TypeDescription
;
import
net.bytebuddy.dynamic.DynamicType
;
...
...
@@ -9,6 +10,7 @@ import org.skywalking.apm.agent.core.boot.ServiceManager;
import
org.skywalking.apm.agent.core.conf.SnifferConfigInitializer
;
import
org.skywalking.apm.agent.core.logging.EasyLogResolver
;
import
org.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine
;
import
org.skywalking.apm.agent.core.plugin.EnhanceContext
;
import
org.skywalking.apm.agent.core.plugin.PluginBootstrap
;
import
org.skywalking.apm.agent.core.plugin.PluginException
;
import
org.skywalking.apm.agent.core.plugin.PluginFinder
;
...
...
@@ -54,13 +56,21 @@ public class SkyWalkingAgent {
@Override
public
DynamicType
.
Builder
<?>
transform
(
DynamicType
.
Builder
<?>
builder
,
TypeDescription
typeDescription
,
ClassLoader
classLoader
,
JavaModule
module
)
{
AbstractClassEnhancePluginDefine
pluginDefine
=
pluginFinder
.
find
(
typeDescription
,
classLoader
);
if
(
pluginDefine
!=
null
)
{
DynamicType
.
Builder
<?>
newBuilder
=
pluginDefine
.
define
(
typeDescription
.
getTypeName
(),
builder
,
classLoader
);
if
(
newBuilder
!=
null
)
{
List
<
AbstractClassEnhancePluginDefine
>
pluginDefines
=
pluginFinder
.
find
(
typeDescription
,
classLoader
);
if
(
pluginDefines
.
size
()
>
0
)
{
DynamicType
.
Builder
<?>
newBuilder
=
builder
;
EnhanceContext
context
=
new
EnhanceContext
();
for
(
AbstractClassEnhancePluginDefine
define
:
pluginDefines
)
{
DynamicType
.
Builder
<?>
possibleNewBuilder
=
define
.
define
(
typeDescription
.
getTypeName
(),
newBuilder
,
classLoader
,
context
);
if
(
possibleNewBuilder
!=
null
)
{
newBuilder
=
possibleNewBuilder
;
}
}
if
(
context
.
isEnhanced
())
{
logger
.
debug
(
"Finish the prepare stage for {}."
,
typeDescription
.
getName
());
return
newBuilder
;
}
return
newBuilder
;
}
logger
.
debug
(
"Matched class {}, but ignore by finding mechanism."
,
typeDescription
.
getTypeName
());
...
...
apm-sniffer/apm-sdk-plugin/pom.xml
浏览文件 @
a20d6ea2
...
...
@@ -26,6 +26,7 @@
<module>
struts2-2.x-plugin
</module>
<module>
nutz-plugins
</module>
<module>
jetty-plugin
</module>
<module>
spymemcached-2.x-plugin
</module>
</modules>
<packaging>
pom
</packaging>
...
...
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/skywalking/apm/plugin/spring/mvc/
ControllerServiceMethodInter
ceptor.java
→
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/skywalking/apm/plugin/spring/mvc/
AbstractMethodInte
ceptor.java
浏览文件 @
a20d6ea2
package
org.skywalking.apm.plugin.spring.mvc
;
import
java.lang.reflect.Method
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
org.skywalking.apm.agent.core.context.CarrierItem
;
import
org.skywalking.apm.agent.core.context.ContextCarrier
;
import
org.skywalking.apm.agent.core.context.ContextManager
;
...
...
@@ -13,33 +10,30 @@ import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance
import
org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor
;
import
org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult
;
import
org.skywalking.apm.network.trace.component.ComponentsDefine
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.context.request.RequestContextHolder
;
import
org.springframework.web.context.request.ServletRequestAttributes
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.lang.reflect.Method
;
/**
*
The <code>ControllerServiceMethodInterceptor</code> only use the first mapping value.
*
the abstract method inteceptor
*/
public
class
ControllerServiceMethodInterceptor
implements
InstanceMethodsAroundInterceptor
{
public
abstract
class
AbstractMethodInteceptor
implements
InstanceMethodsAroundInterceptor
{
public
abstract
String
getRequestURL
(
Method
method
);
@Override
public
void
beforeMethod
(
EnhancedInstance
objInst
,
Method
method
,
Object
[]
allArguments
,
Class
<?>[]
argumentsTypes
,
MethodInterceptResult
result
)
throws
Throwable
{
MethodInterceptResult
result
)
throws
Throwable
{
PathMappingCache
pathMappingCache
=
(
PathMappingCache
)
objInst
.
getSkyWalkingDynamicField
();
String
requestURL
=
pathMappingCache
.
findPathMapping
(
method
);
if
(
requestURL
==
null
)
{
RequestMapping
methodRequestMapping
=
method
.
getAnnotation
(
RequestMapping
.
class
);
if
(
methodRequestMapping
.
value
().
length
>
0
)
{
requestURL
=
methodRequestMapping
.
value
()[
0
];
}
else
if
(
methodRequestMapping
.
path
().
length
>
0
)
{
requestURL
=
methodRequestMapping
.
path
()[
0
];
}
else
{
requestURL
=
""
;
}
requestURL
=
getRequestURL
(
method
);
pathMappingCache
.
addPathMapping
(
method
,
requestURL
);
requestURL
=
pathMappingCache
.
findPathMapping
(
method
);
}
HttpServletRequest
request
=
((
ServletRequestAttributes
)
RequestContextHolder
.
getRequestAttributes
()).
getRequest
();
HttpServletRequest
request
=
((
ServletRequestAttributes
)
RequestContextHolder
.
getRequestAttributes
()).
getRequest
();
ContextCarrier
contextCarrier
=
new
ContextCarrier
();
CarrierItem
next
=
contextCarrier
.
items
();
...
...
@@ -57,7 +51,7 @@ public class ControllerServiceMethodInterceptor implements InstanceMethodsAround
@Override
public
Object
afterMethod
(
EnhancedInstance
objInst
,
Method
method
,
Object
[]
allArguments
,
Class
<?>[]
argumentsTypes
,
Object
ret
)
throws
Throwable
{
Object
ret
)
throws
Throwable
{
HttpServletResponse
response
=
((
ServletRequestAttributes
)
RequestContextHolder
.
getRequestAttributes
()).
getResponse
();
AbstractSpan
span
=
ContextManager
.
activeSpan
();
...
...
@@ -69,8 +63,9 @@ public class ControllerServiceMethodInterceptor implements InstanceMethodsAround
return
ret
;
}
@Override
public
void
handleMethodException
(
EnhancedInstance
objInst
,
Method
method
,
Object
[]
allArguments
,
Class
<?>[]
argumentsTypes
,
Throwable
t
)
{
@Override
public
void
handleMethodException
(
EnhancedInstance
objInst
,
Method
method
,
Object
[]
allArguments
,
Class
<?>[]
argumentsTypes
,
Throwable
t
)
{
ContextManager
.
activeSpan
().
errorOccurred
().
log
(
t
);
}
}
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/skywalking/apm/plugin/spring/mvc/RequestMappingMethodInterceptor.java
0 → 100644
浏览文件 @
a20d6ea2
package
org.skywalking.apm.plugin.spring.mvc
;
import
java.lang.reflect.Method
;
import
org.springframework.web.bind.annotation.RequestMapping
;
/**
* The <code>RequestMappingMethodInterceptor</code> only use the first mapping value.
* it will inteceptor with <code>@RequestMapping</code>
* @author clevertension
*/
public
class
RequestMappingMethodInterceptor
extends
AbstractMethodInteceptor
{
@Override
public
String
getRequestURL
(
Method
method
)
{
String
requestURL
=
""
;
RequestMapping
methodRequestMapping
=
method
.
getAnnotation
(
RequestMapping
.
class
);
if
(
methodRequestMapping
.
value
().
length
>
0
)
{
requestURL
=
methodRequestMapping
.
value
()[
0
];
}
else
if
(
methodRequestMapping
.
path
().
length
>
0
)
{
requestURL
=
methodRequestMapping
.
path
()[
0
];
}
return
requestURL
;
}
}
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/skywalking/apm/plugin/spring/mvc/RestMappingMethodInterceptor.java
0 → 100644
浏览文件 @
a20d6ea2
package
org.skywalking.apm.plugin.spring.mvc
;
import
java.lang.reflect.Method
;
import
org.springframework.web.bind.annotation.*
;
/**
* The <code>RestMappingMethodInterceptor</code> only use the first mapping value.
* it will inteceptor with
* <code>@GetMapping</code>, <code>@PostMapping</code>, <code>@PutMapping</code>
* <code>@DeleteMapping</code>, <code>@PatchMapping</code>
* @author clevertension
*/
public
class
RestMappingMethodInterceptor
extends
AbstractMethodInteceptor
{
@Override
public
String
getRequestURL
(
Method
method
)
{
String
requestURL
=
""
;
GetMapping
getMapping
=
method
.
getAnnotation
(
GetMapping
.
class
);
PostMapping
postMapping
=
method
.
getAnnotation
(
PostMapping
.
class
);
PutMapping
putMapping
=
method
.
getAnnotation
(
PutMapping
.
class
);
DeleteMapping
deleteMapping
=
method
.
getAnnotation
(
DeleteMapping
.
class
);
PatchMapping
patchMapping
=
method
.
getAnnotation
(
PatchMapping
.
class
);
if
(
getMapping
!=
null
)
{
if
(
getMapping
.
value
().
length
>
0
)
{
requestURL
=
getMapping
.
value
()[
0
];
}
else
if
(
getMapping
.
path
().
length
>
0
)
{
requestURL
=
getMapping
.
path
()[
0
];
}
}
else
if
(
postMapping
!=
null
)
{
if
(
postMapping
.
value
().
length
>
0
)
{
requestURL
=
postMapping
.
value
()[
0
];
}
else
if
(
postMapping
.
path
().
length
>
0
)
{
requestURL
=
postMapping
.
path
()[
0
];
}
}
else
if
(
putMapping
!=
null
)
{
if
(
putMapping
.
value
().
length
>
0
)
{
requestURL
=
putMapping
.
value
()[
0
];
}
else
if
(
putMapping
.
path
().
length
>
0
)
{
requestURL
=
putMapping
.
path
()[
0
];
}
}
else
if
(
deleteMapping
!=
null
)
{
if
(
deleteMapping
.
value
().
length
>
0
)
{
requestURL
=
deleteMapping
.
value
()[
0
];
}
else
if
(
deleteMapping
.
path
().
length
>
0
)
{
requestURL
=
deleteMapping
.
path
()[
0
];
}
}
else
if
(
patchMapping
!=
null
)
{
if
(
patchMapping
.
value
().
length
>
0
)
{
requestURL
=
patchMapping
.
value
()[
0
];
}
else
if
(
patchMapping
.
path
().
length
>
0
)
{
requestURL
=
patchMapping
.
path
()[
0
];
}
}
return
requestURL
;
}
}
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/skywalking/apm/plugin/spring/mvc/define/AbstractControllerInstrumentation.java
浏览文件 @
a20d6ea2
...
...
@@ -20,8 +20,8 @@ import static org.skywalking.apm.agent.core.plugin.match.ClassAnnotationMatch.by
* <code>org.skywalking.apm.plugin.spring.mvc.ControllerConstructorInterceptor</code> set the controller base path to
* dynamic field before execute constructor.
*
* <code>org.skywalking.apm.plugin.spring.mvc.
ControllerService
MethodInterceptor</code> get the request path from
* dynamic field first, if not found, <code>
ControllerService
MethodInterceptor</code> generate request path that
* <code>org.skywalking.apm.plugin.spring.mvc.
RequestMapping
MethodInterceptor</code> get the request path from
* dynamic field first, if not found, <code>
RequestMapping
MethodInterceptor</code> generate request path that
* combine the path value of current annotation on current method and the base path and set the new path to the dynamic
* filed
*
...
...
@@ -56,7 +56,26 @@ public abstract class AbstractControllerInstrumentation extends ClassInstanceMet
@Override
public
String
getMethodsInterceptor
()
{
return
"org.skywalking.apm.plugin.spring.mvc.ControllerServiceMethodInterceptor"
;
return
"org.skywalking.apm.plugin.spring.mvc.RequestMappingMethodInterceptor"
;
}
@Override
public
boolean
isOverrideArgs
()
{
return
false
;
}
},
new
InstanceMethodsInterceptPoint
()
{
@Override
public
ElementMatcher
<
MethodDescription
>
getMethodsMatcher
()
{
return
isAnnotatedWith
(
named
(
"org.springframework.web.bind.annotation.GetMapping"
))
.
or
(
isAnnotatedWith
(
named
(
"org.springframework.web.bind.annotation.PostMapping"
)))
.
or
(
isAnnotatedWith
(
named
(
"org.springframework.web.bind.annotation.PutMapping"
)))
.
or
(
isAnnotatedWith
(
named
(
"org.springframework.web.bind.annotation.DeleteMapping"
)))
.
or
(
isAnnotatedWith
(
named
(
"org.springframework.web.bind.annotation.PatchMapping"
)));
}
@Override
public
String
getMethodsInterceptor
()
{
return
"org.skywalking.apm.plugin.spring.mvc.RestMappingMethodInterceptor"
;
}
@Override
...
...
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/test/java/org/skywalking/apm/plugin/spring/mvc/ControllerConstructorInterceptorTest.java
0 → 100644
浏览文件 @
a20d6ea2
package
org.skywalking.apm.plugin.spring.mvc
;
import
org.junit.Assert
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.powermock.modules.junit4.PowerMockRunner
;
import
org.powermock.modules.junit4.PowerMockRunnerDelegate
;
import
org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance
;
import
org.skywalking.apm.agent.test.tools.TracingSegmentRunner
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
java.lang.reflect.Method
;
@RunWith
(
PowerMockRunner
.
class
)
@PowerMockRunnerDelegate
(
TracingSegmentRunner
.
class
)
public
class
ControllerConstructorInterceptorTest
{
private
ControllerConstructorInterceptor
controllerConstructorInterceptor
;
private
final
MockEnhancedInstance1
inst1
=
new
MockEnhancedInstance1
();
private
final
MockEnhancedInstance2
inst2
=
new
MockEnhancedInstance2
();
private
final
MockEnhancedInstance3
inst3
=
new
MockEnhancedInstance3
();
@Before
public
void
setUp
()
throws
Exception
{
controllerConstructorInterceptor
=
new
ControllerConstructorInterceptor
();
}
@Test
public
void
testOnConstruct_Accuracy1
()
throws
Throwable
{
controllerConstructorInterceptor
.
onConstruct
(
inst1
,
null
);
PathMappingCache
cache
=
(
PathMappingCache
)
inst1
.
getSkyWalkingDynamicField
();
Assert
.
assertNotNull
(
cache
);
Object
obj
=
new
Object
();
Method
m
=
obj
.
getClass
().
getMethods
()[
0
];
cache
.
addPathMapping
(
m
,
"#toString"
);
Assert
.
assertEquals
(
"the two value should be equal"
,
cache
.
findPathMapping
(
m
),
"/test1#toString"
);
}
@Test
public
void
testOnConstruct_Accuracy2
()
throws
Throwable
{
controllerConstructorInterceptor
.
onConstruct
(
inst2
,
null
);
PathMappingCache
cache
=
(
PathMappingCache
)
inst2
.
getSkyWalkingDynamicField
();
Assert
.
assertNotNull
(
cache
);
Object
obj
=
new
Object
();
Method
m
=
obj
.
getClass
().
getMethods
()[
0
];
cache
.
addPathMapping
(
m
,
"#toString"
);
Assert
.
assertEquals
(
"the two value should be equal"
,
cache
.
findPathMapping
(
m
),
"#toString"
);
}
@Test
public
void
testOnConstruct_Accuracy3
()
throws
Throwable
{
controllerConstructorInterceptor
.
onConstruct
(
inst3
,
null
);
PathMappingCache
cache
=
(
PathMappingCache
)
inst3
.
getSkyWalkingDynamicField
();
Assert
.
assertNotNull
(
cache
);
Object
obj
=
new
Object
();
Method
m
=
obj
.
getClass
().
getMethods
()[
0
];
cache
.
addPathMapping
(
m
,
"#toString"
);
Assert
.
assertEquals
(
"the two value should be equal"
,
cache
.
findPathMapping
(
m
),
"/test3#toString"
);
}
@RequestMapping
(
value
=
"/test1"
)
private
class
MockEnhancedInstance1
implements
EnhancedInstance
{
private
Object
value
;
@Override
public
Object
getSkyWalkingDynamicField
()
{
return
value
;
}
@Override
public
void
setSkyWalkingDynamicField
(
Object
value
)
{
this
.
value
=
value
;
}
}
private
class
MockEnhancedInstance2
implements
EnhancedInstance
{
private
Object
value
;
@Override
public
Object
getSkyWalkingDynamicField
()
{
return
value
;
}
@Override
public
void
setSkyWalkingDynamicField
(
Object
value
)
{
this
.
value
=
value
;
}
}
@RequestMapping
(
path
=
"/test3"
)
private
class
MockEnhancedInstance3
implements
EnhancedInstance
{
private
Object
value
;
@Override
public
Object
getSkyWalkingDynamicField
()
{
return
value
;
}
@Override
public
void
setSkyWalkingDynamicField
(
Object
value
)
{
this
.
value
=
value
;
}
}
}
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/test/java/org/skywalking/apm/plugin/spring/mvc/PathMappingCacheTest.java
0 → 100644
浏览文件 @
a20d6ea2
package
org.skywalking.apm.plugin.spring.mvc
;
import
org.junit.Assert
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.powermock.modules.junit4.PowerMockRunner
;
import
org.powermock.modules.junit4.PowerMockRunnerDelegate
;
import
org.skywalking.apm.agent.test.tools.TracingSegmentRunner
;
import
java.lang.reflect.Method
;
import
static
org
.
powermock
.
api
.
mockito
.
PowerMockito
.
whenNew
;
@RunWith
(
PowerMockRunner
.
class
)
@PowerMockRunnerDelegate
(
TracingSegmentRunner
.
class
)
public
class
PathMappingCacheTest
{
private
PathMappingCache
pathMappingCache
;
@Before
public
void
setUp
()
throws
Exception
{
pathMappingCache
=
new
PathMappingCache
(
"org.skywalking.apm.plugin.spring.mvc"
);
}
@Test
public
void
testAddPathMapping1
()
throws
Throwable
{
Object
obj
=
new
Object
();
Method
m
=
obj
.
getClass
().
getMethods
()[
0
];
pathMappingCache
.
addPathMapping
(
m
,
"#toString"
);
Assert
.
assertEquals
(
"the two value should be equal"
,
pathMappingCache
.
findPathMapping
(
m
),
"org.skywalking.apm.plugin.spring.mvc#toString"
);
}
}
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/test/java/org/skywalking/apm/plugin/spring/mvc/RequestMappingMethodInterceptorTest.java
0 → 100644
浏览文件 @
a20d6ea2
package
org.skywalking.apm.plugin.spring.mvc
;
import
org.junit.Before
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.mockito.Mock
;
import
org.powermock.modules.junit4.PowerMockRunner
;
import
org.powermock.modules.junit4.PowerMockRunnerDelegate
;
import
org.skywalking.apm.agent.core.context.trace.*
;
import
org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance
;
import
org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult
;
import
org.skywalking.apm.agent.test.helper.SegmentHelper
;
import
org.skywalking.apm.agent.test.helper.SegmentRefHelper
;
import
org.skywalking.apm.agent.test.helper.SpanHelper
;
import
org.skywalking.apm.agent.test.tools.AgentServiceRule
;
import
org.skywalking.apm.agent.test.tools.SegmentStorage
;
import
org.skywalking.apm.agent.test.tools.SegmentStoragePoint
;
import
org.skywalking.apm.agent.test.tools.TracingSegmentRunner
;
import
org.skywalking.apm.network.trace.component.ComponentsDefine
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.context.request.RequestContextHolder
;
import
org.springframework.web.context.request.ServletRequestAttributes
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.lang.reflect.Method
;
import
java.util.List
;
import
static
org
.
hamcrest
.
CoreMatchers
.
is
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
static
org
.
skywalking
.
apm
.
agent
.
test
.
tools
.
SpanAssert
.*;
@RunWith
(
PowerMockRunner
.
class
)
@PowerMockRunnerDelegate
(
TracingSegmentRunner
.
class
)
public
class
RequestMappingMethodInterceptorTest
{
private
RequestMappingMethodInterceptor
interceptor
;
@SegmentStoragePoint
private
SegmentStorage
segmentStorage
;
@Rule
public
AgentServiceRule
serviceRule
=
new
AgentServiceRule
();
private
ServletRequestAttributes
servletRequestAttributes
;
@Mock
private
HttpServletRequest
request
;
@Mock
private
HttpServletResponse
response
;
@Mock
private
MethodInterceptResult
methodInterceptResult
;
private
Object
[]
arguments
;
private
Class
[]
argumentType
;
private
EnhancedInstance
enhancedInstance
;
private
ControllerConstructorInterceptor
controllerConstructorInterceptor
;
@Before
public
void
setUp
()
throws
Exception
{
interceptor
=
new
RequestMappingMethodInterceptor
();
enhancedInstance
=
new
MockEnhancedInstance1
();
controllerConstructorInterceptor
=
new
ControllerConstructorInterceptor
();
servletRequestAttributes
=
new
ServletRequestAttributes
(
request
,
response
);
when
(
request
.
getScheme
()).
thenReturn
(
"http"
);
when
(
request
.
getServerName
()).
thenReturn
(
"localhost"
);
when
(
request
.
getServerPort
()).
thenReturn
(
8080
);
when
(
request
.
getRequestURI
()).
thenReturn
(
"/test/testRequestURL"
);
when
(
request
.
getRequestURL
()).
thenReturn
(
new
StringBuffer
(
"http://localhost:8080/test/testRequestURL"
));
when
(
response
.
getStatus
()).
thenReturn
(
200
);
arguments
=
new
Object
[]
{
request
,
response
};
argumentType
=
new
Class
[]
{
request
.
getClass
(),
response
.
getClass
()};
}
@Test
public
void
testWithoutSerializedContextData
()
throws
Throwable
{
controllerConstructorInterceptor
.
onConstruct
(
enhancedInstance
,
null
);
RequestMappingClass1
mappingClass1
=
new
RequestMappingClass1
();
Method
m
=
mappingClass1
.
getClass
().
getMethod
(
"testRequestURL"
);
RequestContextHolder
.
setRequestAttributes
(
servletRequestAttributes
);
interceptor
.
beforeMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
methodInterceptResult
);
interceptor
.
afterMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
null
);
assertThat
(
segmentStorage
.
getTraceSegments
().
size
(),
is
(
1
));
TraceSegment
traceSegment
=
segmentStorage
.
getTraceSegments
().
get
(
0
);
List
<
AbstractTracingSpan
>
spans
=
SegmentHelper
.
getSpans
(
traceSegment
);
assertHttpSpan
(
spans
.
get
(
0
));
}
@Test
public
void
testWithOccurException
()
throws
Throwable
{
controllerConstructorInterceptor
.
onConstruct
(
enhancedInstance
,
null
);
RequestMappingClass1
mappingClass1
=
new
RequestMappingClass1
();
Method
m
=
mappingClass1
.
getClass
().
getMethod
(
"testRequestURL"
);
RequestContextHolder
.
setRequestAttributes
(
servletRequestAttributes
);
interceptor
.
beforeMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
methodInterceptResult
);
interceptor
.
handleMethodException
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
new
RuntimeException
());
interceptor
.
afterMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
null
);
assertThat
(
segmentStorage
.
getTraceSegments
().
size
(),
is
(
1
));
TraceSegment
traceSegment
=
segmentStorage
.
getTraceSegments
().
get
(
0
);
List
<
AbstractTracingSpan
>
spans
=
SegmentHelper
.
getSpans
(
traceSegment
);
assertHttpSpan
(
spans
.
get
(
0
));
List
<
LogDataEntity
>
logDataEntities
=
SpanHelper
.
getLogs
(
spans
.
get
(
0
));
assertThat
(
logDataEntities
.
size
(),
is
(
1
));
assertException
(
logDataEntities
.
get
(
0
),
RuntimeException
.
class
);
}
private
void
assertTraceSegmentRef
(
TraceSegmentRef
ref
)
{
assertThat
(
SegmentRefHelper
.
getEntryApplicationInstanceId
(
ref
),
is
(
1
));
assertThat
(
SegmentRefHelper
.
getSpanId
(
ref
),
is
(
3
));
assertThat
(
SegmentRefHelper
.
getTraceSegmentId
(
ref
).
toString
(),
is
(
"1.444.555"
));
}
private
void
assertHttpSpan
(
AbstractTracingSpan
span
)
{
assertThat
(
span
.
getOperationName
(),
is
(
"/test/testRequestURL"
));
assertComponent
(
span
,
ComponentsDefine
.
SPRING_MVC_ANNOTATION
);
assertTag
(
span
,
0
,
"http://localhost:8080/test/testRequestURL"
);
assertThat
(
span
.
isEntry
(),
is
(
true
));
assertLayer
(
span
,
SpanLayer
.
HTTP
);
}
@RequestMapping
(
value
=
"/test"
)
private
class
MockEnhancedInstance1
implements
EnhancedInstance
{
private
Object
value
;
@Override
public
Object
getSkyWalkingDynamicField
()
{
return
value
;
}
@Override
public
void
setSkyWalkingDynamicField
(
Object
value
)
{
this
.
value
=
value
;
}
}
private
class
RequestMappingClass1
{
@RequestMapping
(
"/testRequestURL"
)
public
void
testRequestURL
()
{
}
}
}
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/test/java/org/skywalking/apm/plugin/spring/mvc/RestMappingMethodInterceptorTest.java
0 → 100644
浏览文件 @
a20d6ea2
package
org.skywalking.apm.plugin.spring.mvc
;
import
org.junit.Before
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.mockito.Mock
;
import
org.powermock.modules.junit4.PowerMockRunner
;
import
org.powermock.modules.junit4.PowerMockRunnerDelegate
;
import
org.skywalking.apm.agent.core.context.trace.*
;
import
org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance
;
import
org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult
;
import
org.skywalking.apm.agent.test.helper.SegmentHelper
;
import
org.skywalking.apm.agent.test.helper.SegmentRefHelper
;
import
org.skywalking.apm.agent.test.helper.SpanHelper
;
import
org.skywalking.apm.agent.test.tools.AgentServiceRule
;
import
org.skywalking.apm.agent.test.tools.SegmentStorage
;
import
org.skywalking.apm.agent.test.tools.SegmentStoragePoint
;
import
org.skywalking.apm.agent.test.tools.TracingSegmentRunner
;
import
org.skywalking.apm.network.trace.component.ComponentsDefine
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.context.request.RequestContextHolder
;
import
org.springframework.web.context.request.ServletRequestAttributes
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.lang.reflect.Method
;
import
java.util.List
;
import
static
org
.
hamcrest
.
CoreMatchers
.
is
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
static
org
.
skywalking
.
apm
.
agent
.
test
.
tools
.
SpanAssert
.*;
@RunWith
(
PowerMockRunner
.
class
)
@PowerMockRunnerDelegate
(
TracingSegmentRunner
.
class
)
public
class
RestMappingMethodInterceptorTest
{
private
RestMappingMethodInterceptor
interceptor
;
@SegmentStoragePoint
private
SegmentStorage
segmentStorage
;
@Rule
public
AgentServiceRule
serviceRule
=
new
AgentServiceRule
();
@Mock
private
HttpServletRequest
request
;
@Mock
private
HttpServletResponse
response
;
@Mock
private
MethodInterceptResult
methodInterceptResult
;
private
Object
[]
arguments
;
private
Class
[]
argumentType
;
private
EnhancedInstance
enhancedInstance
;
private
ControllerConstructorInterceptor
controllerConstructorInterceptor
;
@Before
public
void
setUp
()
throws
Exception
{
interceptor
=
new
RestMappingMethodInterceptor
();
enhancedInstance
=
new
RestMappingMethodInterceptorTest
.
MockEnhancedInstance1
();
controllerConstructorInterceptor
=
new
ControllerConstructorInterceptor
();
when
(
request
.
getScheme
()).
thenReturn
(
"http"
);
when
(
request
.
getServerName
()).
thenReturn
(
"localhost"
);
when
(
request
.
getServerPort
()).
thenReturn
(
8080
);
when
(
response
.
getStatus
()).
thenReturn
(
200
);
arguments
=
new
Object
[]
{
request
,
response
};
argumentType
=
new
Class
[]
{
request
.
getClass
(),
response
.
getClass
()};
}
@Test
public
void
testGetMapping
()
throws
Throwable
{
controllerConstructorInterceptor
.
onConstruct
(
enhancedInstance
,
null
);
RestMappingClass1
mappingClass1
=
new
RestMappingClass1
();
Method
m
=
mappingClass1
.
getClass
().
getMethod
(
"getRequestURL"
);
when
(
request
.
getRequestURI
()).
thenReturn
(
"/test/testRequestURL"
);
when
(
request
.
getRequestURL
()).
thenReturn
(
new
StringBuffer
(
"http://localhost:8080/test/getRequestURL"
));
ServletRequestAttributes
servletRequestAttributes
=
new
ServletRequestAttributes
(
request
,
response
);
RequestContextHolder
.
setRequestAttributes
(
servletRequestAttributes
);
interceptor
.
beforeMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
methodInterceptResult
);
interceptor
.
afterMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
null
);
assertThat
(
segmentStorage
.
getTraceSegments
().
size
(),
is
(
1
));
TraceSegment
traceSegment
=
segmentStorage
.
getTraceSegments
().
get
(
0
);
List
<
AbstractTracingSpan
>
spans
=
SegmentHelper
.
getSpans
(
traceSegment
);
assertHttpSpan
(
spans
.
get
(
0
),
"/getRequestURL"
);
}
@Test
public
void
testPostMapping
()
throws
Throwable
{
controllerConstructorInterceptor
.
onConstruct
(
enhancedInstance
,
null
);
RestMappingClass1
mappingClass1
=
new
RestMappingClass1
();
Method
m
=
mappingClass1
.
getClass
().
getMethod
(
"postRequestURL"
);
when
(
request
.
getRequestURI
()).
thenReturn
(
"/test/testRequestURL"
);
when
(
request
.
getRequestURL
()).
thenReturn
(
new
StringBuffer
(
"http://localhost:8080/test/postRequestURL"
));
ServletRequestAttributes
servletRequestAttributes
=
new
ServletRequestAttributes
(
request
,
response
);
RequestContextHolder
.
setRequestAttributes
(
servletRequestAttributes
);
interceptor
.
beforeMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
methodInterceptResult
);
interceptor
.
afterMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
null
);
assertThat
(
segmentStorage
.
getTraceSegments
().
size
(),
is
(
1
));
TraceSegment
traceSegment
=
segmentStorage
.
getTraceSegments
().
get
(
0
);
List
<
AbstractTracingSpan
>
spans
=
SegmentHelper
.
getSpans
(
traceSegment
);
assertHttpSpan
(
spans
.
get
(
0
),
"/postRequestURL"
);
}
@Test
public
void
testPutMapping
()
throws
Throwable
{
controllerConstructorInterceptor
.
onConstruct
(
enhancedInstance
,
null
);
RestMappingClass1
mappingClass1
=
new
RestMappingClass1
();
Method
m
=
mappingClass1
.
getClass
().
getMethod
(
"putRequestURL"
);
when
(
request
.
getRequestURI
()).
thenReturn
(
"/test/testRequestURL"
);
when
(
request
.
getRequestURL
()).
thenReturn
(
new
StringBuffer
(
"http://localhost:8080/test/putRequestURL"
));
ServletRequestAttributes
servletRequestAttributes
=
new
ServletRequestAttributes
(
request
,
response
);
RequestContextHolder
.
setRequestAttributes
(
servletRequestAttributes
);
interceptor
.
beforeMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
methodInterceptResult
);
interceptor
.
afterMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
null
);
assertThat
(
segmentStorage
.
getTraceSegments
().
size
(),
is
(
1
));
TraceSegment
traceSegment
=
segmentStorage
.
getTraceSegments
().
get
(
0
);
List
<
AbstractTracingSpan
>
spans
=
SegmentHelper
.
getSpans
(
traceSegment
);
assertHttpSpan
(
spans
.
get
(
0
),
"/putRequestURL"
);
}
@Test
public
void
testDeleteMapping
()
throws
Throwable
{
controllerConstructorInterceptor
.
onConstruct
(
enhancedInstance
,
null
);
RestMappingClass1
mappingClass1
=
new
RestMappingClass1
();
Method
m
=
mappingClass1
.
getClass
().
getMethod
(
"deleteRequestURL"
);
when
(
request
.
getRequestURI
()).
thenReturn
(
"/test/testRequestURL"
);
when
(
request
.
getRequestURL
()).
thenReturn
(
new
StringBuffer
(
"http://localhost:8080/test/deleteRequestURL"
));
ServletRequestAttributes
servletRequestAttributes
=
new
ServletRequestAttributes
(
request
,
response
);
RequestContextHolder
.
setRequestAttributes
(
servletRequestAttributes
);
interceptor
.
beforeMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
methodInterceptResult
);
interceptor
.
afterMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
null
);
assertThat
(
segmentStorage
.
getTraceSegments
().
size
(),
is
(
1
));
TraceSegment
traceSegment
=
segmentStorage
.
getTraceSegments
().
get
(
0
);
List
<
AbstractTracingSpan
>
spans
=
SegmentHelper
.
getSpans
(
traceSegment
);
assertHttpSpan
(
spans
.
get
(
0
),
"/deleteRequestURL"
);
}
@Test
public
void
testPatchMapping
()
throws
Throwable
{
controllerConstructorInterceptor
.
onConstruct
(
enhancedInstance
,
null
);
RestMappingClass1
mappingClass1
=
new
RestMappingClass1
();
Method
m
=
mappingClass1
.
getClass
().
getMethod
(
"patchRequestURL"
);
when
(
request
.
getRequestURI
()).
thenReturn
(
"/test/testRequestURL"
);
when
(
request
.
getRequestURL
()).
thenReturn
(
new
StringBuffer
(
"http://localhost:8080/test/patchRequestURL"
));
ServletRequestAttributes
servletRequestAttributes
=
new
ServletRequestAttributes
(
request
,
response
);
RequestContextHolder
.
setRequestAttributes
(
servletRequestAttributes
);
interceptor
.
beforeMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
methodInterceptResult
);
interceptor
.
afterMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
null
);
assertThat
(
segmentStorage
.
getTraceSegments
().
size
(),
is
(
1
));
TraceSegment
traceSegment
=
segmentStorage
.
getTraceSegments
().
get
(
0
);
List
<
AbstractTracingSpan
>
spans
=
SegmentHelper
.
getSpans
(
traceSegment
);
assertHttpSpan
(
spans
.
get
(
0
),
"/patchRequestURL"
);
}
@Test
public
void
testDummy
()
throws
Throwable
{
controllerConstructorInterceptor
.
onConstruct
(
enhancedInstance
,
null
);
RestMappingClass1
mappingClass1
=
new
RestMappingClass1
();
Method
m
=
mappingClass1
.
getClass
().
getMethod
(
"dummy"
);
when
(
request
.
getRequestURI
()).
thenReturn
(
"/test"
);
when
(
request
.
getRequestURL
()).
thenReturn
(
new
StringBuffer
(
"http://localhost:8080/test"
));
ServletRequestAttributes
servletRequestAttributes
=
new
ServletRequestAttributes
(
request
,
response
);
RequestContextHolder
.
setRequestAttributes
(
servletRequestAttributes
);
interceptor
.
beforeMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
methodInterceptResult
);
interceptor
.
afterMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
null
);
assertThat
(
segmentStorage
.
getTraceSegments
().
size
(),
is
(
1
));
TraceSegment
traceSegment
=
segmentStorage
.
getTraceSegments
().
get
(
0
);
List
<
AbstractTracingSpan
>
spans
=
SegmentHelper
.
getSpans
(
traceSegment
);
assertHttpSpan
(
spans
.
get
(
0
),
""
);
}
@Test
public
void
testWithOccurException
()
throws
Throwable
{
controllerConstructorInterceptor
.
onConstruct
(
enhancedInstance
,
null
);
RestMappingClass1
mappingClass1
=
new
RestMappingClass1
();
Method
m
=
mappingClass1
.
getClass
().
getMethod
(
"getRequestURL"
);
when
(
request
.
getRequestURI
()).
thenReturn
(
"/test/testRequestURL"
);
when
(
request
.
getRequestURL
()).
thenReturn
(
new
StringBuffer
(
"http://localhost:8080/test/getRequestURL"
));
ServletRequestAttributes
servletRequestAttributes
=
new
ServletRequestAttributes
(
request
,
response
);
RequestContextHolder
.
setRequestAttributes
(
servletRequestAttributes
);
interceptor
.
beforeMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
methodInterceptResult
);
interceptor
.
handleMethodException
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
new
RuntimeException
());
interceptor
.
afterMethod
(
enhancedInstance
,
m
,
arguments
,
argumentType
,
null
);
assertThat
(
segmentStorage
.
getTraceSegments
().
size
(),
is
(
1
));
TraceSegment
traceSegment
=
segmentStorage
.
getTraceSegments
().
get
(
0
);
List
<
AbstractTracingSpan
>
spans
=
SegmentHelper
.
getSpans
(
traceSegment
);
assertHttpSpan
(
spans
.
get
(
0
),
"/getRequestURL"
);
List
<
LogDataEntity
>
logDataEntities
=
SpanHelper
.
getLogs
(
spans
.
get
(
0
));
assertThat
(
logDataEntities
.
size
(),
is
(
1
));
assertException
(
logDataEntities
.
get
(
0
),
RuntimeException
.
class
);
}
private
void
assertTraceSegmentRef
(
TraceSegmentRef
ref
)
{
assertThat
(
SegmentRefHelper
.
getEntryApplicationInstanceId
(
ref
),
is
(
1
));
assertThat
(
SegmentRefHelper
.
getSpanId
(
ref
),
is
(
3
));
assertThat
(
SegmentRefHelper
.
getTraceSegmentId
(
ref
).
toString
(),
is
(
"1.444.555"
));
}
private
void
assertHttpSpan
(
AbstractTracingSpan
span
,
String
suffix
)
{
assertThat
(
span
.
getOperationName
(),
is
(
"/test"
+
suffix
));
assertComponent
(
span
,
ComponentsDefine
.
SPRING_MVC_ANNOTATION
);
assertTag
(
span
,
0
,
"http://localhost:8080/test"
+
suffix
);
assertThat
(
span
.
isEntry
(),
is
(
true
));
assertLayer
(
span
,
SpanLayer
.
HTTP
);
}
@RequestMapping
(
value
=
"/test"
)
private
class
MockEnhancedInstance1
implements
EnhancedInstance
{
private
Object
value
;
@Override
public
Object
getSkyWalkingDynamicField
()
{
return
value
;
}
@Override
public
void
setSkyWalkingDynamicField
(
Object
value
)
{
this
.
value
=
value
;
}
}
private
class
RestMappingClass1
{
@GetMapping
(
"/getRequestURL"
)
public
void
getRequestURL
()
{
}
@PostMapping
(
"/postRequestURL"
)
public
void
postRequestURL
()
{
}
@PutMapping
(
"/putRequestURL"
)
public
void
putRequestURL
()
{
}
@DeleteMapping
(
"/deleteRequestURL"
)
public
void
deleteRequestURL
()
{
}
@PatchMapping
(
"/patchRequestURL"
)
public
void
patchRequestURL
()
{
}
public
void
dummy
()
{
}
}
}
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/test/java/org/skywalking/apm/plugin/spring/mvc/define/ControllerInstrumentationTest.java
0 → 100644
浏览文件 @
a20d6ea2
package
org.skywalking.apm.plugin.spring.mvc.define
;
import
org.junit.Assert
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.powermock.modules.junit4.PowerMockRunner
;
import
org.powermock.modules.junit4.PowerMockRunnerDelegate
;
import
org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint
;
import
org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint
;
import
org.skywalking.apm.agent.test.tools.TracingSegmentRunner
;
import
net.bytebuddy.description.method.MethodDescription
;
import
net.bytebuddy.matcher.ElementMatchers
;
import
static
net
.
bytebuddy
.
matcher
.
ElementMatchers
.
isAnnotatedWith
;
import
static
net
.
bytebuddy
.
matcher
.
ElementMatchers
.
named
;
import
static
org
.
hamcrest
.
CoreMatchers
.
is
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
@RunWith
(
PowerMockRunner
.
class
)
@PowerMockRunnerDelegate
(
TracingSegmentRunner
.
class
)
public
class
ControllerInstrumentationTest
{
private
ControllerInstrumentation
controllerInstrumentation
;
@Before
public
void
setUp
()
throws
Exception
{
controllerInstrumentation
=
new
ControllerInstrumentation
();
}
@Test
public
void
testGetEnhanceAnnotations
()
throws
Throwable
{
Assert
.
assertArrayEquals
(
new
String
[]
{
ControllerInstrumentation
.
ENHANCE_ANNOTATION
},
controllerInstrumentation
.
getEnhanceAnnotations
());
}
@Test
public
void
testGetInstanceMethodsInterceptPoints
()
throws
Throwable
{
InstanceMethodsInterceptPoint
[]
methodPoints
=
controllerInstrumentation
.
getInstanceMethodsInterceptPoints
();
assertThat
(
methodPoints
.
length
,
is
(
2
));
assertThat
(
methodPoints
[
0
].
getMethodsInterceptor
(),
is
(
"org.skywalking.apm.plugin.spring.mvc.RequestMappingMethodInterceptor"
));
assertThat
(
methodPoints
[
1
].
getMethodsInterceptor
(),
is
(
"org.skywalking.apm.plugin.spring.mvc.RestMappingMethodInterceptor"
));
Assert
.
assertFalse
(
methodPoints
[
0
].
isOverrideArgs
());
Assert
.
assertFalse
(
methodPoints
[
1
].
isOverrideArgs
());
Assert
.
assertNotNull
(
methodPoints
[
0
].
getMethodsMatcher
());
Assert
.
assertNotNull
(
methodPoints
[
1
].
getMethodsMatcher
());
}
@Test
public
void
testGetConstructorsInterceptPoints
()
throws
Throwable
{
ConstructorInterceptPoint
[]
cips
=
controllerInstrumentation
.
getConstructorsInterceptPoints
();
Assert
.
assertEquals
(
cips
.
length
,
1
);
ConstructorInterceptPoint
cip
=
cips
[
0
];
Assert
.
assertNotNull
(
cip
);
Assert
.
assertEquals
(
cip
.
getConstructorInterceptor
(),
"org.skywalking.apm.plugin.spring.mvc.ControllerConstructorInterceptor"
);
Assert
.
assertTrue
(
cip
.
getConstructorMatcher
().
equals
(
ElementMatchers
.
any
()));
}
}
apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/test/java/org/skywalking/apm/plugin/spring/mvc/define/RestControllerInstrumentationTest.java
0 → 100644
浏览文件 @
a20d6ea2
package
org.skywalking.apm.plugin.spring.mvc.define
;
import
org.junit.Assert
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.powermock.modules.junit4.PowerMockRunner
;
import
org.powermock.modules.junit4.PowerMockRunnerDelegate
;
import
org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint
;
import
org.skywalking.apm.agent.test.tools.TracingSegmentRunner
;
import
static
org
.
hamcrest
.
CoreMatchers
.
is
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
@RunWith
(
PowerMockRunner
.
class
)
@PowerMockRunnerDelegate
(
TracingSegmentRunner
.
class
)
public
class
RestControllerInstrumentationTest
{
private
RestControllerInstrumentation
restControllerInstrumentation
;
@Before
public
void
setUp
()
throws
Exception
{
restControllerInstrumentation
=
new
RestControllerInstrumentation
();
}
@Test
public
void
testGetEnhanceAnnotations
()
throws
Throwable
{
Assert
.
assertArrayEquals
(
new
String
[]
{
restControllerInstrumentation
.
ENHANCE_ANNOTATION
},
restControllerInstrumentation
.
getEnhanceAnnotations
());
}
@Test
public
void
testGetInstanceMethodsInterceptPoints
()
throws
Throwable
{
InstanceMethodsInterceptPoint
[]
methodPoints
=
restControllerInstrumentation
.
getInstanceMethodsInterceptPoints
();
assertThat
(
methodPoints
.
length
,
is
(
2
));
assertThat
(
methodPoints
[
0
].
getMethodsInterceptor
(),
is
(
"org.skywalking.apm.plugin.spring.mvc.RequestMappingMethodInterceptor"
));
assertThat
(
methodPoints
[
1
].
getMethodsInterceptor
(),
is
(
"org.skywalking.apm.plugin.spring.mvc.RestMappingMethodInterceptor"
));
Assert
.
assertFalse
(
methodPoints
[
0
].
isOverrideArgs
());
Assert
.
assertFalse
(
methodPoints
[
1
].
isOverrideArgs
());
Assert
.
assertNotNull
(
methodPoints
[
0
].
getMethodsMatcher
());
Assert
.
assertNotNull
(
methodPoints
[
1
].
getMethodsMatcher
());
}
}
apm-sniffer/apm-sdk-plugin/spymemcached-2.x-plugin/pom.xml
0 → 100644
浏览文件 @
a20d6ea2
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
>
<modelVersion>
4.0.0
</modelVersion>
<parent>
<groupId>
org.skywalking
</groupId>
<artifactId>
apm-sdk-plugin
</artifactId>
<version>
3.2.3-2017
</version>
</parent>
<artifactId>
apm-spymemcached-2.x-plugin
</artifactId>
<name>
spymemcached-2.x-plugin
</name>
<url>
http://maven.apache.org
</url>
<properties>
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
<spymemcached.version>
2.11.1
</spymemcached.version>
</properties>
<dependencies>
<dependency>
<groupId>
net.spy
</groupId>
<artifactId>
spymemcached
</artifactId>
<version>
${spymemcached.version}
</version>
<scope>
provided
</scope>
</dependency>
<dependency>
<groupId>
org.apache.logging.log4j
</groupId>
<artifactId>
log4j-core
</artifactId>
<version>
2.4.1
</version>
<scope>
test
</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
apm-sniffer/apm-sdk-plugin/spymemcached-2.x-plugin/src/main/java/org/skywalking/apm/plugin/spymemcached/v2/MemcachedConstructorWithInetSocketAddressListArgInterceptor.java
0 → 100644
浏览文件 @
a20d6ea2
package
org.skywalking.apm.plugin.spymemcached.v2
;
import
java.net.InetSocketAddress
;
import
java.util.List
;
import
org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance
;
import
org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor
;
public
class
MemcachedConstructorWithInetSocketAddressListArgInterceptor
implements
InstanceConstructorInterceptor
{
@Override
public
void
onConstruct
(
EnhancedInstance
objInst
,
Object
[]
allArguments
)
{
StringBuilder
memcachConnInfo
=
new
StringBuilder
();
@SuppressWarnings
(
"unchecked"
)
List
<
InetSocketAddress
>
inetSocketAddressList
=
(
List
<
InetSocketAddress
>)
allArguments
[
1
];
for
(
InetSocketAddress
inetSocketAddress
:
inetSocketAddressList
)
{
String
host
=
inetSocketAddress
.
getAddress
().
getHostAddress
();
int
port
=
inetSocketAddress
.
getPort
();
memcachConnInfo
.
append
(
host
).
append
(
":"
).
append
(
port
).
append
(
";"
);
}
if
(
memcachConnInfo
.
length
()
>
1
)
{
memcachConnInfo
=
new
StringBuilder
(
memcachConnInfo
.
substring
(
0
,
memcachConnInfo
.
length
()
-
1
));
}
objInst
.
setSkyWalkingDynamicField
(
memcachConnInfo
.
toString
());
}
}
\ No newline at end of file
apm-sniffer/apm-sdk-plugin/spymemcached-2.x-plugin/src/main/java/org/skywalking/apm/plugin/spymemcached/v2/MemcachedMethodInterceptor.java
0 → 100644
浏览文件 @
a20d6ea2
package
org.skywalking.apm.plugin.spymemcached.v2
;
import
java.lang.reflect.Method
;
import
org.skywalking.apm.agent.core.context.ContextManager
;
import
org.skywalking.apm.agent.core.context.tag.Tags
;
import
org.skywalking.apm.agent.core.context.trace.AbstractSpan
;
import
org.skywalking.apm.agent.core.context.trace.SpanLayer
;
import
org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance
;
import
org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor
;
import
org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult
;
import
org.skywalking.apm.network.trace.component.ComponentsDefine
;
public
class
MemcachedMethodInterceptor
implements
InstanceMethodsAroundInterceptor
{
private
static
final
String
SPY_MEMCACHE
=
"SpyMemcached/"
;
@Override
public
void
beforeMethod
(
EnhancedInstance
objInst
,
Method
method
,
Object
[]
allArguments
,
Class
<?>[]
argumentsTypes
,
MethodInterceptResult
result
)
throws
Throwable
{
String
peer
=
String
.
valueOf
(
objInst
.
getSkyWalkingDynamicField
());
AbstractSpan
span
=
ContextManager
.
createExitSpan
(
SPY_MEMCACHE
+
method
.
getName
(),
peer
);
span
.
setComponent
(
ComponentsDefine
.
MEMCACHE
);
Tags
.
DB_TYPE
.
set
(
span
,
ComponentsDefine
.
MEMCACHE
.
getName
());
SpanLayer
.
asDB
(
span
);
Tags
.
DB_STATEMENT
.
set
(
span
,
method
.
getName
()
+
" "
+
allArguments
[
0
]);
}
@Override
public
Object
afterMethod
(
EnhancedInstance
objInst
,
Method
method
,
Object
[]
allArguments
,
Class
<?>[]
argumentsTypes
,
Object
ret
)
throws
Throwable
{
ContextManager
.
stopSpan
();
return
ret
;
}
@Override
public
void
handleMethodException
(
EnhancedInstance
objInst
,
Method
method
,
Object
[]
allArguments
,
Class
<?>[]
argumentsTypes
,
Throwable
t
)
{
AbstractSpan
span
=
ContextManager
.
activeSpan
();
span
.
errorOccurred
();
span
.
log
(
t
);
}
}
apm-sniffer/apm-sdk-plugin/spymemcached-2.x-plugin/src/main/java/org/skywalking/apm/plugin/spymemcached/v2/define/MemcachedInstrumentation.java
0 → 100644
浏览文件 @
a20d6ea2
package
org.skywalking.apm.plugin.spymemcached.v2.define
;
import
static
org
.
skywalking
.
apm
.
agent
.
core
.
plugin
.
match
.
NameMatch
.
byName
;
import
java.util.List
;
import
org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint
;
import
org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint
;
import
org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine
;
import
org.skywalking.apm.agent.core.plugin.match.ClassMatch
;
import
net.bytebuddy.description.method.MethodDescription
;
import
net.bytebuddy.matcher.ElementMatcher
;
import
static
net
.
bytebuddy
.
matcher
.
ElementMatchers
.
named
;
import
static
net
.
bytebuddy
.
matcher
.
ElementMatchers
.
takesArgument
;
/**
*
* {@link MemcachedInstrumentation} presents that skywalking intercept all constructors and methods of
* {@link net.spy.memcached.MemcachedClient}.
* {@link XMemcachedConstructorWithInetSocketAddressListArgInterceptor} intercepts the constructor with
* argument {@link java.net.InetSocketAddress}.
*
* @author IluckySi
*
*/
public
class
MemcachedInstrumentation
extends
ClassInstanceMethodsEnhancePluginDefine
{
private
static
final
String
ENHANCE_CLASS
=
"net.spy.memcached.MemcachedClient"
;
private
static
final
String
CONSTRUCTOR_WITH_INETSOCKETADDRESS_LIST_ARG_INTERCEPT_CLASS
=
"org.skywalking.apm.plugin.spymemcached.v2.MemcachedConstructorWithInetSocketAddressListArgInterceptor"
;
private
static
final
String
METHOD_INTERCEPT_CLASS
=
"org.skywalking.apm.plugin.spymemcached.v2.MemcachedMethodInterceptor"
;
@Override
public
ClassMatch
enhanceClass
()
{
return
byName
(
ENHANCE_CLASS
);
}
@Override
protected
ConstructorInterceptPoint
[]
getConstructorsInterceptPoints
()
{
return
new
ConstructorInterceptPoint
[]
{
new
ConstructorInterceptPoint
()
{
@Override
public
ElementMatcher
<
MethodDescription
>
getConstructorMatcher
()
{
return
takesArgument
(
1
,
List
.
class
);
}
@Override
public
String
getConstructorInterceptor
()
{
return
CONSTRUCTOR_WITH_INETSOCKETADDRESS_LIST_ARG_INTERCEPT_CLASS
;
}
}
};
}
@Override
protected
InstanceMethodsInterceptPoint
[]
getInstanceMethodsInterceptPoints
()
{
return
new
InstanceMethodsInterceptPoint
[]
{
new
InstanceMethodsInterceptPoint
()
{
@Override
public
ElementMatcher
<
MethodDescription
>
getMethodsMatcher
()
{
return
named
(
"touch"
).
or
(
named
(
"append"
))
.
or
(
named
(
"prepend"
)).
or
(
named
(
"asyncCAS"
))
.
or
(
named
(
"cas"
))
.
or
(
named
(
"add"
)).
or
(
named
(
"set"
)).
or
(
named
(
"replace"
))
.
or
(
named
(
"asyncGet"
)).
or
(
named
(
"asyncGets"
)).
or
(
named
(
"gets"
)).
or
(
named
(
"getAndTouch"
))
.
or
(
named
(
"get"
)).
or
(
named
(
"asyncGetBulk"
))
.
or
(
named
(
"asyncGetAndTouch"
))
.
or
(
named
(
"getBulk"
)).
or
(
named
(
"getStats"
))
.
or
(
named
(
"incr"
))
.
or
(
named
(
"decr"
)).
or
(
named
(
"asyncIncr"
))
.
or
(
named
(
"asyncDecr"
))
.
or
(
named
(
"delete"
));
}
@Override
public
String
getMethodsInterceptor
()
{
return
METHOD_INTERCEPT_CLASS
;
}
@Override
public
boolean
isOverrideArgs
()
{
return
false
;
}
}
};
}
}
apm-sniffer/apm-sdk-plugin/spymemcached-2.x-plugin/src/main/resources/skywalking-plugin.def
0 → 100644
浏览文件 @
a20d6ea2
spymemcached-2.x=org.skywalking.apm.plugin.spymemcached.v2.define.MemcachedInstrumentation
\ No newline at end of file
apm-sniffer/apm-sdk-plugin/spymemcached-2.x-plugin/src/test/java/org/skywalking/apm/plugin/spymemcached/v2/MemcachedConstructorWithInetSocketAddressListArgInterceptorTest.java
0 → 100644
浏览文件 @
a20d6ea2
package
org.skywalking.apm.plugin.spymemcached.v2
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
java.net.InetSocketAddress
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.mockito.Mock
;
import
org.mockito.runners.MockitoJUnitRunner
;
import
org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance
;
@RunWith
(
MockitoJUnitRunner
.
class
)
public
class
MemcachedConstructorWithInetSocketAddressListArgInterceptorTest
{
private
MemcachedConstructorWithInetSocketAddressListArgInterceptor
interceptor
;
@Mock
private
EnhancedInstance
enhancedInstance
;
@Before
public
void
setUp
()
throws
Exception
{
interceptor
=
new
MemcachedConstructorWithInetSocketAddressListArgInterceptor
();
}
@Test
public
void
onConstructWithInetSocketAddressList
()
{
List
<
InetSocketAddress
>
inetSocketAddressList
=
new
ArrayList
<
InetSocketAddress
>();
inetSocketAddressList
.
add
(
new
InetSocketAddress
(
"127.0.0.1"
,
11211
));
inetSocketAddressList
.
add
(
new
InetSocketAddress
(
"127.0.0.2"
,
11211
));
interceptor
.
onConstruct
(
enhancedInstance
,
new
Object
[]{
null
,
inetSocketAddressList
});
verify
(
enhancedInstance
,
times
(
1
)).
setSkyWalkingDynamicField
(
"127.0.0.1:11211;127.0.0.2:11211"
);
}
}
apm-sniffer/apm-sdk-plugin/spymemcached-2.x-plugin/src/test/java/org/skywalking/apm/plugin/spymemcached/v2/MemcachedMethodInterceptorTest.java
0 → 100644
浏览文件 @
a20d6ea2
package
org.skywalking.apm.plugin.spymemcached.v2
;
import
static
junit
.
framework
.
TestCase
.
assertNotNull
;
import
static
org
.
hamcrest
.
CoreMatchers
.
is
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
java.lang.reflect.Method
;
import
java.util.List
;
import
org.hamcrest.CoreMatchers
;
import
org.junit.Assert
;
import
org.junit.Before
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.mockito.Mock
;
import
org.powermock.modules.junit4.PowerMockRunner
;
import
org.powermock.modules.junit4.PowerMockRunnerDelegate
;
import
org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan
;
import
org.skywalking.apm.agent.core.context.trace.LogDataEntity
;
import
org.skywalking.apm.agent.core.context.trace.SpanLayer
;
import
org.skywalking.apm.agent.core.context.trace.TraceSegment
;
import
org.skywalking.apm.agent.core.context.util.KeyValuePair
;
import
org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance
;
import
org.skywalking.apm.agent.test.helper.SegmentHelper
;
import
org.skywalking.apm.agent.test.helper.SpanHelper
;
import
org.skywalking.apm.agent.test.tools.AgentServiceRule
;
import
org.skywalking.apm.agent.test.tools.SegmentStorage
;
import
org.skywalking.apm.agent.test.tools.SegmentStoragePoint
;
import
org.skywalking.apm.agent.test.tools.TracingSegmentRunner
;
import
net.spy.memcached.MemcachedClient
;
@RunWith
(
PowerMockRunner
.
class
)
@PowerMockRunnerDelegate
(
TracingSegmentRunner
.
class
)
public
class
MemcachedMethodInterceptorTest
{
@SegmentStoragePoint
private
SegmentStorage
segmentStorage
;
@Rule
public
AgentServiceRule
serviceRule
=
new
AgentServiceRule
();
@Mock
private
EnhancedInstance
enhancedInstance
;
private
MemcachedMethodInterceptor
interceptor
;
private
Object
[]
allArgument
;
private
Class
[]
argumentType
;
@Before
public
void
setUp
()
throws
Exception
{
allArgument
=
new
Object
[]
{
"OperationKey"
,
"OperationValue"
};
argumentType
=
new
Class
[]
{
String
.
class
,
String
.
class
};
interceptor
=
new
MemcachedMethodInterceptor
();
when
(
enhancedInstance
.
getSkyWalkingDynamicField
()).
thenReturn
(
"127.0.0.1:11211"
);
}
@Test
public
void
testIntercept
()
throws
Throwable
{
interceptor
.
beforeMethod
(
enhancedInstance
,
getMockSetMethod
(),
allArgument
,
argumentType
,
null
);
interceptor
.
afterMethod
(
enhancedInstance
,
getMockGetMethod
(),
allArgument
,
argumentType
,
null
);
TraceSegment
traceSegment
=
segmentStorage
.
getTraceSegments
().
get
(
0
);
List
<
AbstractTracingSpan
>
spans
=
SegmentHelper
.
getSpans
(
traceSegment
);
assertThat
(
spans
.
size
(),
is
(
1
));
assertMemcacheSpan
(
spans
.
get
(
0
));
}
@Test
public
void
testInterceptWithException
()
throws
Throwable
{
interceptor
.
beforeMethod
(
enhancedInstance
,
getMockSetMethod
(),
allArgument
,
argumentType
,
null
);
interceptor
.
handleMethodException
(
enhancedInstance
,
getMockSetMethod
(),
allArgument
,
argumentType
,
new
RuntimeException
());
interceptor
.
afterMethod
(
enhancedInstance
,
getMockSetMethod
(),
allArgument
,
argumentType
,
null
);
TraceSegment
traceSegment
=
segmentStorage
.
getTraceSegments
().
get
(
0
);
List
<
AbstractTracingSpan
>
spans
=
SegmentHelper
.
getSpans
(
traceSegment
);
assertThat
(
spans
.
size
(),
is
(
1
));
assertMemcacheSpan
(
spans
.
get
(
0
));
assertLogData
(
SpanHelper
.
getLogs
(
spans
.
get
(
0
)));
}
private
void
assertLogData
(
List
<
LogDataEntity
>
logDataEntities
)
{
assertThat
(
logDataEntities
.
size
(),
is
(
1
));
LogDataEntity
logData
=
logDataEntities
.
get
(
0
);
Assert
.
assertThat
(
logData
.
getLogs
().
size
(),
is
(
4
));
Assert
.
assertThat
(
logData
.
getLogs
().
get
(
0
).
getValue
(),
CoreMatchers
.<
Object
>
is
(
"error"
));
Assert
.
assertThat
(
logData
.
getLogs
().
get
(
1
).
getValue
(),
CoreMatchers
.<
Object
>
is
(
RuntimeException
.
class
.
getName
()));
Assert
.
assertNull
(
logData
.
getLogs
().
get
(
2
).
getValue
());
assertNotNull
(
logData
.
getLogs
().
get
(
3
).
getValue
());
}
private
void
assertMemcacheSpan
(
AbstractTracingSpan
span
)
{
assertThat
(
span
.
getOperationName
(),
is
(
"SpyMemcached/set"
));
assertThat
(
span
.
isExit
(),
is
(
true
));
assertThat
(
SpanHelper
.
getComponentId
(
span
),
is
(
20
));
List
<
KeyValuePair
>
tags
=
SpanHelper
.
getTags
(
span
);
assertThat
(
tags
.
get
(
0
).
getValue
(),
is
(
"Memcache"
));
assertThat
(
tags
.
get
(
1
).
getValue
(),
is
(
"set OperationKey"
));
assertThat
(
SpanHelper
.
getLayer
(
span
),
is
(
SpanLayer
.
DB
));
}
private
Method
getMockSetMethod
()
{
try
{
return
MemcachedClient
.
class
.
getMethod
(
"set"
,
String
.
class
,
int
.
class
,
Object
.
class
);
}
catch
(
NoSuchMethodException
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
private
Method
getMockGetMethod
()
{
try
{
return
MemcachedClient
.
class
.
getMethod
(
"get"
,
String
.
class
);
}
catch
(
NoSuchMethodException
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录