Merge pull request #259 from ascrutae/zhangxin/feature/support-tomcat-httpclient-dubbo-plugin
support tomcat dubbo and httpclient plugins
This commit is contained in:
commit
6e4cabcbef
|
|
@ -5,4 +5,8 @@ package org.skywalking.apm.network.trace.component;
|
|||
*/
|
||||
public class ComponentsDefine {
|
||||
public static final OfficialComponent TOMCAT = new OfficialComponent(1, "Tomcat");
|
||||
|
||||
public static final OfficialComponent HTTPCLIENT = new OfficialComponent(2, "HttpClient");
|
||||
|
||||
public static final OfficialComponent DUBBO = new OfficialComponent(3, "Dubbo");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
package org.skywalking.apm.agent.core.boot;
|
||||
|
||||
import org.skywalking.apm.logging.ILog;
|
||||
import org.skywalking.apm.logging.LogManager;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
import org.skywalking.apm.logging.ILog;
|
||||
import org.skywalking.apm.logging.LogManager;
|
||||
|
||||
/**
|
||||
* The <code>ServiceManager</code> bases on {@link ServiceLoader},
|
||||
|
|
@ -58,7 +57,7 @@ public enum ServiceManager {
|
|||
}
|
||||
}
|
||||
|
||||
private void afterBoot(){
|
||||
private void afterBoot() {
|
||||
for (BootService service : bootedServices.values()) {
|
||||
try {
|
||||
service.afterBoot();
|
||||
|
|
@ -72,11 +71,11 @@ public enum ServiceManager {
|
|||
* Find a {@link BootService} implementation, which is already started.
|
||||
*
|
||||
* @param serviceClass class name.
|
||||
* @param <T> {@link BootService} implementation class.
|
||||
* @param <T> {@link BootService} implementation class.
|
||||
* @return {@link BootService} instance
|
||||
*/
|
||||
public <T extends BootService> T findService(Class<T> serviceClass) {
|
||||
return (T) bootedServices.get(serviceClass);
|
||||
return (T)bootedServices.get(serviceClass);
|
||||
}
|
||||
|
||||
ServiceLoader<BootService> load() {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import java.util.List;
|
|||
import org.skywalking.apm.agent.core.context.ids.DistributedTraceId;
|
||||
import org.skywalking.apm.agent.core.context.ids.PropagatedTraceId;
|
||||
import org.skywalking.apm.agent.core.context.trace.TraceSegment;
|
||||
import org.skywalking.apm.agent.core.dictionary.DictionaryManager;
|
||||
import org.skywalking.apm.agent.core.dictionary.DictionaryUtil;
|
||||
import org.skywalking.apm.util.StringUtil;
|
||||
|
||||
|
|
|
|||
|
|
@ -185,9 +185,9 @@ public class TracingContext implements AbstractTracerContext {
|
|||
return new ExitSpan(spanIdGenerator++, parentSpanId, operationName, remotePeer);
|
||||
}
|
||||
});
|
||||
exitSpan.start();
|
||||
push(exitSpan);
|
||||
}
|
||||
exitSpan.start();
|
||||
return exitSpan;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class TraceSegmentRef {
|
|||
}
|
||||
String entryOperationName = carrier.getEntryOperationName();
|
||||
if (entryOperationName.charAt(0) == '#') {
|
||||
this.operationName = host.substring(1);
|
||||
this.operationName = entryOperationName.substring(1);
|
||||
} else {
|
||||
this.operationId = Integer.parseInt(entryOperationName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import net.bytebuddy.dynamic.DynamicType;
|
|||
import net.bytebuddy.implementation.FieldAccessor;
|
||||
import net.bytebuddy.implementation.MethodDelegation;
|
||||
import net.bytebuddy.implementation.SuperMethodCall;
|
||||
import net.bytebuddy.implementation.bind.annotation.FieldProxy;
|
||||
import net.bytebuddy.implementation.bind.annotation.Morph;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
import org.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine;
|
||||
|
|
@ -128,7 +127,7 @@ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePlugi
|
|||
.withBinders(
|
||||
Morph.Binder.install(OverrideCallable.class)
|
||||
)
|
||||
.to(new InstMethodsInterWithOverrideArgs(interceptor))
|
||||
.to(new InstMethodsInterWithOverrideArgs(interceptor, classLoader))
|
||||
);
|
||||
} else {
|
||||
newClassBuilder =
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
package org.skywalking.apm.agent.core.plugin.interceptor.enhance;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import net.bytebuddy.implementation.bind.annotation.AllArguments;
|
||||
import net.bytebuddy.implementation.bind.annotation.FieldProxy;
|
||||
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
|
||||
import net.bytebuddy.implementation.bind.annotation.This;
|
||||
import org.skywalking.apm.agent.core.plugin.PluginException;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package org.skywalking.apm.agent.core.plugin.interceptor.enhance;
|
|||
|
||||
import java.lang.reflect.Method;
|
||||
import net.bytebuddy.implementation.bind.annotation.AllArguments;
|
||||
import net.bytebuddy.implementation.bind.annotation.FieldProxy;
|
||||
import net.bytebuddy.implementation.bind.annotation.Morph;
|
||||
import net.bytebuddy.implementation.bind.annotation.Origin;
|
||||
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ public class GRPCStreamServiceStatus {
|
|||
*/
|
||||
public void wait4Finish(long maxTimeout) {
|
||||
long time = 0;
|
||||
while (status == false) {
|
||||
while (!status) {
|
||||
if (time > maxTimeout) {
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ public class SnifferConfigInitializerTest {
|
|||
Assert.assertEquals("crmApp", Config.Agent.APPLICATION_CODE);
|
||||
Assert.assertEquals("127.0.0.1:8080", Config.Collector.SERVERS);
|
||||
|
||||
Assert.assertNotNull(Config.Buffer.SIZE);
|
||||
Assert.assertNotNull(Config.Logging.DIR);
|
||||
Assert.assertNotNull(Config.Logging.FILE_NAME);
|
||||
Assert.assertNotNull(Config.Logging.MAX_FILE_SIZE);
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
package org.skywalking.apm.agent.core.context.trace;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.skywalking.apm.agent.core.tags.StringTagReader;
|
||||
import org.skywalking.apm.agent.core.context.tag.StringTag;
|
||||
|
||||
/**
|
||||
* @author wusheng
|
||||
*/
|
||||
public class LeafSpanTestCase {
|
||||
@Test
|
||||
public void testLeaf() {
|
||||
LeafSpan span = new LeafSpan(0, "serviceA", System.currentTimeMillis());
|
||||
span.push();
|
||||
span.setOperationName("serviceA2");
|
||||
span.setTag("key", "value-text");
|
||||
span.setTag("key2", false);
|
||||
span.setTag("key3", 1);
|
||||
|
||||
//start 2nd span
|
||||
span.push();
|
||||
|
||||
Assert.assertFalse(span.isFinished());
|
||||
Assert.assertTrue(span.isLeaf());
|
||||
span.setOperationName("service123");
|
||||
span.setTag("key", "value-text2");
|
||||
span.setTag("key2", true);
|
||||
span.setTag("key3", 2);
|
||||
Assert.assertEquals("serviceA2", span.getOperationName());
|
||||
Assert.assertEquals("value-text", StringTagReader.get(span, new StringTag("key")));
|
||||
Assert.assertFalse(BooleanTagReader.get(span, new BooleanTag("key2", false)));
|
||||
Assert.assertEquals(1, IntTagReader.get(span, new IntTag("key3")).intValue());
|
||||
|
||||
//end 2nd span
|
||||
span.pop();
|
||||
|
||||
span.pop();
|
||||
Assert.assertTrue(span.isFinished());
|
||||
}
|
||||
}
|
||||
|
|
@ -42,6 +42,11 @@ public class DubboInstrumentation extends ClassInstanceMethodsEnhancePluginDefin
|
|||
public String getMethodsInterceptor() {
|
||||
return INTERCEPT_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,11 @@ 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.skywalking.apm.plugin.dubbox.BugFixActive;
|
||||
import org.skywalking.apm.plugin.dubbox.SWBaseBean;
|
||||
|
||||
|
|
@ -27,8 +30,6 @@ import org.skywalking.apm.plugin.dubbox.SWBaseBean;
|
|||
*/
|
||||
public class DubboInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
|
||||
public static final String DUBBO_COMPONENT = "Dubbo";
|
||||
|
||||
/**
|
||||
* <h2>Consumer:</h2> The serialized trace context data will inject the first param that extend {@link SWBaseBean}
|
||||
* of dubbo service if the method {@link BugFixActive#active()} be called. or the serialized context data will
|
||||
|
|
@ -39,26 +40,21 @@ public class DubboInterceptor implements InstanceMethodsAroundInterceptor {
|
|||
* {@link RpcContext#attachments}. current trace segment will ref if the serialize context data is not null.
|
||||
*/
|
||||
@Override
|
||||
public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext,
|
||||
MethodInterceptResult result) {
|
||||
Object[] arguments = interceptorContext.allArguments();
|
||||
Invoker invoker = (Invoker) arguments[0];
|
||||
Invocation invocation = (Invocation) arguments[1];
|
||||
public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
|
||||
Invoker invoker = (Invoker)allArguments[0];
|
||||
Invocation invocation = (Invocation)allArguments[1];
|
||||
RpcContext rpcContext = RpcContext.getContext();
|
||||
boolean isConsumer = rpcContext.isConsumerSide();
|
||||
URL requestURL = invoker.getUrl();
|
||||
|
||||
AbstractSpan span = ContextManager.createSpan(generateOperationName(requestURL, invocation));
|
||||
Tags.URL.set(span, generateRequestURL(requestURL, invocation));
|
||||
Tags.COMPONENT.set(span, DUBBO_COMPONENT);
|
||||
Tags.SPAN_LAYER.asRPCFramework(span);
|
||||
span.setPeerHost(requestURL.getHost());
|
||||
span.setPort(requestURL.getPort());
|
||||
AbstractSpan span;
|
||||
|
||||
final String host = requestURL.getHost();
|
||||
final int port = requestURL.getPort();
|
||||
if (isConsumer) {
|
||||
Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT);
|
||||
ContextCarrier contextCarrier = new ContextCarrier();
|
||||
ContextManager.inject(contextCarrier);
|
||||
final ContextCarrier contextCarrier = new ContextCarrier();
|
||||
span = ContextManager.createExitSpan(generateOperationName(requestURL, invocation), contextCarrier, host + ":" + port);
|
||||
if (!BugFixActive.isActive()) {
|
||||
//invocation.getAttachments().put("contextData", contextDataStr);
|
||||
//@see https://github.com/alibaba/dubbo/blob/dubbo-2.5.3/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcInvocation.java#L154-L161
|
||||
|
|
@ -67,7 +63,6 @@ public class DubboInterceptor implements InstanceMethodsAroundInterceptor {
|
|||
fix283SendNoAttachmentIssue(invocation, contextCarrier);
|
||||
}
|
||||
} else {
|
||||
Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_SERVER);
|
||||
|
||||
ContextCarrier contextCarrier;
|
||||
if (!BugFixActive.isActive()) {
|
||||
|
|
@ -76,21 +71,18 @@ public class DubboInterceptor implements InstanceMethodsAroundInterceptor {
|
|||
contextCarrier = fix283RecvNoAttachmentIssue(invocation);
|
||||
}
|
||||
|
||||
if (contextCarrier != null) {
|
||||
ContextManager.extract(contextCarrier);
|
||||
}
|
||||
span = ContextManager.createEntrySpan(generateOperationName(requestURL, invocation), contextCarrier);
|
||||
}
|
||||
|
||||
Tags.URL.set(span, generateRequestURL(requestURL, invocation));
|
||||
span.setComponent(ComponentsDefine.DUBBO);
|
||||
SpanLayer.asRPCFramework(span);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute after {@link com.alibaba.dubbo.monitor.support.MonitorFilter#invoke(Invoker, Invocation)},
|
||||
* when dubbo instrumentation is active. Check {@link Result#getException()} , if not NULL,
|
||||
* log the exception and set tag error=true.
|
||||
*/
|
||||
@Override
|
||||
public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext,
|
||||
Object ret) {
|
||||
Result result = (Result) ret;
|
||||
public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Object ret) throws Throwable {
|
||||
Result result = (Result)ret;
|
||||
if (result != null && result.getException() != null) {
|
||||
dealException(result.getException());
|
||||
}
|
||||
|
|
@ -100,8 +92,8 @@ public class DubboInterceptor implements InstanceMethodsAroundInterceptor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(Throwable t, EnhancedClassInstanceContext context,
|
||||
InstanceMethodInvokeContext interceptorContext) {
|
||||
public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Throwable t) {
|
||||
dealException(t);
|
||||
}
|
||||
|
||||
|
|
@ -110,7 +102,7 @@ public class DubboInterceptor implements InstanceMethodsAroundInterceptor {
|
|||
*/
|
||||
private void dealException(Throwable throwable) {
|
||||
AbstractSpan span = ContextManager.activeSpan();
|
||||
Tags.ERROR.set(span, true);
|
||||
span.errorOccurred();
|
||||
span.log(throwable);
|
||||
}
|
||||
|
||||
|
|
@ -159,7 +151,7 @@ public class DubboInterceptor implements InstanceMethodsAroundInterceptor {
|
|||
private void fix283SendNoAttachmentIssue(Invocation invocation, ContextCarrier contextCarrier) {
|
||||
for (Object parameter : invocation.getArguments()) {
|
||||
if (parameter instanceof SWBaseBean) {
|
||||
((SWBaseBean) parameter).setTraceContext(contextCarrier.serialize());
|
||||
((SWBaseBean)parameter).setTraceContext(contextCarrier.serialize());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -173,7 +165,7 @@ public class DubboInterceptor implements InstanceMethodsAroundInterceptor {
|
|||
private ContextCarrier fix283RecvNoAttachmentIssue(Invocation invocation) {
|
||||
for (Object parameter : invocation.getArguments()) {
|
||||
if (parameter instanceof SWBaseBean) {
|
||||
return new ContextCarrier().deserialize(((SWBaseBean) parameter).getTraceContext());
|
||||
return new ContextCarrier().deserialize(((SWBaseBean)parameter).getTraceContext());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,68 +12,47 @@ 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;
|
||||
|
||||
/**
|
||||
* {@link HttpClientExecuteInterceptor} transport the trace context by call {@link HttpRequest#setHeader(Header)},
|
||||
* The current span tag the {@link Tags#ERROR} if {@link StatusLine#getStatusCode()} is not equals 200.
|
||||
* The {@link Tags#STATUS_CODE} will be set if {@link StatusLine#getStatusCode()} is not equals 200.
|
||||
*
|
||||
* @author zhangxin
|
||||
*/
|
||||
public class HttpClientExecuteInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
private static final String COMPONENT_NAME = "HttpClient";
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedClassInstanceContext context,
|
||||
InstanceMethodInvokeContext interceptorContext, MethodInterceptResult result) {
|
||||
Object[] allArguments = interceptorContext.allArguments();
|
||||
@Override public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
|
||||
if (allArguments[0] == null || allArguments[1] == null) {
|
||||
// illegal args, can't trace. ignore.
|
||||
return;
|
||||
}
|
||||
HttpHost httpHost = (HttpHost)allArguments[0];
|
||||
final HttpHost httpHost = (HttpHost)allArguments[0];
|
||||
HttpRequest httpRequest = (HttpRequest)allArguments[1];
|
||||
AbstractSpan span = createSpan(httpRequest);
|
||||
span.setPeerHost(httpHost.getHostName());
|
||||
span.setPort(httpHost.getPort());
|
||||
Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT);
|
||||
Tags.COMPONENT.set(span, COMPONENT_NAME);
|
||||
Tags.URL.set(span, generateURL(httpRequest));
|
||||
Tags.SPAN_LAYER.asHttp(span);
|
||||
final ContextCarrier contextCarrier = new ContextCarrier();
|
||||
AbstractSpan span = null;
|
||||
String remotePeer = httpHost.getHostName() + ":" + httpHost.getPort();
|
||||
try {
|
||||
URL url = new URL(httpRequest.getRequestLine().getUri());
|
||||
span = ContextManager.createExitSpan(url.getPath(), contextCarrier, remotePeer);
|
||||
} catch (MalformedURLException e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
span.setComponent(ComponentsDefine.HTTPCLIENT);
|
||||
Tags.URL.set(span, httpRequest.getRequestLine().getUri());
|
||||
SpanLayer.asHttp(span);
|
||||
|
||||
ContextCarrier contextCarrier = new ContextCarrier();
|
||||
ContextManager.inject(contextCarrier);
|
||||
httpRequest.setHeader(Config.Plugin.Propagation.HEADER_NAME, contextCarrier.serialize());
|
||||
}
|
||||
|
||||
/**
|
||||
* Format request URL.
|
||||
*
|
||||
* @return request URL
|
||||
*/
|
||||
private String generateURL(HttpRequest httpRequest) {
|
||||
return httpRequest.getRequestLine().getUri();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create span.
|
||||
*/
|
||||
private AbstractSpan createSpan(HttpRequest httpRequest) {
|
||||
AbstractSpan span;
|
||||
try {
|
||||
URL url = new URL(httpRequest.getRequestLine().getUri());
|
||||
span = ContextManager.createSpan(url.getPath());
|
||||
} catch (MalformedURLException e) {
|
||||
span = ContextManager.createSpan(httpRequest.getRequestLine().getUri());
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedClassInstanceContext context,
|
||||
InstanceMethodInvokeContext interceptorContext, Object ret) {
|
||||
Object[] allArguments = interceptorContext.allArguments();
|
||||
@Override public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Object ret) throws Throwable {
|
||||
if (allArguments[0] == null || allArguments[1] == null) {
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -82,19 +61,18 @@ public class HttpClientExecuteInterceptor implements InstanceMethodsAroundInterc
|
|||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
AbstractSpan span = ContextManager.activeSpan();
|
||||
if (statusCode != 200) {
|
||||
Tags.ERROR.set(span, true);
|
||||
span.errorOccurred();
|
||||
Tags.STATUS_CODE.set(span, statusCode + "");
|
||||
}
|
||||
|
||||
Tags.STATUS_CODE.set(span, statusCode);
|
||||
ContextManager.stopSpan();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(Throwable t, EnhancedClassInstanceContext context,
|
||||
InstanceMethodInvokeContext interceptorContext) {
|
||||
Tags.ERROR.set(ContextManager.activeSpan(), true);
|
||||
ContextManager.activeSpan().log(t);
|
||||
@Override public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Throwable t) {
|
||||
AbstractSpan activeSpan = ContextManager.activeSpan();
|
||||
activeSpan.errorOccurred();
|
||||
activeSpan.log(t);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,11 @@ public class AbstractHttpClientInstrumentation extends HttpClientInstrumentation
|
|||
public String getMethodsInterceptor() {
|
||||
return getInstanceMethodsInterceptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,24 +2,16 @@ package org.skywalking.apm.plugin.httpClient.v4.define;
|
|||
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
||||
/**
|
||||
* {@link AbstractHttpClientInstrumentation} presents that skywalking intercepts
|
||||
* {@link org.apache.http.impl.client.DefaultRequestDirector#execute(HttpHost, org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext)}
|
||||
* by using {@link HttpClientInstrumentation#INTERCEPT_CLASS}.
|
||||
*
|
||||
* @author zhangxin
|
||||
*/
|
||||
public class DefaultRequestDirectorInstrumentation extends HttpClientInstrumentation {
|
||||
|
||||
/**
|
||||
* Enhance class.
|
||||
*/
|
||||
private static final String ENHANCE_CLASS = "org.apache.http.impl.discovery.DefaultRequestDirector";
|
||||
private static final String ENHANCE_CLASS = "org.apache.http.impl.client.DefaultRequestDirector";
|
||||
|
||||
/**
|
||||
* DefaultRequestDirector is default implement.<br/>
|
||||
|
|
@ -44,6 +36,11 @@ public class DefaultRequestDirectorInstrumentation extends HttpClientInstrumenta
|
|||
public String getMethodsInterceptor() {
|
||||
return getInstanceMethodsInterceptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||
|
||||
/**
|
||||
* {@link AbstractHttpClientInstrumentation} presents that skywalking intercepts {@link
|
||||
* org.apache.http.impl.client.InternalHttpClient#doExecute(org.apache.http.HttpHost, org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext)} by using {@link
|
||||
* HttpClientInstrumentation#INTERCEPT_CLASS}.
|
||||
* org.apache.http.impl.client.InternalHttpClient#doExecute(org.apache.http.HttpHost, org.apache.http.HttpRequest,
|
||||
* org.apache.http.protocol.HttpContext)} by using {@link HttpClientInstrumentation#INTERCEPT_CLASS}.
|
||||
*
|
||||
* @author zhangxin
|
||||
*/
|
||||
|
|
@ -35,6 +35,11 @@ public class InternalHttpClientInstrumentation extends HttpClientInstrumentation
|
|||
public String getMethodsInterceptor() {
|
||||
return getInstanceMethodsInterceptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,11 @@ public class MinimalHttpClientInstrumentation extends HttpClientInstrumentation
|
|||
public String getMethodsInterceptor() {
|
||||
return getInstanceMethodsInterceptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,12 @@ 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.context.trace.TraceSegment;
|
||||
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.util.StringUtil;
|
||||
import org.skywalking.apm.network.trace.component.ComponentsDefine;
|
||||
|
||||
/**
|
||||
* {@link TomcatInterceptor} fetch the serialized context data by using {@link HttpServletRequest#getHeader(String)}.
|
||||
|
|
@ -18,85 +20,48 @@ import org.skywalking.apm.util.StringUtil;
|
|||
* segment id of the previous level if the serialized context is not null.
|
||||
*/
|
||||
public class TomcatInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
/**
|
||||
* Tomcat component.
|
||||
*/
|
||||
public static final String TOMCAT_COMPONENT = "Tomcat";
|
||||
|
||||
/**
|
||||
* The {@link TraceSegment#refs} of current trace segment will reference to the
|
||||
* * The {@link TraceSegment#refs} of current trace segment will reference to the
|
||||
* trace segment id of the previous level if the serialized context is not null.
|
||||
*
|
||||
* @param context instance context, a class instance only has one {@link EnhancedClassInstanceContext} instance.
|
||||
* @param interceptorContext method context, includes class name, method name, etc.
|
||||
* @param result change this result, if you want to truncate the method.
|
||||
* @param objInst
|
||||
* @param methodName
|
||||
* @param allArguments
|
||||
* @param argumentsTypes
|
||||
* @param result change this result, if you want to truncate the method.
|
||||
* @throws Throwable
|
||||
*/
|
||||
@Override
|
||||
public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext,
|
||||
MethodInterceptResult result) {
|
||||
Object[] args = interceptorContext.allArguments();
|
||||
HttpServletRequest request = (HttpServletRequest) args[0];
|
||||
|
||||
AbstractSpan span = ContextManager.createSpan(request.getRequestURI());
|
||||
Tags.COMPONENT.set(span, TOMCAT_COMPONENT);
|
||||
span.setPeerHost(fetchRequestPeerHost(request));
|
||||
span.setPort(request.getRemotePort());
|
||||
Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_SERVER);
|
||||
Tags.URL.set(span, request.getRequestURL().toString());
|
||||
Tags.SPAN_LAYER.asHttp(span);
|
||||
|
||||
@Override public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
|
||||
HttpServletRequest request = (HttpServletRequest)allArguments[0];
|
||||
String tracingHeaderValue = request.getHeader(Config.Plugin.Propagation.HEADER_NAME);
|
||||
if (!StringUtil.isEmpty(tracingHeaderValue)) {
|
||||
ContextManager.extract(new ContextCarrier().deserialize(tracingHeaderValue));
|
||||
}
|
||||
ContextCarrier contextCarrier = new ContextCarrier().deserialize(tracingHeaderValue);
|
||||
AbstractSpan span = ContextManager.createEntrySpan(request.getRequestURI(), contextCarrier);
|
||||
Tags.URL.set(span, request.getRequestURL().toString());
|
||||
Tags.HTTP.METHOD.set(span, request.getMethod());
|
||||
span.setComponent(ComponentsDefine.TOMCAT);
|
||||
SpanLayer.asHttp(span);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext,
|
||||
Object ret) {
|
||||
HttpServletResponse response = (HttpServletResponse) interceptorContext.allArguments()[1];
|
||||
@Override public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Object ret) throws Throwable {
|
||||
HttpServletResponse response = (HttpServletResponse)allArguments[1];
|
||||
|
||||
AbstractSpan span = ContextManager.activeSpan();
|
||||
Tags.STATUS_CODE.set(span, response.getStatus());
|
||||
|
||||
if (response.getStatus() != 200) {
|
||||
Tags.ERROR.set(span, true);
|
||||
span.errorOccurred();
|
||||
Tags.STATUS_CODE.set(span, response.getStatus() + "");
|
||||
}
|
||||
|
||||
ContextManager.stopSpan();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(Throwable t, EnhancedClassInstanceContext context,
|
||||
InstanceMethodInvokeContext interceptorContext) {
|
||||
@Override public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Throwable t) {
|
||||
AbstractSpan span = ContextManager.activeSpan();
|
||||
span.log(t);
|
||||
Tags.ERROR.set(span, true);
|
||||
span.errorOccurred();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public String fetchRequestPeerHost(HttpServletRequest request) {
|
||||
String ip = request.getHeader("X-Forwarded-For");
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_CLIENT_IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,11 @@ public class TomcatInstrumentation extends ClassInstanceMethodsEnhancePluginDefi
|
|||
public String getMethodsInterceptor() {
|
||||
return INTERCEPT_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
package org.skywalking.apm.sniffer.mock.trace.tags;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wusheng
|
||||
*/
|
||||
public class BooleanTagReader {
|
||||
public static Boolean get(Span span, BooleanTag tag) {
|
||||
List<BooleanTagItem> tagsWithBoolList = null;
|
||||
try {
|
||||
Field tagsWithBool = Span.class.getDeclaredField("tagsWithBool");
|
||||
tagsWithBool.setAccessible(true);
|
||||
tagsWithBoolList = (List<BooleanTagItem>)tagsWithBool.get(span);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (tagsWithBoolList != null) {
|
||||
for (BooleanTagItem item : tagsWithBoolList) {
|
||||
if (tag.key().equals(item.getKey())) {
|
||||
return item.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
return tag.defaultValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
package org.skywalking.apm.sniffer.mock.trace.tags;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wusheng
|
||||
*/
|
||||
public class IntTagReader {
|
||||
public static Integer get(Span span, IntTag tag) {
|
||||
List<IntTagItem> tagsWithIntList = null;
|
||||
try {
|
||||
Field tagsWithInt = Span.class.getDeclaredField("tagsWithInt");
|
||||
tagsWithInt.setAccessible(true);
|
||||
tagsWithIntList = (List<IntTagItem>)tagsWithInt.get(span);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (IntTagItem item : tagsWithIntList) {
|
||||
if (tag.key().equals(item.getKey())) {
|
||||
return item.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue