提交 901dca5e 编写于 作者: A ascrutae

Merge remote-tracking branch 'upstream/feature/new-context-carrier' into...

Merge remote-tracking branch 'upstream/feature/new-context-carrier' into feature/support-struts2-plugin
......@@ -5,64 +5,26 @@ import io.opentracing.Span;
import io.opentracing.SpanContext;
import io.opentracing.Tracer;
import io.opentracing.propagation.Format;
import io.opentracing.propagation.TextMap;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Map;
/**
* @author wusheng
*/
public class SkywalkingTracer implements Tracer {
private static String TRACE_HEAD_NAME = "sw3";
@NeedSnifferActivation("1. ContextManager#inject" +
"2. ContextCarrier#serialize")
private String inject() {
return null;
}
@NeedSnifferActivation("1. ContextCarrier#deserialize" +
"2. ContextManager#extract")
private void extract(String carrier) {
}
@Override
public SpanBuilder buildSpan(String operationName) {
return new SkywalkingSpanBuilder(operationName);
}
@NeedSnifferActivation
@Override
public <C> void inject(SpanContext spanContext, Format<C> format, C carrier) {
if (Format.Builtin.TEXT_MAP.equals(format) || Format.Builtin.HTTP_HEADERS.equals(format)) {
((TextMap)carrier).put(TRACE_HEAD_NAME, inject());
} else if (Format.Builtin.BINARY.equals(format)) {
byte[] key = TRACE_HEAD_NAME.getBytes(ByteBufferContext.CHARSET);
byte[] value = inject().getBytes(ByteBufferContext.CHARSET);
((ByteBuffer)carrier).put(key);
((ByteBuffer)carrier).putInt(value.length);
((ByteBuffer)carrier).put(value);
} else {
throw new IllegalArgumentException("Unsupported format: " + format);
}
}
@NeedSnifferActivation
@Override
public <C> SpanContext extract(Format<C> format, C carrier) {
if (Format.Builtin.TEXT_MAP.equals(format) || Format.Builtin.HTTP_HEADERS.equals(format)) {
TextMap textMapCarrier = (TextMap)carrier;
extract(fetchContextData(textMapCarrier));
return new TextMapContext(textMapCarrier);
} else if (Format.Builtin.BINARY.equals(format)) {
ByteBuffer byteBufferCarrier = (ByteBuffer)carrier;
extract(fetchContextData(byteBufferCarrier));
return new ByteBufferContext((ByteBuffer)carrier);
} else {
throw new IllegalArgumentException("Unsupported format: " + format);
}
return new TextMapContext();
}
@Override
......@@ -78,34 +40,4 @@ public class SkywalkingTracer implements Tracer {
throw new IllegalArgumentException("span must be a type of SkywalkingSpan");
}
}
private String fetchContextData(TextMap textMap) {
Iterator<Map.Entry<String, String>> iterator = textMap.iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
if (TRACE_HEAD_NAME.equals(entry.getKey())) {
return entry.getValue();
}
}
return null;
}
private String fetchContextData(ByteBuffer byteBuffer) {
String contextDataStr = new String(byteBuffer.array(), Charset.forName("UTF-8"));
int index = contextDataStr.indexOf(TRACE_HEAD_NAME);
if (index == -1) {
return null;
}
try {
byteBuffer.position(index + TRACE_HEAD_NAME.getBytes().length);
byte[] contextDataBytes = new byte[byteBuffer.getInt()];
byteBuffer.get(contextDataBytes);
return new String(contextDataBytes, Charset.forName("UTF-8"));
} catch (Exception e) {
return null;
}
}
}
package org.skywalking.apm.toolkit.opentracing;
import io.opentracing.SpanContext;
import io.opentracing.propagation.TextMap;
import java.util.HashMap;
import java.util.Map;
......@@ -10,14 +8,11 @@ import java.util.Map;
* Created by wusheng on 2016/12/21.
*/
public class TextMapContext implements SpanContext {
private final TextMap textMap;
TextMapContext(TextMap textMap) {
this.textMap = textMap;
public TextMapContext() {
}
@Override
public Iterable<Map.Entry<String, String>> baggageItems() {
return new HashMap<String, String>().entrySet();
return new HashMap<String, String>(0).entrySet();
}
}
......@@ -134,13 +134,5 @@ public class Config {
*/
public static boolean TRACE_PARAM = false;
}
public static class Propagation {
/**
* The header name of cross process propagation data.
*/
public static String HEADER_NAME = "sw3";
}
}
}
package org.skywalking.apm.agent.core.context;
import java.util.Iterator;
/**
* @author wusheng
*/
public class CarrierItem implements Iterator<CarrierItem> {
private String headKey;
private String headValue;
private CarrierItem next;
public CarrierItem(String headKey, String headValue) {
this.headKey = headKey;
this.headValue = headValue;
next = null;
}
public CarrierItem(String headKey, String headValue, CarrierItem next) {
this.headKey = headKey;
this.headValue = headValue;
this.next = next;
}
public String getHeadKey() {
return headKey;
}
public String getHeadValue() {
return headValue;
}
public void setHeadValue(String headValue) {
this.headValue = headValue;
}
@Override
public boolean hasNext() {
return next != null;
}
@Override
public CarrierItem next() {
return next;
}
@Override
public void remove() {
}
}
package org.skywalking.apm.agent.core.context;
/**
* @author wusheng
*/
public class CarrierItemHead extends CarrierItem {
public CarrierItemHead(CarrierItem next) {
super("", "", next);
}
}
......@@ -59,13 +59,19 @@ public class ContextCarrier implements Serializable {
*/
private DistributedTraceId primaryDistributedTraceId;
public CarrierItem items() {
SW3CarrierItem carrierItem = new SW3CarrierItem(this, null);
CarrierItemHead head = new CarrierItemHead(carrierItem);
return head;
}
/**
* Serialize this {@link ContextCarrier} to a {@link String},
* with '|' split.
*
* @return the serialization string.
*/
public String serialize() {
String serialize() {
if (this.isValid()) {
return StringUtil.join('|',
this.getTraceSegmentId().encode(),
......@@ -75,7 +81,7 @@ public class ContextCarrier implements Serializable {
this.getPeerHost(),
this.getEntryOperationName(),
this.getParentOperationName(),
this.getPrimaryDistributedTraceId().toBase64());
this.getPrimaryDistributedTraceId().encode());
} else {
return "";
}
......@@ -86,7 +92,7 @@ public class ContextCarrier implements Serializable {
*
* @param text carries {@link #traceSegmentId} and {@link #spanId}, with '|' split.
*/
public ContextCarrier deserialize(String text) {
ContextCarrier deserialize(String text) {
if (text != null) {
String[] parts = text.split("\\|", 8);
if (parts.length == 8) {
......@@ -114,6 +120,7 @@ public class ContextCarrier implements Serializable {
*/
public boolean isValid() {
return traceSegmentId != null
&& traceSegmentId.isValid()
&& getSpanId() > -1
&& parentApplicationInstanceId != DictionaryUtil.nullValue()
&& entryApplicationInstanceId != DictionaryUtil.nullValue()
......
package org.skywalking.apm.agent.core.context;
/**
* @author wusheng
*/
public class SW3CarrierItem extends CarrierItem {
public static final String HEADER_NAME = "sw3";
private ContextCarrier carrier;
public SW3CarrierItem(ContextCarrier carrier, CarrierItem next) {
super(HEADER_NAME, carrier.serialize(), next);
this.carrier = carrier;
}
@Override
public void setHeadValue(String headValue) {
carrier.deserialize(headValue);
}
}
package org.skywalking.apm.agent.core.context;
/**
* @author wusheng
*/
public class TraceContextCarrierItem extends CarrierItem {
private static final String HEAD_NAME = "Trace-Context";
public TraceContextCarrierItem(String headValue, CarrierItem next) {
super(HEAD_NAME, headValue, next);
}
}
......@@ -26,7 +26,7 @@ public abstract class DistributedTraceId {
this.id = new ID(id);
}
public String toBase64() {
public String encode() {
return id.encode();
}
......
package org.skywalking.apm.agent.core.context.ids;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.skywalking.apm.agent.core.context.ids.base64.Base64;
import org.skywalking.apm.network.proto.UniqueId;
/**
* @author wusheng
*/
public class ID {
private static final Base64.Encoder ENCODER = Base64.getEncoder();
private static final Base64.Decoder DECODER = Base64.getDecoder();
private long part1;
private long part2;
private long part3;
private String encoding;
private boolean isValid;
public ID(long part1, long part2, long part3) {
this.part1 = part1;
this.part2 = part2;
this.part3 = part3;
this.encoding = null;
this.isValid = true;
}
public ID(String encodingString) {
int index = 0;
String[] idParts = encodingString.split("\\.", 3);
this.isValid = true;
for (int part = 0; part < 3; part++) {
String encodedString;
char potentialTypeChar = encodingString.charAt(index);
long value;
if (potentialTypeChar == '#') {
encodedString = encodingString.substring(index + 1, index + 5);
index += 5;
value = ByteBuffer.wrap(DECODER.decode(encodedString)).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(0);
} else if (potentialTypeChar == '$') {
encodedString = encodingString.substring(index + 1, index + 9);
index += 9;
value = ByteBuffer.wrap(DECODER.decode(encodedString)).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().get(0);
} else {
encodedString = encodingString.substring(index, index + 12);
index += 12;
value = ByteBuffer.wrap(DECODER.decode(encodedString)).order(ByteOrder.LITTLE_ENDIAN).asLongBuffer().get(0);
}
if (part == 0) {
part1 = value;
} else if (part == 1) {
part2 = value;
} else {
part3 = value;
try {
if (part == 0) {
part1 = Long.parseLong(idParts[part]);
} else if (part == 1) {
part2 = Long.parseLong(idParts[part]);
} else {
part3 = Long.parseLong(idParts[part]);
}
} catch (NumberFormatException e) {
this.isValid = false;
break;
}
}
......@@ -57,36 +42,11 @@ public class ID {
public String encode() {
if (encoding == null) {
encoding = long2Base64(part1) + long2Base64(part2) + long2Base64(part3);
encoding = toString();
}
return encoding;
}
private String long2Base64(long partN) {
if (partN < 0) {
throw new IllegalArgumentException("negative value.");
}
if (partN < 32768) {
// 0 - 32767
// "#" as a prefix of a short value with base64 encoding.
byte[] data = new byte[2];
ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put((short)partN);
return '#' + ENCODER.encodeToString(data);
} else if (partN <= 2147483647) {
// 32768 - 2147483647
// "$" as a prefix of an integer value (greater than a short) with base64 encoding.
byte[] data = new byte[4];
ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().put((int)partN);
return '$' + ENCODER.encodeToString(data);
} else {
// > 2147483647
// a long value (greater than an integer)
byte[] data = new byte[8];
ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).asLongBuffer().put(partN);
return ENCODER.encodeToString(data);
}
}
@Override public String toString() {
return part1 + "." + part2 + '.' + part3;
}
......@@ -113,6 +73,10 @@ public class ID {
return result;
}
public boolean isValid() {
return isValid;
}
public UniqueId transform() {
return UniqueId.newBuilder().addIdParts(part1).addIdParts(part2).addIdParts(part3).build();
}
......
......@@ -79,7 +79,7 @@ public class ContextManagerTest {
@Test
public void createMultipleEntrySpan() {
ContextCarrier contextCarrier = new ContextCarrier().deserialize("#AQA*#AQA*4WcWe0tQNQA*|1|1|1|#127.0.0.1:8080|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
ContextCarrier contextCarrier = new ContextCarrier().deserialize("1.2343.234234234|1|1|1|#127.0.0.1:8080|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
assertTrue(contextCarrier.isValid());
AbstractSpan firstEntrySpan = ContextManager.createEntrySpan("/testFirstEntry", contextCarrier);
......@@ -202,7 +202,7 @@ public class ContextManagerTest {
@Test
public void testTransform() throws InvalidProtocolBufferException {
ContextCarrier contextCarrier = new ContextCarrier().deserialize("#AQA*#AQA*4WcWe0tQNQA*|3|1|1|#127.0.0.1:8080|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
ContextCarrier contextCarrier = new ContextCarrier().deserialize("1.234.1983829|3|1|1|#127.0.0.1:8080|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
assertTrue(contextCarrier.isValid());
AbstractSpan firstEntrySpan = ContextManager.createEntrySpan("/testFirstEntry", contextCarrier);
......
......@@ -6,7 +6,7 @@ import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcContext;
import java.lang.reflect.Method;
import org.skywalking.apm.agent.core.conf.Config;
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;
......@@ -16,28 +16,20 @@ 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;
/**
* {@link DubboInterceptor} define how to enhance class {@link com.alibaba.dubbo.monitor.support.MonitorFilter#invoke(Invoker,
* Invocation)}. the trace context transport to the provider side by {@link RpcContext#attachments}.but all the version
* of dubbo framework below 2.8.3 don't support {@link RpcContext#attachments}, we support another way to support it. it
* is that all request parameters of dubbo service need to extend {@link SWBaseBean}, and {@link DubboInterceptor} will
* inject the trace context data to the {@link SWBaseBean} bean and extract the trace context data from {@link
* SWBaseBean}, or the trace context data will not transport to the provider side.
* of dubbo framework below 2.8.3 don't support {@link RpcContext#attachments}, we support another way to support it.
*
* @author zhangxin
*/
public class DubboInterceptor implements InstanceMethodsAroundInterceptor {
/**
* <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
* <h2>Consumer:</h2> The serialized trace context data will
* inject to the {@link RpcContext#attachments} for transport to provider side.
* <p>
* <h2>Provider:</h2> The serialized trace context data will extract from the first param that extend {@link
* SWBaseBean} of dubbo service if the method {@link BugFixActive#active()} be called. or it will extract from
* <h2>Provider:</h2> The serialized trace context data will extract from
* {@link RpcContext#attachments}. current trace segment will ref if the serialize context data is not null.
*/
@Override
......@@ -56,20 +48,19 @@ public class DubboInterceptor implements InstanceMethodsAroundInterceptor {
if (isConsumer) {
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
rpcContext.getAttachments().put(Config.Plugin.Propagation.HEADER_NAME, contextCarrier.serialize());
} else {
fix283SendNoAttachmentIssue(invocation, contextCarrier);
//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
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
rpcContext.getAttachments().put(next.getHeadKey(), next.getHeadValue());
}
} else {
ContextCarrier contextCarrier;
if (!BugFixActive.isActive()) {
contextCarrier = new ContextCarrier().deserialize(rpcContext.getAttachment(Config.Plugin.Propagation.HEADER_NAME));
} else {
contextCarrier = fix283RecvNoAttachmentIssue(invocation);
ContextCarrier contextCarrier = new ContextCarrier();
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
next.setHeadValue(rpcContext.getAttachment(next.getHeadKey()));
}
span = ContextManager.createEntrySpan(generateOperationName(requestURL, invocation), contextCarrier);
......@@ -143,33 +134,4 @@ public class DubboInterceptor implements InstanceMethodsAroundInterceptor {
requestURL.append(generateOperationName(url, invocation));
return requestURL.toString();
}
/**
* Set the trace context.
*
* @param contextCarrier {@link ContextCarrier}.
*/
private void fix283SendNoAttachmentIssue(Invocation invocation, ContextCarrier contextCarrier) {
for (Object parameter : invocation.getArguments()) {
if (parameter instanceof SWBaseBean) {
((SWBaseBean)parameter).setTraceContext(contextCarrier.serialize());
return;
}
}
}
/**
* Fetch the trace context by using {@link Invocation#getArguments()}.
*
* @return trace context data.
*/
private ContextCarrier fix283RecvNoAttachmentIssue(Invocation invocation) {
for (Object parameter : invocation.getArguments()) {
if (parameter instanceof SWBaseBean) {
return new ContextCarrier().deserialize(((SWBaseBean)parameter).getTraceContext());
}
}
return null;
}
}
package org.skywalking.apm.plugin.dubbox;
/**
* {@link BugFixActive#active} is an flag that present the dubbox version is below 2.8.3, The version 2.8.3 of dubbox
* don't support attachment. so skywalking provided another way to support the function that transport the serialized
* context data. The way is that all parameters of dubbo service need to extend {@link SWBaseBean}, {@link
* org.skywalking.apm.plugin.dubbo.DubboInterceptor} fetch the serialized context data by using {@link
* SWBaseBean#getTraceContext()}.
*
* @author zhangxin
*/
public final class BugFixActive {
private static boolean ACTIVE = false;
/**
* Set active status, before startup dubbo remote.
*/
public static void active() {
BugFixActive.ACTIVE = true;
}
public static boolean isActive() {
return BugFixActive.ACTIVE;
}
}
package org.skywalking.apm.plugin.dubbox;
import java.io.Serializable;
/**
* All the request parameter of dubbox service need to extend {@link SWBaseBean} to transport
* the serialized trace context to the provider side if the version of dubbox is below 2.8.3.
*
* @author zhangxin
*/
public class SWBaseBean implements Serializable {
/**
* Serialized trace context.
*/
private String traceContext;
public String getTraceContext() {
return traceContext;
}
public void setTraceContext(String traceContext) {
this.traceContext = traceContext;
}
}
......@@ -7,7 +7,6 @@ import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcContext;
import java.util.List;
import org.hamcrest.CoreMatchers;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
......@@ -18,7 +17,7 @@ import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
import org.skywalking.apm.agent.core.conf.Config;
import org.skywalking.apm.agent.core.context.ContextCarrier;
import org.skywalking.apm.agent.core.context.SW3CarrierItem;
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;
......@@ -27,7 +26,6 @@ import org.skywalking.apm.agent.core.context.trace.TraceSegmentRef;
import org.skywalking.apm.agent.core.context.util.KeyValuePair;
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.FieldSetter;
import org.skywalking.apm.agent.test.helper.SegmentHelper;
import org.skywalking.apm.agent.test.helper.SegmentRefHelper;
import org.skywalking.apm.agent.test.helper.SpanHelper;
......@@ -35,7 +33,6 @@ 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.plugin.dubbox.BugFixActive;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertNull;
......@@ -45,7 +42,7 @@ import static org.powermock.api.mockito.PowerMockito.when;
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(TracingSegmentRunner.class)
@PrepareForTest({RpcContext.class, BugFixActive.class})
@PrepareForTest({RpcContext.class})
public class DubboInterceptorTest {
@SegmentStoragePoint
......@@ -59,7 +56,6 @@ public class DubboInterceptorTest {
private DubboInterceptor dubboInterceptor;
private RequestParamForTestBelow283 testParam;
@Mock
private RpcContext rpcContext;
@Mock
......@@ -77,39 +73,20 @@ public class DubboInterceptorTest {
@Before
public void setUp() throws Exception {
dubboInterceptor = new DubboInterceptor();
testParam = new RequestParamForTestBelow283();
PowerMockito.mockStatic(RpcContext.class);
when(invoker.getUrl()).thenReturn(URL.valueOf("dubbo://127.0.0.1:20880/org.skywalking.apm.test.TestDubboService"));
when(invocation.getMethodName()).thenReturn("test");
when(invocation.getParameterTypes()).thenReturn(new Class[] {String.class});
when(invocation.getArguments()).thenReturn(new Object[] {testParam});
when(invocation.getArguments()).thenReturn(new Object[] {"abc"});
PowerMockito.when(RpcContext.getContext()).thenReturn(rpcContext);
when(rpcContext.isConsumerSide()).thenReturn(true);
allArguments = new Object[] {invoker, invocation};
argumentTypes = new Class[] {invoker.getClass(), invocation.getClass()};
Config.Agent.APPLICATION_CODE = "DubboTestCases-APP";
FieldSetter.setStaticValue(BugFixActive.class, "ACTIVE", false);
}
@Test
public void testConsumerBelow283() throws Throwable {
BugFixActive.active();
dubboInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
dubboInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, result);
assertThat(segmentStorage.getTraceSegments().size(), is(1));
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
assertThat(SegmentHelper.getSpans(traceSegment).size(), is(1));
assertConsumerSpan(SegmentHelper.getSpans(traceSegment).get(0));
ContextCarrier contextCarrier = new ContextCarrier();
contextCarrier.deserialize(testParam.getTraceContext());
assertTrue(contextCarrier.isValid());
}
@Test
public void testConsumerWithAttachment() throws Throwable {
......@@ -148,25 +125,13 @@ public class DubboInterceptorTest {
@Test
public void testProviderWithAttachment() throws Throwable {
when(rpcContext.isConsumerSide()).thenReturn(false);
when(rpcContext.getAttachment(Config.Plugin.Propagation.HEADER_NAME)).thenReturn("#AQA*#AQA*4WcWe0tQNQA*|3|1|1|#192.168.1.8 :18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
when(rpcContext.getAttachment(SW3CarrierItem.HEADER_NAME)).thenReturn("1.323.4433|3|1|1|#192.168.1.8 :18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
dubboInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
dubboInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, result);
assertProvider();
}
@Test
public void testProviderBelow283() throws Throwable {
when(rpcContext.isConsumerSide()).thenReturn(false);
FieldSetter.setStaticValue(BugFixActive.class, "ACTIVE", true);
testParam.setTraceContext("#AQA*#AQA*4WcWe0tQNQA*|3|1|1|#192.168.1.8 :18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
dubboInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
dubboInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, result);
assertProvider();
}
private void assertConsumerTraceSegmentInErrorCase(
TraceSegment traceSegment) {
......@@ -195,7 +160,7 @@ public class DubboInterceptorTest {
private void assertTraceSegmentRef(TraceSegmentRef actual) {
assertThat(SegmentRefHelper.getSpanId(actual), is(3));
assertThat(SegmentRefHelper.getEntryApplicationInstanceId(actual), is(1));
assertThat(SegmentRefHelper.getTraceSegmentId(actual).toString(), is("1.1.15006458883500001"));
assertThat(SegmentRefHelper.getTraceSegmentId(actual).toString(), is("1.323.4433"));
}
private void assertProviderSpan(AbstractTracingSpan span) {
......
package org.skywalking.apm.plugin.dubbo;
import org.skywalking.apm.plugin.dubbox.SWBaseBean;
/**
* {@link RequestParamForTestBelow283} store context data for test.
*/
public class RequestParamForTestBelow283 extends SWBaseBean {
}
......@@ -6,13 +6,13 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.skywalking.apm.agent.core.conf.Config;
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;
......@@ -37,7 +37,6 @@ public class DefaultHttpClientInterceptor implements InstanceMethodsAroundInterc
* port, kind, component, url from {@link feign.Request}.
* Through the reflection of the way, set the http header of context data into {@link feign.Request#headers}.
*
*
* @param method
* @param result change this result, if you want to truncate the method.
* @throws Throwable
......@@ -55,9 +54,6 @@ public class DefaultHttpClientInterceptor implements InstanceMethodsAroundInterc
Tags.URL.set(span, url.getPath());
SpanLayer.asHttp(span);
List<String> contextCollection = new ArrayList<String>();
contextCollection.add(contextCarrier.serialize());
Field headersField = Request.class.getDeclaredField("headers");
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
......@@ -65,7 +61,13 @@ public class DefaultHttpClientInterceptor implements InstanceMethodsAroundInterc
headersField.setAccessible(true);
Map<String, Collection<String>> headers = new LinkedHashMap<String, Collection<String>>();
headers.put(Config.Plugin.Propagation.HEADER_NAME, contextCollection);
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
List<String> contextCollection = new LinkedList<String>();
contextCollection.add(next.getHeadValue());
headers.put(next.getHeadKey(), contextCollection);
}
headers.putAll(request.headers());
headersField.set(request, Collections.unmodifiableMap(headers));
......@@ -76,7 +78,6 @@ public class DefaultHttpClientInterceptor implements InstanceMethodsAroundInterc
* the server.
* Finish the {@link AbstractSpan}.
*
*
* @param method
* @param ret the method's original return value.
* @return
......
......@@ -6,7 +6,7 @@ import java.net.URL;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.skywalking.apm.agent.core.conf.Config;
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;
......@@ -42,7 +42,11 @@ public class HttpClientExecuteInterceptor implements InstanceMethodsAroundInterc
Tags.HTTP.METHOD.set(span, httpRequest.getRequestLine().getMethod());
SpanLayer.asHttp(span);
httpRequest.setHeader(Config.Plugin.Propagation.HEADER_NAME, contextCarrier.serialize());
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
httpRequest.setHeader(next.getHeadKey(), next.getHeadValue());
}
}
@Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
......
......@@ -4,7 +4,7 @@ import com.weibo.api.motan.rpc.Request;
import com.weibo.api.motan.rpc.Response;
import com.weibo.api.motan.rpc.URL;
import java.lang.reflect.Method;
import org.skywalking.apm.agent.core.conf.Config;
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;
......@@ -42,7 +42,11 @@ public class MotanConsumerInterceptor implements InstanceConstructorInterceptor,
span.setComponent(ComponentsDefine.MOTAN);
Tags.URL.set(span, url.getIdentity());
SpanLayer.asRPCFramework(span);
request.setAttachment(Config.Plugin.Propagation.HEADER_NAME, contextCarrier.serialize());
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
request.setAttachment(next.getHeadKey(), next.getHeadValue());
}
}
}
......
......@@ -3,7 +3,7 @@ package org.skywalking.apm.plugin.motan;
import com.weibo.api.motan.rpc.Request;
import com.weibo.api.motan.rpc.Response;
import java.lang.reflect.Method;
import org.skywalking.apm.agent.core.conf.Config;
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.trace.AbstractSpan;
......@@ -27,8 +27,13 @@ public class MotanProviderInterceptor implements InstanceMethodsAroundIntercepto
@Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
Request request = (Request)allArguments[0];
String serializedContextData = request.getAttachments().get(Config.Plugin.Propagation.HEADER_NAME);
ContextCarrier contextCarrier = new ContextCarrier().deserialize(serializedContextData);
ContextCarrier contextCarrier = new ContextCarrier();
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
next.setHeadValue(request.getAttachments().get(next.getHeadKey()));
}
AbstractSpan span = ContextManager.createEntrySpan(generateViewPoint(request), contextCarrier);
SpanLayer.asRPCFramework(span);
span.setComponent(ComponentsDefine.MOTAN);
......
......@@ -13,7 +13,7 @@ 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.conf.Config;
import org.skywalking.apm.agent.core.context.SW3CarrierItem;
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;
......@@ -91,7 +91,7 @@ public class MotanProviderInterceptorTest {
@Test
public void testInvokerWithRefSegment() throws Throwable {
HashMap attachments = new HashMap();
attachments.put(Config.Plugin.Propagation.HEADER_NAME, "#AQA*#AQA*4WcWe0tQNQA*|3|1|1|#192.168.1.8:18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
attachments.put(SW3CarrierItem.HEADER_NAME, "1.123.456|3|1|1|#192.168.1.8:18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
when(request.getAttachments()).thenReturn(attachments);
invokeInterceptor.beforeMethod(enhancedInstance, null, arguments, argumentType, null);
......@@ -135,7 +135,7 @@ public class MotanProviderInterceptorTest {
}
private void assertRefSegment(TraceSegmentRef primaryRef) {
assertThat(SegmentRefHelper.getTraceSegmentId(primaryRef).toString(), is("1.1.15006458883500001"));
assertThat(SegmentRefHelper.getTraceSegmentId(primaryRef).toString(), is("1.123.456"));
assertThat(SegmentRefHelper.getSpanId(primaryRef), is(3));
assertThat(SegmentRefHelper.getEntryApplicationInstanceId(primaryRef), is(1));
assertThat(SegmentRefHelper.getPeerHost(primaryRef), is("192.168.1.8:18002"));
......
......@@ -8,7 +8,7 @@ import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.skywalking.apm.agent.core.conf.Config;
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;
......@@ -44,7 +44,6 @@ public class RealCallInterceptor implements InstanceMethodsAroundInterceptor, In
* port, kind, component, url from {@link okhttp3.Request}.
* Through the reflection of the way, set the http header of context data into {@link okhttp3.Request#headers}.
*
*
* @param method
* @param result change this result, if you want to truncate the method.
* @throws Throwable
......@@ -67,8 +66,13 @@ public class RealCallInterceptor implements InstanceMethodsAroundInterceptor, In
modifiersField.setInt(headersField, headersField.getModifiers() & ~Modifier.FINAL);
headersField.setAccessible(true);
Headers headers = request.headers().newBuilder().add(Config.Plugin.Propagation.HEADER_NAME, contextCarrier.serialize()).build();
headersField.set(request, headers);
Headers.Builder headerBuilder = request.headers().newBuilder();
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
headerBuilder.add(next.getHeadKey(), next.getHeadValue());
}
headersField.set(request, headerBuilder.build());
}
/**
......@@ -76,7 +80,6 @@ public class RealCallInterceptor implements InstanceMethodsAroundInterceptor, In
* the server.
* Finish the {@link AbstractSpan}.
*
*
* @param method
* @param ret the method's original return value.
* @return
......
......@@ -3,7 +3,7 @@ package org.skywalking.apm.plugin.resin.v3;
import com.caucho.server.connection.CauchoRequest;
import com.caucho.server.http.HttpResponse;
import java.lang.reflect.Method;
import org.skywalking.apm.agent.core.conf.Config;
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;
......@@ -25,8 +25,13 @@ public class ResinV3Interceptor implements InstanceMethodsAroundInterceptor {
@Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
CauchoRequest request = (CauchoRequest)allArguments[0];
String tracingHeaderValue = request.getHeader(Config.Plugin.Propagation.HEADER_NAME);
ContextCarrier contextCarrier = new ContextCarrier().deserialize(tracingHeaderValue);
ContextCarrier contextCarrier = new ContextCarrier();
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
next.setHeadValue(request.getHeader(next.getHeadKey()));
}
AbstractSpan span = ContextManager.createEntrySpan(request.getPageURI(), contextCarrier);
span.setComponent(ComponentsDefine.RESIN);
Tags.URL.set(span, appendRequestURL(request));
......
......@@ -10,7 +10,7 @@ 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.conf.Config;
import org.skywalking.apm.agent.core.context.SW3CarrierItem;
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;
......@@ -90,7 +90,7 @@ public class ResinV3InterceptorTest {
@Test
public void testWithSerializedContextData() throws Throwable {
when(request.getHeader(Config.Plugin.Propagation.HEADER_NAME)).thenReturn("#AQA*#AQA*4WcWe0tQNQA*|3|1|1|#192.168.1.8:18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
when(request.getHeader(SW3CarrierItem.HEADER_NAME)).thenReturn("1.333.2345|3|1|1|#192.168.1.8:18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
interceptor.beforeMethod(enhancedInstance, null, arguments, argumentType, methodInterceptResult);
interceptor.afterMethod(enhancedInstance, null, arguments, argumentType, null);
......@@ -122,7 +122,7 @@ public class ResinV3InterceptorTest {
private void assertTraceSegmentRef(TraceSegmentRef ref) {
assertThat(SegmentRefHelper.getSpanId(ref), is(3));
assertThat(SegmentRefHelper.getEntryApplicationInstanceId(ref), is(1));
assertThat(SegmentRefHelper.getTraceSegmentId(ref).toString(), is("1.1.15006458883500001"));
assertThat(SegmentRefHelper.getTraceSegmentId(ref).toString(), is("1.333.2345"));
}
private void assertHttpSpan(AbstractTracingSpan span) {
......
......@@ -3,7 +3,7 @@ package org.skywalking.apm.plugin.resin.v4;
import com.caucho.server.http.CauchoRequest;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletResponse;
import org.skywalking.apm.agent.core.conf.Config;
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;
......@@ -22,8 +22,12 @@ public class ResinV4Interceptor implements InstanceMethodsAroundInterceptor {
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
CauchoRequest request = (CauchoRequest)allArguments[0];
String tracingHeaderValue = request.getHeader(Config.Plugin.Propagation.HEADER_NAME);
ContextCarrier contextCarrier = new ContextCarrier().deserialize(tracingHeaderValue);
ContextCarrier contextCarrier = new ContextCarrier();
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
next.setHeadValue(request.getHeader(next.getHeadKey()));
}
AbstractSpan span = ContextManager.createEntrySpan(request.getPageURI(), contextCarrier);
span.setComponent(ComponentsDefine.RESIN);
Tags.URL.set(span, appendRequestURL(request));
......
......@@ -10,7 +10,7 @@ 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.conf.Config;
import org.skywalking.apm.agent.core.context.SW3CarrierItem;
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;
......@@ -92,7 +92,7 @@ public class ResinV4InterceptorTest {
@Test
public void testWithSerializedContextData() throws Throwable {
when(request.getHeader(Config.Plugin.Propagation.HEADER_NAME)).thenReturn("#AQA*#AQA*4WcWe0tQNQA*|3|1|1|#192.168.1.8:18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
when(request.getHeader(SW3CarrierItem.HEADER_NAME)).thenReturn("1.444.555|3|1|1|#192.168.1.8:18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
interceptor.beforeMethod(enhancedInstance, null, arguments, argumentType, methodInterceptResult);
interceptor.afterMethod(enhancedInstance, null, arguments, argumentType, null);
......@@ -124,7 +124,7 @@ public class ResinV4InterceptorTest {
private void assertTraceSegmentRef(TraceSegmentRef ref) {
assertThat(SegmentRefHelper.getEntryApplicationInstanceId(ref), is(1));
assertThat(SegmentRefHelper.getSpanId(ref), is(3));
assertThat(SegmentRefHelper.getTraceSegmentId(ref).toString(), is("1.1.15006458883500001"));
assertThat(SegmentRefHelper.getTraceSegmentId(ref).toString(), is("1.444.555"));
}
private void assertHttpSpan(AbstractTracingSpan span) {
......
......@@ -3,7 +3,7 @@ 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.conf.Config;
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;
......@@ -19,8 +19,6 @@ import org.springframework.web.context.request.ServletRequestAttributes;
/**
* The <code>ControllerServiceMethodInterceptor</code> only use the first mapping value.
*
* @See {@link ControllerConstructorInterceptor} to explain why we are doing this.
*/
public class ControllerServiceMethodInterceptor implements InstanceMethodsAroundInterceptor {
@Override
......@@ -40,8 +38,14 @@ public class ControllerServiceMethodInterceptor implements InstanceMethodsAround
}
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
String tracingHeaderValue = request.getHeader(Config.Plugin.Propagation.HEADER_NAME);
ContextCarrier contextCarrier = new ContextCarrier().deserialize(tracingHeaderValue);
ContextCarrier contextCarrier = new ContextCarrier();
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
next.setHeadValue(request.getHeader(next.getHeadKey()));
}
AbstractSpan span = ContextManager.createEntrySpan(requestURL, contextCarrier);
Tags.URL.set(span, request.getRequestURL().toString());
Tags.HTTP.METHOD.set(span, request.getMethod());
......
......@@ -30,7 +30,7 @@ public class RestExecuteInterceptor implements InstanceMethodsAroundInterceptor
SpanLayer.asHttp(span);
Object[] cacheValues = new Object[3];
cacheValues[0] = requestURL;
cacheValues[1] = contextCarrier.serialize();
cacheValues[1] = contextCarrier;
objInst.setSkyWalkingDynamicField(cacheValues);
}
......
......@@ -29,7 +29,7 @@ public class RestExecuteInterceptor implements InstanceMethodsAroundInterceptor
Tags.HTTP.METHOD.set(span, httpMethod.toString());
SpanLayer.asHttp(span);
objInst.setSkyWalkingDynamicField(contextCarrier.serialize());
objInst.setSkyWalkingDynamicField(contextCarrier);
}
@Override
......
package org.skywalking.apm.plugin.spring.resttemplate.sync;
import java.lang.reflect.Method;
import org.skywalking.apm.agent.core.conf.Config;
import org.skywalking.apm.agent.core.context.CarrierItem;
import org.skywalking.apm.agent.core.context.ContextCarrier;
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;
......@@ -22,7 +23,12 @@ public class RestRequestInterceptor implements InstanceMethodsAroundInterceptor
ClientHttpRequest clientHttpRequest = (ClientHttpRequest)ret;
if (clientHttpRequest instanceof AbstractClientHttpRequest) {
AbstractClientHttpRequest httpRequest = (AbstractClientHttpRequest)clientHttpRequest;
httpRequest.getHeaders().set(Config.Plugin.Propagation.HEADER_NAME, String.valueOf(objInst.getSkyWalkingDynamicField()));
ContextCarrier contextCarrier = (ContextCarrier)objInst.getSkyWalkingDynamicField();
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
httpRequest.getHeaders().set(next.getHeadKey(), next.getHeadValue());
}
}
return ret;
}
......
package org.springframework.http.client;
import java.lang.reflect.Method;
import org.skywalking.apm.agent.core.conf.Config;
import org.skywalking.apm.agent.core.context.CarrierItem;
import org.skywalking.apm.agent.core.context.ContextCarrier;
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;
......@@ -19,7 +20,13 @@ public class RestRequestInterceptor implements InstanceMethodsAroundInterceptor
Object ret) throws Throwable {
AbstractAsyncClientHttpRequest clientHttpRequest = (AbstractAsyncClientHttpRequest)ret;
if (ret != null) {
clientHttpRequest.getHeaders().set(Config.Plugin.Propagation.HEADER_NAME, String.valueOf(((Object[])objInst.getSkyWalkingDynamicField())[1]));
Object[] cacheValues = (Object[])objInst.getSkyWalkingDynamicField();
ContextCarrier contextCarrier = (ContextCarrier)cacheValues[1];
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
clientHttpRequest.getHeaders().set(next.getHeadKey(), next.getHeadValue());
}
}
return ret;
}
......
......@@ -3,7 +3,7 @@ package org.skywalking.apm.plugin.tomcat78x;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.skywalking.apm.agent.core.conf.Config;
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;
......@@ -16,9 +16,9 @@ import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptR
import org.skywalking.apm.network.trace.component.ComponentsDefine;
/**
* {@link TomcatInvokeInterceptor} fetch the serialized context data by using {@link HttpServletRequest#getHeader(String)}.
* 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.
* {@link TomcatInvokeInterceptor} fetch the serialized context data by using {@link
* HttpServletRequest#getHeader(String)}. 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.
*/
public class TomcatInvokeInterceptor implements InstanceMethodsAroundInterceptor {
......@@ -36,8 +36,14 @@ public class TomcatInvokeInterceptor implements InstanceMethodsAroundInterceptor
@Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
HttpServletRequest request = (HttpServletRequest)allArguments[0];
String tracingHeaderValue = request.getHeader(Config.Plugin.Propagation.HEADER_NAME);
ContextCarrier contextCarrier = new ContextCarrier().deserialize(tracingHeaderValue);
ContextCarrier contextCarrier = new ContextCarrier();
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
next.setHeadValue(request.getHeader(next.getHeadKey()));
}
AbstractSpan span = ContextManager.createEntrySpan(request.getRequestURI(), contextCarrier);
Tags.URL.set(span, request.getRequestURL().toString());
Tags.HTTP.METHOD.set(span, request.getMethod());
......
......@@ -10,7 +10,7 @@ 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.conf.Config;
import org.skywalking.apm.agent.core.context.SW3CarrierItem;
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;
......@@ -90,7 +90,7 @@ public class TomcatInvokeInterceptorTest {
@Test
public void testWithSerializedContextData() throws Throwable {
when(request.getHeader(Config.Plugin.Propagation.HEADER_NAME)).thenReturn("#AQA*#AQA*4WcWe0tQNQA*|3|1|1|#192.168.1.8:18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
when(request.getHeader(SW3CarrierItem.HEADER_NAME)).thenReturn("1.234.111|3|1|1|#192.168.1.8:18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
tomcatInvokeInterceptor.beforeMethod(enhancedInstance, null, arguments, argumentType, methodInterceptResult);
tomcatInvokeInterceptor.afterMethod(enhancedInstance, null, arguments, argumentType, null);
......@@ -138,7 +138,7 @@ public class TomcatInvokeInterceptorTest {
private void assertTraceSegmentRef(TraceSegmentRef ref) {
assertThat(SegmentRefHelper.getEntryApplicationInstanceId(ref), is(1));
assertThat(SegmentRefHelper.getSpanId(ref), is(3));
assertThat(SegmentRefHelper.getTraceSegmentId(ref).toString(), is("1.1.15006458883500001"));
assertThat(SegmentRefHelper.getTraceSegmentId(ref).toString(), is("1.234.111"));
}
private void assertHttpSpan(AbstractTracingSpan span) {
......
package org.skywalking.apm.toolkit.activation.opentracing.tracer;
import io.opentracing.propagation.Format;
import io.opentracing.propagation.TextMap;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Map;
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.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.toolkit.opentracing.TextMapContext;
public class SkywalkingTracerExtractInterceptor implements InstanceMethodsAroundInterceptor {
@Override
......@@ -17,10 +23,26 @@ public class SkywalkingTracerExtractInterceptor implements InstanceMethodsAround
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Object ret) throws Throwable {
String carrier = (String)allArguments[0];
ContextCarrier contextCarrier = new ContextCarrier().deserialize(carrier);
ContextManager.extract(contextCarrier);
return ret;
Format format = (Format)allArguments[0];
if (Format.Builtin.TEXT_MAP.equals(format) || Format.Builtin.HTTP_HEADERS.equals(format)) {
TextMap textMapCarrier = (TextMap)allArguments[1];
ContextCarrier contextCarrier = new ContextCarrier();
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
Iterator<Map.Entry<String, String>> iterator = textMapCarrier.iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
if (next.getHeadKey().equals(entry.getKey())) {
next.setHeadValue(entry.getValue());
break;
}
}
}
ContextManager.extract(contextCarrier);
}
return new TextMapContext();
}
@Override
......
package org.skywalking.apm.toolkit.activation.opentracing.tracer;
import io.opentracing.propagation.Format;
import io.opentracing.propagation.TextMap;
import java.lang.reflect.Method;
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.plugin.interceptor.enhance.EnhancedInstance;
......@@ -17,9 +20,21 @@ public class SkywalkingTracerInjectInterceptor implements InstanceMethodsAroundI
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Object ret) throws Throwable {
ContextCarrier contextCarrier = new ContextCarrier();
ContextManager.inject(contextCarrier);
return contextCarrier.serialize();
Format format = (Format)allArguments[1];
if (Format.Builtin.TEXT_MAP.equals(format) || Format.Builtin.HTTP_HEADERS.equals(format)) {
TextMap carrier = (TextMap)allArguments[2];
ContextCarrier contextCarrier = new ContextCarrier();
ContextManager.inject(contextCarrier);
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
carrier.put(next.getHeadKey(), next.getHeadValue());
}
} else {
//Don't support other format yet.
}
return null;
}
@Override
......
package org.skywalking.apm.toolkit.activation.opentracing;
import io.opentracing.Tracer;
import io.opentracing.propagation.Format;
import io.opentracing.propagation.TextMap;
import io.opentracing.tag.Tags;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
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.context.ContextCarrier;
import org.skywalking.apm.agent.core.context.ContextSnapshot;
import org.skywalking.apm.agent.core.context.SW3CarrierItem;
import org.skywalking.apm.agent.core.context.ids.ID;
import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
import org.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.skywalking.apm.agent.core.context.trace.TraceSegmentRef;
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.SegmentRefHelper;
import org.skywalking.apm.agent.test.tools.AgentServiceRule;
import org.skywalking.apm.agent.test.tools.SegmentStorage;
import org.skywalking.apm.agent.test.tools.SegmentStoragePoint;
......@@ -34,15 +38,15 @@ import org.skywalking.apm.toolkit.activation.opentracing.tracer.SkywalkingTracer
import org.skywalking.apm.toolkit.opentracing.SkywalkingContinuation;
import org.skywalking.apm.toolkit.opentracing.SkywalkingSpan;
import org.skywalking.apm.toolkit.opentracing.SkywalkingSpanBuilder;
import org.skywalking.apm.toolkit.opentracing.SkywalkingTracer;
import org.skywalking.apm.toolkit.opentracing.TextMapContext;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.skywalking.apm.agent.test.tools.SegmentRefAssert.assertEntryApplicationInstanceId;
import static org.skywalking.apm.agent.test.tools.SegmentRefAssert.assertPeerHost;
import static org.skywalking.apm.agent.test.tools.SegmentRefAssert.assertSegmentId;
import static org.skywalking.apm.agent.test.tools.SegmentRefAssert.assertEntryApplicationInstanceId;
import static org.skywalking.apm.agent.test.tools.SegmentRefAssert.assertSpanId;
import static org.skywalking.apm.agent.test.tools.SpanAssert.assertComponent;
import static org.skywalking.apm.agent.test.tools.SpanAssert.assertLogSize;
......@@ -170,14 +174,25 @@ public class SkywalkingSpanActivationTest {
.withTag(Tags.PEER_HOST_IPV4.getKey(), "127.0.0.1").withTag(Tags.PEER_PORT.getKey(), 8080);
startSpan();
String extractValue = (String)injectInterceptor.afterMethod(enhancedInstance, null,
null, null, null);
final Map<String, String> values = new HashMap<String, String>();
TextMap carrier = new TextMap() {
@Override public Iterator<Map.Entry<String, String>> iterator() {
return null;
}
@Override public void put(String key, String value) {
values.put(key, value);
}
};
injectInterceptor.afterMethod(enhancedInstance, null,
new Object[] {new TextMapContext(), Format.Builtin.TEXT_MAP, carrier}, null, null);
ContextCarrier contextCarrier = new ContextCarrier().deserialize(extractValue);
assertTrue(contextCarrier.isValid());
assertThat(contextCarrier.getPeerHost(), is("#127.0.0.1:8080"));
assertThat(contextCarrier.getSpanId(), is(0));
assertThat(contextCarrier.getEntryOperationName(), is("#testOperationName"));
String[] parts = values.get(SW3CarrierItem.HEADER_NAME).split("\\|", 8);
Assert.assertEquals("0", parts[1]);
Assert.assertEquals("#127.0.0.1:8080", parts[4]);
Assert.assertTrue(new ID(parts[7]).isValid());
stopSpan();
}
......@@ -186,15 +201,29 @@ public class SkywalkingSpanActivationTest {
spanBuilder.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)
.withTag(Tags.PEER_HOST_IPV4.getKey(), "127.0.0.1").withTag(Tags.PEER_PORT.getKey(), 8080);
startSpan();
final Map<String, String> values = new HashMap<String, String>();
TextMap carrier = new TextMap() {
@Override public Iterator<Map.Entry<String, String>> iterator() {
return values.entrySet().iterator();
}
@Override public void put(String key, String value) {
values.put(key, value);
}
};
values.put(SW3CarrierItem.HEADER_NAME, "1.343.222|3|1|1|#127.0.0.1:8080|#/portal/|#/testEntrySpan|434.12.12123");
extractInterceptor.afterMethod(enhancedInstance, null,
new Object[] {"#AQA*#AQA*4WcWe0tQNQA*|3|1|1|#127.0.0.1:8080|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*"}, new Class[] {String.class}, null);
new Object[] {Format.Builtin.TEXT_MAP, carrier}, new Class[] {}, null);
stopSpan();
TraceSegment tracingSegment = assertTraceSemgnets();
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(tracingSegment);
assertThat(tracingSegment.getRefs().size(), is(1));
TraceSegmentRef ref = tracingSegment.getRefs().get(0);
assertSegmentId(ref, "1.1.15006458883500001");
assertSegmentId(ref, "1.343.222");
assertSpanId(ref, 3);
assertEntryApplicationInstanceId(ref, 1);
assertPeerHost(ref, "127.0.0.1:8080");
......@@ -207,8 +236,23 @@ public class SkywalkingSpanActivationTest {
spanBuilder.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)
.withTag(Tags.PEER_HOST_IPV4.getKey(), "127.0.0.1").withTag(Tags.PEER_PORT.getKey(), 8080);
startSpan();
final Map<String, String> values = new HashMap<String, String>();
TextMap carrier = new TextMap() {
@Override public Iterator<Map.Entry<String, String>> iterator() {
return values.entrySet().iterator();
}
@Override public void put(String key, String value) {
values.put(key, value);
}
};
values.put(SW3CarrierItem.HEADER_NAME, "aaaaaaaa|3|#192.168.1.8:18002|#/portal/|#/testEntrySpan|1.234.444");
extractInterceptor.afterMethod(enhancedInstance, null,
new Object[] {"#AQA*#AQA*4WcWe0tQNQA*|3|#192.168.1.8:18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*"}, new Class[] {String.class}, null);
new Object[] {Format.Builtin.TEXT_MAP, carrier}, new Class[] {}, null);
stopSpan();
TraceSegment tracingSegment = assertTraceSemgnets();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册