提交 9f912d00 编写于 作者: A ascrutae

support resttemplate plugin

上级 303cc1ca
......@@ -31,6 +31,8 @@ public class ComponentsDefine {
public static final OfficialComponent OKHTTP = new OfficialComponent(12, "OKHttp");
public static final OfficialComponent REST_TEMPLATE = new OfficialComponent(13, "RestTemplate");
private static ComponentsDefine instance = new ComponentsDefine();
private String[] components;
......@@ -40,7 +42,7 @@ public class ComponentsDefine {
}
public ComponentsDefine() {
components = new String[13];
components = new String[14];
addComponent(TOMCAT);
addComponent(HTTPCLIENT);
addComponent(DUBBO);
......@@ -53,6 +55,7 @@ public class ComponentsDefine {
addComponent(RESIN);
addComponent(FEIGN);
addComponent(OKHTTP);
addComponent(REST_TEMPLATE);
}
private void addComponent(OfficialComponent component) {
......
......@@ -80,6 +80,16 @@
<artifactId>apm-feign-default-http-9.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-resttemplate-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-spring-concurrent-util-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<!-- activation -->
<dependency>
......
......@@ -22,6 +22,7 @@
<module>okhttp-3.x-plugin</module>
<module>resin-3.x-plugin</module>
<module>resin-4.x-plugin</module>
<module>spring-plugins</module>
</modules>
<packaging>pom</packaging>
......
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-plugins</artifactId>
<groupId>org.skywalking</groupId>
<version>3.2-2017</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apm-spring-concurrent-util-plugin</artifactId>
<packaging>jar</packaging>
<name>concurrent-util-4.3.x-plugin</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.8.RELEASE</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
package org.skywalking.apm.plugin.spring.concurrent;
import java.net.URI;
import org.skywalking.apm.agent.core.context.ContextManager;
import org.skywalking.apm.agent.core.context.ContextSnapshot;
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 FailureCallbackInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
Object[] cacheValues = (Object[])objInst.getSkyWalkingDynamicField();
if (cacheValues == null) {
return;
}
URI uri = (URI)cacheValues[0];
AbstractSpan span = ContextManager.createLocalSpan("future/failureCallback:" + uri.getPath());
span.errorOccurred().log((Throwable)allArguments[0]).setComponent(ComponentsDefine.REST_TEMPLATE).setLayer(SpanLayer.HTTP);
Tags.URL.set(span, uri.getPath());
ContextManager.continued((ContextSnapshot)cacheValues[2]);
}
@Override
public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Object ret) throws Throwable {
ContextManager.stopSpan();
return ret;
}
@Override
public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
ContextManager.activeSpan().errorOccurred().log(t);
}
}
package org.skywalking.apm.plugin.spring.concurrent;
import java.net.URI;
import org.skywalking.apm.agent.core.context.ContextManager;
import org.skywalking.apm.agent.core.context.ContextSnapshot;
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 SuccessCallbackInterceptor implements InstanceMethodsAroundInterceptor {
@Override public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
Object[] cacheValues = (Object[])objInst.getSkyWalkingDynamicField();
if (cacheValues == null) {
return;
}
URI uri = (URI)cacheValues[0];
AbstractSpan span = ContextManager.createLocalSpan("future/successCallback:" + uri.getPath());
span.setComponent(ComponentsDefine.REST_TEMPLATE).setLayer(SpanLayer.HTTP);
Tags.URL.set(span, uri.getPath());
ContextManager.continued((ContextSnapshot)cacheValues[2]);
}
@Override public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Object ret) throws Throwable {
ContextManager.stopSpan();
return ret;
}
@Override public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
ContextManager.activeSpan().errorOccurred().log(t);
}
}
package org.skywalking.apm.plugin.spring.concurrent.define;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
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 org.skywalking.apm.plugin.spring.concurrent.FailureCallbackInterceptor;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.skywalking.apm.plugin.spring.concurrent.match.FailedCallbackMatch.failedCallbackMatch;
/**
* {@link FailureCallbackInstrumentation} enhance the onFailure method that class inherited
* <code>org.springframework.util.concurrent.FailureCallback</code> by {@link FailureCallbackInterceptor}.
*
* @author zhangxin
*/
public class FailureCallbackInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
public static final String FAILURE_CALLBACK_INTERCEPTOR = "org.skywalking.apm.plugin.spring.concurrent.FailureCallbackInterceptor";
public static final String FAILURE_METHOD_NAME = "onFailure";
@Override
protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override
protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(FAILURE_METHOD_NAME);
}
@Override
public String getMethodsInterceptor() {
return FAILURE_CALLBACK_INTERCEPTOR;
}
@Override
public boolean isOverrideArgs() {
return false;
}
}
};
}
@Override
protected ClassMatch enhanceClass() {
return failedCallbackMatch();
}
}
package org.skywalking.apm.plugin.spring.concurrent.define;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
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 org.skywalking.apm.plugin.spring.concurrent.FailureCallbackInterceptor;
import org.skywalking.apm.plugin.spring.concurrent.SuccessCallbackInterceptor;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.skywalking.apm.plugin.spring.concurrent.match.ListenableFutureCallbackMatch.listenableFutureCallbackMatch;
/**
* {@link ListenableFutureCallbackInstrumentation} enhance <code>onSuccess</code> method and <code>oonFailure</code>
* that class inherited <code>org.springframework.util.concurrent.ListenableFutureCallback</code> by {@link
* SuccessCallbackInterceptor} and {@link FailureCallbackInterceptor }.
*
* @author zhangxin
*/
public class ListenableFutureCallbackInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
@Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(SuccessCallbackInstrumentation.SUCCESS_METHOD_NAME);
}
@Override public String getMethodsInterceptor() {
return SuccessCallbackInstrumentation.SUCCESS_CALLBACK_INTERCEPTOR;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(FailureCallbackInstrumentation.FAILURE_METHOD_NAME);
}
@Override
public String getMethodsInterceptor() {
return FailureCallbackInstrumentation.FAILURE_CALLBACK_INTERCEPTOR;
}
@Override
public boolean isOverrideArgs() {
return false;
}
}
};
}
@Override protected ClassMatch enhanceClass() {
return listenableFutureCallbackMatch();
}
}
package org.skywalking.apm.plugin.spring.concurrent.define;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
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 org.skywalking.apm.plugin.spring.concurrent.FailureCallbackInterceptor;
import org.skywalking.apm.plugin.spring.concurrent.SuccessCallbackInterceptor;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.skywalking.apm.plugin.spring.concurrent.match.SuccessCallbackMatch.successCallbackMatch;
/**
* {@link SuccessCallbackInstrumentation} enhance the <code>onSuccess</code> method that class inherited
* <code>org.springframework.util.concurrent.SuccessCallback</code> by {@link SuccessCallbackInterceptor}.
*
* @author zhangxin
*/
public class SuccessCallbackInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
public static final String SUCCESS_CALLBACK_INTERCEPTOR = "org.skywalking.apm.plugin.spring.concurrent.SuccessCallbackInterceptor";
public static final String SUCCESS_METHOD_NAME = "onSuccess";
@Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(SUCCESS_METHOD_NAME);
}
@Override public String getMethodsInterceptor() {
return SUCCESS_CALLBACK_INTERCEPTOR;
}
@Override public boolean isOverrideArgs() {
return false;
}
}
};
}
@Override protected ClassMatch enhanceClass() {
return successCallbackMatch();
}
}
package org.skywalking.apm.plugin.spring.concurrent.match;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.skywalking.apm.agent.core.plugin.match.IndirectMatch;
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
/**
* {@link EitherInterfaceMatch} match the class inherited {@link #getMatchInterface() } and not inherited {@link
* #getMutexInterface()}
*
* @author zhangxin
*/
public abstract class EitherInterfaceMatch implements IndirectMatch {
private static final String SPRING_PACKAGE_PREFIX = "org.springframework";
private static final String OBJECT_CLASS_NAME = "java.lang.Object";
protected EitherInterfaceMatch() {
}
@Override
public ElementMatcher.Junction buildJunction() {
return not(nameStartsWith(SPRING_PACKAGE_PREFIX)).
and(hasSuperType(named(getMatchInterface())))
.and(not(hasSuperType(named(getMutexInterface()))));
}
@Override
public boolean isMatch(TypeDescription typeDescription) {
MatchResult matchResult = new MatchResult();
for (TypeDescription.Generic generic : typeDescription.getInterfaces()) {
matchHierarchyClazz(generic, matchResult);
}
matchHierarchyClazz(typeDescription.getSuperClass(), matchResult);
return matchResult.result();
}
public abstract String getMatchInterface();
public abstract String getMutexInterface();
private void matchHierarchyClazz(TypeDescription.Generic clazz, MatchResult matchResult) {
if (clazz.asRawType().getTypeName().equals(getMutexInterface())) {
matchResult.findMutexInterface = true;
return;
}
if (clazz.asRawType().getTypeName().equals(getMatchInterface())) {
matchResult.findMatchInterface = true;
}
for (TypeDescription.Generic generic : clazz.getInterfaces()) {
matchHierarchyClazz(generic, matchResult);
}
TypeDescription.Generic superClazz = clazz.getSuperClass();
if (superClazz != null && !clazz.getTypeName().equals(OBJECT_CLASS_NAME)) {
matchHierarchyClazz(superClazz, matchResult);
}
}
private static class MatchResult {
private boolean findMatchInterface = false;
private boolean findMutexInterface = false;
public boolean result() {
return findMatchInterface && !findMutexInterface;
}
}
}
package org.skywalking.apm.plugin.spring.concurrent.match;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
/**
* {@link FailedCallbackMatch} match the class that inherited <code>org.springframework.util.concurrent.FailureCallback</code>
* and not inherited <code>org.springframework.util.concurrent.SuccessCallback</code>
*
* @author zhangxin
*/
public class FailedCallbackMatch extends EitherInterfaceMatch {
private static final String MATCH_INTERFACE = "org.springframework.util.concurrent.FailureCallback";
private static final String MUTEX_INTERFACE = "org.springframework.util.concurrent.SuccessCallback";
private FailedCallbackMatch() {
}
@Override public String getMatchInterface() {
return MATCH_INTERFACE;
}
@Override public String getMutexInterface() {
return MUTEX_INTERFACE;
}
public static ClassMatch failedCallbackMatch() {
return new FailedCallbackMatch();
}
}
package org.skywalking.apm.plugin.spring.concurrent.match;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.skywalking.apm.agent.core.plugin.match.IndirectMatch;
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
/**
* {@link ListenableFutureCallbackMatch} match the class that inherited <code>org.springframework.util.concurrent.ListenableFutureCallback</code>.
*
* @author zhangxin
*/
public class ListenableFutureCallbackMatch implements IndirectMatch {
private static final String LISTENABLE_FUTURE_CALLBACK_CLASS_NAME = "org.springframework.util.concurrent.ListenableFutureCallback";
private ListenableFutureCallbackMatch() {
}
@Override
public ElementMatcher.Junction buildJunction() {
return not(nameStartsWith("org.springframework")).
and(hasSuperType(named(LISTENABLE_FUTURE_CALLBACK_CLASS_NAME)));
}
@Override
public boolean isMatch(TypeDescription typeDescription) {
boolean isMatch = false;
for (TypeDescription.Generic generic : typeDescription.getInterfaces()) {
isMatch = isMatch || matchExactClass(generic);
}
return isMatch || matchExactClass(typeDescription.getSuperClass());
}
private boolean matchExactClass(TypeDescription.Generic clazz) {
if (clazz.asRawType().getTypeName().equals(LISTENABLE_FUTURE_CALLBACK_CLASS_NAME)) {
return true;
}
boolean isMatch = false;
for (TypeDescription.Generic generic : clazz.getInterfaces()) {
isMatch = isMatch || matchExactClass(generic);
}
if (!isMatch) {
TypeDescription.Generic superClazz = clazz.getSuperClass();
if (superClazz != null && !clazz.getTypeName().equals("java.lang.Object")) {
isMatch = isMatch || matchExactClass(superClazz);
}
}
return isMatch;
}
public static ClassMatch listenableFutureCallbackMatch() {
return new ListenableFutureCallbackMatch();
}
}
package org.skywalking.apm.plugin.spring.concurrent.match;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
/**
* {@link SuccessCallbackMatch} match the class that inherited <code>org.springframework.util.concurrent.SuccessCallback</code>
* and not inherited <code>org.springframework.util.concurrent.FailureCallback</code>
*
* @author zhangxin
*/
public class SuccessCallbackMatch extends EitherInterfaceMatch {
private static final String MATCH_INTERFACE = "org.springframework.util.concurrent.SuccessCallback";
private static final String MUTEX_INTERFACE = "org.springframework.util.concurrent.FailureCallback";
private SuccessCallbackMatch() {
}
@Override
public String getMatchInterface() {
return MATCH_INTERFACE;
}
@Override
public String getMutexInterface() {
return MUTEX_INTERFACE;
}
public static ClassMatch successCallbackMatch() {
return new SuccessCallbackMatch();
}
}
spring-concurrent-util-4.3.8=org.skywalking.apm.plugin.spring.concurrent.define.FailureCallbackInstrumentation
spring-concurrent-util-4.3.8=org.skywalking.apm.plugin.spring.concurrent.define.SuccessCallbackInstrumentation
spring-concurrent-util-4.3.8=org.skywalking.apm.plugin.spring.concurrent.define.ListenableFutureCallbackInstrumentation
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.skywalking</groupId>
<artifactId>apm-sdk-plugin</artifactId>
<version>3.2-2017</version>
</parent>
<artifactId>spring-plugins</artifactId>
<modules>
<module>concurrent-util-4.3.x-plugin</module>
<module>resttemplate-4.3.x-plugin</module>
</modules>
<packaging>pom</packaging>
<name>apm-sdk-plugin</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-plugins</artifactId>
<groupId>org.skywalking</groupId>
<version>3.2-2017</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apm-resttemplate-plugin</artifactId>
<packaging>jar</packaging>
<name>resttemplate-4.3.x-plugin</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.8.RELEASE</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
package org.skywalking.apm.plugin.spring.resttemplate.async;
import com.google.instrumentation.trace.Span;
import java.net.URI;
import java.util.List;
import org.skywalking.apm.agent.core.context.ContextManager;
import org.skywalking.apm.agent.core.context.trace.AbstractSpan;
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;
public class FutureGetInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
List<Object> cacheValues = (List<Object>)objInst.getSkyWalkingDynamicField();
ContextManager.createLocalSpan("future/get:" + ((URI)cacheValues.get(0)).getPath());
}
@Override
public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Object ret) throws Throwable {
ContextManager.stopSpan();
return ret;
}
@Override
public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
AbstractSpan activeSpan = ContextManager.activeSpan();
activeSpan.errorOccurred().log(t);
}
}
package org.skywalking.apm.plugin.spring.resttemplate.async;
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;
public class ResponseCallBackInterceptor implements InstanceMethodsAroundInterceptor {
@Override public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
EnhancedInstance successCallBak = (EnhancedInstance)allArguments[0];
successCallBak.setSkyWalkingDynamicField(objInst.getSkyWalkingDynamicField());
if (allArguments.length == 2) {
EnhancedInstance failedCallBack = (EnhancedInstance)allArguments[1];
failedCallBack.setSkyWalkingDynamicField(objInst.getSkyWalkingDynamicField());
}
}
@Override public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Object ret) throws Throwable {
return ret;
}
@Override public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
}
}
package org.skywalking.apm.plugin.spring.resttemplate.async;
import java.net.URI;
import org.skywalking.apm.agent.core.context.ContextCarrier;
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;
import org.springframework.http.HttpMethod;
public class RestExecuteInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
final URI requestURL = (URI)allArguments[0];
final HttpMethod httpMethod = (HttpMethod)allArguments[1];
final ContextCarrier contextCarrier = new ContextCarrier();
String remotePeer = requestURL.getHost() + ":" + requestURL.getPort();
AbstractSpan span = ContextManager.createExitSpan(requestURL.getPath(), contextCarrier, remotePeer);
span.setComponent(ComponentsDefine.REST_TEMPLATE);
Tags.URL.set(span, requestURL.getScheme() + "://" + requestURL.getHost() + ":" + requestURL.getPort() + requestURL.getPath());
Tags.HTTP.METHOD.set(span, httpMethod.toString());
SpanLayer.asHttp(span);
Object[] cacheValues = new Object[3];
cacheValues[0] = requestURL;
cacheValues[1] = contextCarrier.serialize();
objInst.setSkyWalkingDynamicField(cacheValues);
}
@Override
public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Object ret) throws Throwable {
Object[] cacheValues = (Object[])objInst.getSkyWalkingDynamicField();
cacheValues[3] = ContextManager.capture();
((EnhancedInstance)ret).setSkyWalkingDynamicField(cacheValues);
ContextManager.stopSpan();
return ret;
}
@Override
public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
ContextManager.activeSpan().errorOccurred().log(t);
}
}
package org.skywalking.apm.plugin.spring.resttemplate.async.define;
import java.net.URI;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.skywalking.apm.agent.core.context.ContextSnapshot;
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 org.skywalking.apm.plugin.spring.resttemplate.async.ResponseCallBackInterceptor;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
/**
* {@link ResponseExtractorFutureInstrumentation} enhance the <code>addCallback</code> method and <code>get</code> method of
* <code>org.springframework.web.client.AsyncRestTemplate$ResponseExtractorFuture</code> by
* <code>org.skywalking.apm.plugin.spring.resttemplate.async.ResponseCallBackInterceptor</code> and
* <code>org.skywalking.apm.plugin.spring.resttemplate.async.FutureGetInterceptor</code>.
*
* {@link ResponseCallBackInterceptor} set the {@link URI} and {@link ContextSnapshot} to inherited
* <code>org.springframework.util.concurrent.SuccessCallback</code> and <code>org.springframework.util.concurrent.FailureCallback</code>
*
* @author zhangxin
*/
public class ResponseExtractorFutureInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String ADD_CALLBACK_METHOD_NAME = "addCallback";
private static final String ADD_CALLBACK_INTERCEPTOR = "org.skywalking.apm.plugin.spring.resttemplate.async.ResponseCallBackInterceptor";
private static final String ENHANCE_CLASS = "org.springframework.web.client.AsyncRestTemplate$ResponseExtractorFuture";
private static final String GET_METHOD_INTERCEPTOR = "org.skywalking.apm.plugin.spring.resttemplate.async.FutureGetInterceptor";
private static final String GET_METHOD_NAME = "get";
@Override
protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override
protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(ADD_CALLBACK_METHOD_NAME);
}
@Override public String getMethodsInterceptor() {
return ADD_CALLBACK_INTERCEPTOR;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(GET_METHOD_NAME);
}
@Override public String getMethodsInterceptor() {
return GET_METHOD_INTERCEPTOR;
}
@Override public boolean isOverrideArgs() {
return false;
}
}
};
}
@Override
protected ClassMatch enhanceClass() {
return byName(ENHANCE_CLASS);
}
}
package org.skywalking.apm.plugin.spring.resttemplate.async.define;
import java.net.URI;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.skywalking.apm.agent.core.context.ContextSnapshot;
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 org.skywalking.apm.plugin.spring.resttemplate.async.FutureGetInterceptor;
import org.skywalking.apm.plugin.spring.resttemplate.async.ResponseCallBackInterceptor;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
/**
* {@link RestTemplateInstrumentation} enhance the <code>doExecute</code> method and <code>createAsyncRequest</code>
* method of <code>org.springframework.web.client.AsyncRestTemplate</code> by <code>org.skywalking.apm.plugin.spring.resttemplate.async.RestExecuteInterceptor</code>
* and <code>org.springframework.http.client.RestRequestInterceptor</code>.
*
* <code>org.springframework.http.client.RestRequestInterceptor</code> set {@link URI} and {@link ContextSnapshot} to
* <code>org.springframework.web.client.AsyncRestTemplate$ResponseExtractorFuture</code> for propagate trace context
* after execute <code>doExecute</code> .
*
* @author zhangxin
*/
public class RestTemplateInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String ENHANCE_CLASS = "org.springframework.web.client.AsyncRestTemplate";
private static final String DO_EXECUTE_METHOD_NAME = "doExecute";
private static final String DO_EXECUTE_INTERCEPTOR = "org.skywalking.apm.plugin.spring.resttemplate.async.RestExecuteInterceptor";
private static final String CREATE_REQUEST_METHOD_NAME = "createAsyncRequest";
private static final String CREATE_REQUEST_INTERCEPTOR = "org.springframework.http.client.RestRequestInterceptor";
@Override
protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override
protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(DO_EXECUTE_METHOD_NAME);
}
@Override public String getMethodsInterceptor() {
return DO_EXECUTE_INTERCEPTOR;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(CREATE_REQUEST_METHOD_NAME);
}
@Override public String getMethodsInterceptor() {
return CREATE_REQUEST_INTERCEPTOR;
}
@Override public boolean isOverrideArgs() {
return false;
}
}
};
}
@Override
protected ClassMatch enhanceClass() {
return byName(ENHANCE_CLASS);
}
}
package org.skywalking.apm.plugin.spring.resttemplate.sync;
import java.net.URI;
import org.skywalking.apm.agent.core.context.ContextCarrier;
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;
import org.springframework.http.HttpMethod;
public class RestExecuteInterceptor implements InstanceMethodsAroundInterceptor {
@Override public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
final URI requestURL = (URI)allArguments[0];
final HttpMethod httpMethod = (HttpMethod)allArguments[1];
final ContextCarrier contextCarrier = new ContextCarrier();
String remotePeer = requestURL.getHost() + ":" + requestURL.getPort();
AbstractSpan span = ContextManager.createExitSpan(requestURL.getPath(), contextCarrier, remotePeer);
span.setComponent(ComponentsDefine.REST_TEMPLATE);
Tags.URL.set(span, requestURL.getScheme() + "://" + requestURL.getHost() + ":" + requestURL.getPort() + requestURL.getPath());
Tags.HTTP.METHOD.set(span, httpMethod.toString());
SpanLayer.asHttp(span);
objInst.setSkyWalkingDynamicField(contextCarrier.serialize());
}
@Override public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Object ret) throws Throwable {
ContextManager.stopSpan();
return ret;
}
@Override public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
ContextManager.activeSpan().errorOccurred().log(t);
}
}
package org.skywalking.apm.plugin.spring.resttemplate.sync;
import org.skywalking.apm.agent.core.conf.Config;
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.springframework.http.client.AbstractClientHttpRequest;
import org.springframework.http.client.ClientHttpRequest;
public class RestRequestInterceptor implements InstanceMethodsAroundInterceptor {
@Override public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
}
@Override public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Object ret) throws Throwable {
ClientHttpRequest clientHttpRequest = (ClientHttpRequest)ret;
if (clientHttpRequest instanceof AbstractClientHttpRequest) {
AbstractClientHttpRequest httpRequest = (AbstractClientHttpRequest)clientHttpRequest;
httpRequest.getHeaders().set(Config.Plugin.Propagation.HEADER_NAME, String.valueOf(objInst.getSkyWalkingDynamicField()));
}
return ret;
}
@Override public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
}
}
package org.skywalking.apm.plugin.spring.resttemplate.sync;
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.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.springframework.http.client.ClientHttpResponse;
public class RestResponseInterceptor implements InstanceMethodsAroundInterceptor {
@Override public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
}
@Override public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Object ret) throws Throwable {
ClientHttpResponse response = (ClientHttpResponse)allArguments[2];
int statusCode = response.getStatusCode().value();
AbstractSpan span = ContextManager.activeSpan();
if (statusCode >= 400) {
span.errorOccurred();
Tags.STATUS_CODE.set(span, Integer.toString(statusCode));
}
return ret;
}
@Override public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
ContextManager.activeSpan().errorOccurred().log(t);
}
}
package org.skywalking.apm.plugin.spring.resttemplate.sync.define;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
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 static net.bytebuddy.matcher.ElementMatchers.named;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
/**
* {@link RestTemplateInstrumentation} enhance the <code>doExecute</code> method,<code>handleResponse</code> method and
* <code>handleResponse</code> method of <code>org.springframework.web.client.RestTemplate</code> by
* <code>org.skywalking.apm.plugin.spring.resttemplate.sync.RestExecuteInterceptor</code>,
* <code>org.skywalking.apm.plugin.spring.resttemplate.sync.RestResponseInterceptor</code> and
* <code>org.skywalking.apm.plugin.spring.resttemplate.sync.RestRequestInterceptor</code>.
*
* <code>org.skywalking.apm.plugin.spring.resttemplate.sync.RestResponseInterceptor</code> set context to header for
* propagate trace context after execute <code>createRequest</code>.
*
* @author zhangxin
*/
public class RestTemplateInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String ENHANCE_CLASS = "org.springframework.web.client.RestTemplate";
private static final String DO_EXECUTE_METHOD_NAME = "doExecute";
private static final String DO_EXECUTE_INTERCEPTOR = "org.skywalking.apm.plugin.spring.resttemplate.sync.RestExecuteInterceptor";
private static final String HANDLE_REQUEST_METHOD_NAME = "handleResponse";
private static final String HAND_REQUEST_INTERCEPTOR = "org.skywalking.apm.plugin.spring.resttemplate.sync.RestResponseInterceptor";
private static final String CREATE_REQUEST_METHOD_NAME = "createRequest";
private static final String CREATE_REQUEST_INTERCEPTOR = "org.skywalking.apm.plugin.spring.resttemplate.sync.RestRequestInterceptor";
@Override
protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override
protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(DO_EXECUTE_METHOD_NAME);
}
@Override public String getMethodsInterceptor() {
return DO_EXECUTE_INTERCEPTOR;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(HANDLE_REQUEST_METHOD_NAME);
}
@Override public String getMethodsInterceptor() {
return HAND_REQUEST_INTERCEPTOR;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(CREATE_REQUEST_METHOD_NAME);
}
@Override public String getMethodsInterceptor() {
return CREATE_REQUEST_INTERCEPTOR;
}
@Override public boolean isOverrideArgs() {
return false;
}
}
};
}
@Override
protected ClassMatch enhanceClass() {
return byName(ENHANCE_CLASS);
}
}
package org.springframework.http.client;
import java.util.List;
import org.skywalking.apm.agent.core.conf.Config;
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;
public class RestRequestInterceptor implements InstanceMethodsAroundInterceptor {
@Override public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
}
@Override public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Object ret) throws Throwable {
AbstractAsyncClientHttpRequest clientHttpRequest = (AbstractAsyncClientHttpRequest)ret;
clientHttpRequest.getHeaders().set(Config.Plugin.Propagation.HEADER_NAME, String.valueOf(((List<Object>)objInst.getSkyWalkingDynamicField()).get(1)));
return ret;
}
@Override public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
}
}
spring-resttemplate-4.3.8=org.skywalking.apm.plugin.spring.resttemplate.async.define.RestTemplateInstrumentation
spring-resttemplate-4.3.8=org.skywalking.apm.plugin.spring.resttemplate.async.define.ResponseExtractorFutureInstrumentation
spring-resttemplate-4.3.8=org.skywalking.apm.plugin.spring.resttemplate.sync.define.RestTemplateInstrumentation
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册