Skip to content

Commit

Permalink
Merge pull request #455 from wu-sheng/dev/3.2.1
Browse files Browse the repository at this point in the history
Sync Dev/3.2.1
  • Loading branch information
wu-sheng committed Sep 23, 2017
2 parents e588186 + 5ab84c2 commit 38cf773
Show file tree
Hide file tree
Showing 19 changed files with 584 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ public class ComponentsDefine {

public static final OfficialComponent SPRING_MVC_ANNOTATION = new OfficialComponent(14, "SpringMVC");

public static final OfficialComponent STRUTS2 = new OfficialComponent(14, "Struts2");
public static final OfficialComponent STRUTS2 = new OfficialComponent(15, "Struts2");

public static final OfficialComponent NUTZ_MVC_ANNOTATION = new OfficialComponent(16, "NutzMVC");

public static final OfficialComponent NUTZ_HTTP = new OfficialComponent(17, "NutzHttp");

private static ComponentsDefine instance = new ComponentsDefine();

Expand All @@ -46,7 +50,7 @@ public static ComponentsDefine getInstance() {
}

public ComponentsDefine() {
components = new String[16];
components = new String[18];
addComponent(TOMCAT);
addComponent(HTTPCLIENT);
addComponent(DUBBO);
Expand All @@ -62,6 +66,8 @@ public ComponentsDefine() {
addComponent(SPRING_REST_TEMPLATE);
addComponent(SPRING_MVC_ANNOTATION);
addComponent(STRUTS2);
addComponent(NUTZ_MVC_ANNOTATION);
addComponent(NUTZ_HTTP);
}

private void addComponent(OfficialComponent component) {
Expand Down
10 changes: 10 additions & 0 deletions apm-sniffer/apm-agent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@
<artifactId>apm-struts2-2.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-nutz-mvc-annotation-1.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-nutz-http-1.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>

<!-- activation -->
<dependency>
Expand Down
24 changes: 24 additions & 0 deletions apm-sniffer/apm-sdk-plugin/nutz-plugins/http-1.x-plugin/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<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>nutz-plugins</artifactId>
<groupId>org.skywalking</groupId>
<version>3.2.1-2017</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>apm-nutz-http-1.x-plugin</artifactId>
<packaging>jar</packaging>

<name>http-1.x-plugin</name>
<url>http://maven.apache.org</url>

<dependencies>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutz</artifactId>
<version>1.r.62</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.skywalking.apm.plugin.nutz.http.sync;

import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;

public class SenderConstructorInterceptor implements InstanceConstructorInterceptor {

@Override
public void onConstruct(final EnhancedInstance objInst, final Object[] allArguments) {
objInst.setSkyWalkingDynamicField(allArguments[0]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.skywalking.apm.plugin.nutz.http.sync;

import java.lang.reflect.Method;
import java.net.URI;

import org.nutz.http.Request;
import org.nutz.http.Request.METHOD;
import org.nutz.http.Response;
import org.skywalking.apm.agent.core.context.CarrierItem;
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;

public class SenderSendInterceptor implements InstanceMethodsAroundInterceptor {

@Override
public void beforeMethod(final EnhancedInstance objInst, final Method method, final Object[] allArguments, final Class<?>[] argumentsTypes,
final MethodInterceptResult result) throws Throwable {
Request req = (Request) objInst.getSkyWalkingDynamicField();
final URI requestURL = req.getUrl().toURI();
final METHOD httpMethod = req.getMethod();
final ContextCarrier contextCarrier = new ContextCarrier();
String remotePeer = requestURL.getHost() + ":" + requestURL.getPort();
AbstractSpan span = ContextManager.createExitSpan(requestURL.getPath(), contextCarrier, remotePeer);

span.setComponent(ComponentsDefine.NUTZ_HTTP);
Tags.URL.set(span, requestURL.getScheme() + "://" + requestURL.getHost() + ":" + requestURL.getPort() + requestURL.getPath());
Tags.HTTP.METHOD.set(span, httpMethod.toString());
SpanLayer.asHttp(span);

CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
req.getHeader().set(next.getHeadKey(), next.getHeadValue());
}
}

@Override
public Object afterMethod(final EnhancedInstance objInst, final Method method, final Object[] allArguments, final Class<?>[] argumentsTypes,
Object ret) throws Throwable {
Response response = (Response)ret;
int statusCode = response.getStatus();
AbstractSpan span = ContextManager.activeSpan();
if (statusCode >= 400) {
span.errorOccurred();
Tags.STATUS_CODE.set(span, Integer.toString(statusCode));
}
ContextManager.stopSpan();
return ret;
}

@Override
public void handleMethodException(final EnhancedInstance objInst, final Method method, final Object[] allArguments,
final Class<?>[] argumentsTypes, final Throwable t) {
ContextManager.activeSpan().errorOccurred().log(t);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package org.skywalking.apm.plugin.nutz.http.sync.define;

import static net.bytebuddy.matcher.ElementMatchers.named;

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 net.bytebuddy.matcher.ElementMatchers;

public abstract class AbstractNutzHttpInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {

private static final String DO_SEND_METHOD_NAME = "send";
private static final String DO_SEND_INTERCEPTOR = "org.skywalking.apm.plugin.nutz.http.sync.SenderSendInterceptor";
private static final String DO_CONSTRUCTOR_INTERCEPTOR = "org.skywalking.apm.plugin.nutz.http.sync.SenderConstructorInterceptor";

@Override
protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[]{
new ConstructorInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getConstructorMatcher() {
return ElementMatchers.takesArguments(1);
}

@Override
public String getConstructorInterceptor() {
return DO_CONSTRUCTOR_INTERCEPTOR;
}
}
};
}

@Override
protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[]{
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(DO_SEND_METHOD_NAME);
}

@Override
public String getMethodsInterceptor() {
return DO_SEND_INTERCEPTOR;
}

@Override
public boolean isOverrideArgs() {
return false;
}
}
};
}

protected abstract ClassMatch enhanceClass();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.skywalking.apm.plugin.nutz.http.sync.define;

import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.skywalking.apm.agent.core.plugin.match.NameMatch;

public class NutzHttpFilePostSenderInstrumentation extends AbstractNutzHttpInstrumentation {

protected ClassMatch enhanceClass() {
return NameMatch.byName("org.nutz.http.sender.FilePostSender");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.skywalking.apm.plugin.nutz.http.sync.define;

import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.skywalking.apm.agent.core.plugin.match.NameMatch;

public class NutzHttpGetSenderInstrumentation extends AbstractNutzHttpInstrumentation {

@Override
protected ClassMatch enhanceClass() {
return NameMatch.byName("org.nutz.http.sender.GetSender");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.skywalking.apm.plugin.nutz.http.sync.define;

import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.skywalking.apm.agent.core.plugin.match.NameMatch;


public class NutzHttpPostSenderInstrumentation extends AbstractNutzHttpInstrumentation {

@Override
protected ClassMatch enhanceClass() {
return NameMatch.byName("org.nutz.http.sender.PostSender");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
nutz-http-1.x=org.skywalking.apm.plugin.nutz.http.sync.define.NutzHttpGetSenderInstrumentation
nutz-http-1.x=org.skywalking.apm.plugin.nutz.http.sync.define.NutzHttpPostSenderInstrumentation
nutz-http-1.x=org.skywalking.apm.plugin.nutz.http.sync.define.NutzHttpFilePostSenderInstrumentation
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package org.skywalking.apm.plugin.nutz.http.sync;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.lang.reflect.Method;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.nutz.http.Request;
import org.nutz.http.Request.METHOD;
import org.nutz.http.Response;
import org.nutz.http.Sender;
import org.nutz.http.sender.FilePostSender;
import org.nutz.http.sender.GetSender;
import org.nutz.http.sender.PostSender;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
import org.skywalking.apm.agent.core.boot.ServiceManager;
import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
import org.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.test.helper.SegmentHelper;
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;

@RunWith(org.powermock.modules.junit4.PowerMockRunner.class)
@PowerMockRunnerDelegate(TracingSegmentRunner.class)
public class SenderInterceptorTest {

@SegmentStoragePoint
public SegmentStorage segmentStorage;

@Rule
public AgentServiceRule serviceRule = new AgentServiceRule();

@Mock
private EnhancedInstance enhancedInstance;

@Mock
Response resp;

SenderConstructorInterceptor constructorInterceptPoint;

SenderSendInterceptor senderSendInterceptor;

Method sendMethod;
Object[] allArguments;
Class<?>[] argumentsTypes;

@Before
public void setUp() throws Exception {
ServiceManager.INSTANCE.boot();
constructorInterceptPoint = new SenderConstructorInterceptor();
senderSendInterceptor = new SenderSendInterceptor();
}

public void setupSender(Class<? extends Sender> klass) throws NoSuchMethodException, SecurityException {
sendMethod = klass.getMethod("send");
allArguments = new Object[0];
argumentsTypes = new Class<?>[0];
}

@Test
public void test_constructor() {
Request request = Request.create("https://nutz.cn/yvr/list", METHOD.GET);
constructorInterceptPoint.onConstruct(enhancedInstance, new Object[]{request});
verify(enhancedInstance, times(1)).setSkyWalkingDynamicField(request);
}

@Test
public void test_getsender_send() throws NoSuchMethodException, SecurityException, Throwable {
setupSender(GetSender.class);
_sender_sender_test();
}

@Test
public void test_postsender_send() throws NoSuchMethodException, SecurityException, Throwable {
setupSender(PostSender.class);
_sender_sender_test();
}

@Test
public void test_filepostsender_send() throws NoSuchMethodException, SecurityException, Throwable {
setupSender(FilePostSender.class);
_sender_sender_test();
}

protected void _sender_sender_test() throws Throwable {
Request request = Request.create("https://nutz.cn/yvr/list", METHOD.GET);
constructorInterceptPoint.onConstruct(enhancedInstance, new Object[]{request});
verify(enhancedInstance, times(1)).setSkyWalkingDynamicField(request);

when(enhancedInstance.getSkyWalkingDynamicField()).thenReturn(request);
when(resp.getStatus()).thenReturn(200);

senderSendInterceptor.beforeMethod(enhancedInstance, sendMethod, allArguments, argumentsTypes, null);
senderSendInterceptor.afterMethod(enhancedInstance, sendMethod, allArguments, argumentsTypes, resp);

TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
assertThat(spans.size(), is(1));
assertThat(spans.get(0).getOperationName(), is("/yvr/list"));
}
}

0 comments on commit 38cf773

Please sign in to comment.