New v2 header with header key `sw6` (#1894)

* Add some supports to sw6 header. Break many test cases because I turn sw3 default off. For sure, you could open in agent.conf.  FYI @peng-yongsheng @ascrutae

* Fix CI and make user cases still work under v1 header.

* Support BASE64 in v2 header and make entryOperationName and parentOperationName optional in ContextCarrier or ContextSnapshot

* Fix CI.

* @peng-yongsheng This is backend related, please pay attention.

* Fix the carrier item order is incorrect (#1903)
This commit is contained in:
吴晟 Wu Sheng 2018-11-12 17:42:17 +08:00 committed by GitHub
parent 6dd98b37bf
commit 645a9a579d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 604 additions and 160 deletions

View File

@ -18,17 +18,30 @@
package org.apache.skywalking.apm.agent.core.base64;
import java.io.UnsupportedEncodingException;
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
/**
* Copied from {@code zipkin.internal.Base64}, adapted from {@code okio.Base64}
* as JRE 6 doesn't have a base64Url encoder.
* Copied from {@code zipkin.internal.Base64}, adapted from {@code okio.Base64} as JRE 6 doesn't have a base64Url
* encoder.
*
* @author okio cited the original author as Alexander Y. Kleymenov
*/
public final class Base64 {
private static final ILog logger = LogManager.getLogger(Base64.class);
private Base64() {
}
public static String decode2UTFString(String in) {
try {
return new String(decode(in), "utf-8");
} catch (UnsupportedEncodingException e) {
logger.error(e, "Can't decode BASE64 text {}", in);
return "";
}
}
public static byte[] decode(String in) {
// Ignore trailing '=' padding and whitespace from the input.
int limit = in.length();
@ -40,7 +53,7 @@ public final class Base64 {
}
// If the input includes whitespace, this output array will be longer than necessary.
byte[] out = new byte[(int) (limit * 6L / 8L)];
byte[] out = new byte[(int)(limit * 6L / 8L)];
int outCount = 0;
int inCount = 0;
@ -75,14 +88,14 @@ public final class Base64 {
}
// Append this char's 6 bits to the word.
word = (word << 6) | (byte) bits;
word = (word << 6) | (byte)bits;
// For every 4 chars of input, we accumulate 24 bits of output. Emit 3 bytes.
inCount++;
if (inCount % 4 == 0) {
out[outCount++] = (byte) (word >> 16);
out[outCount++] = (byte) (word >> 8);
out[outCount++] = (byte) word;
out[outCount++] = (byte)(word >> 16);
out[outCount++] = (byte)(word >> 8);
out[outCount++] = (byte)word;
}
}
@ -93,16 +106,17 @@ public final class Base64 {
} else if (lastWordChars == 2) {
// We read 2 chars followed by "==". Emit 1 byte with 8 of those 12 bits.
word = word << 12;
out[outCount++] = (byte) (word >> 16);
out[outCount++] = (byte)(word >> 16);
} else if (lastWordChars == 3) {
// We read 3 chars, followed by "=". Emit 2 bytes for 16 of those 18 bits.
word = word << 6;
out[outCount++] = (byte) (word >> 16);
out[outCount++] = (byte) (word >> 8);
out[outCount++] = (byte)(word >> 16);
out[outCount++] = (byte)(word >> 8);
}
// If we sized our out array perfectly, we're done.
if (outCount == out.length) return out;
if (outCount == out.length)
return out;
// Copy the decoded bytes to a new, right-sized array.
byte[] prefix = new byte[outCount];
@ -124,6 +138,15 @@ public final class Base64 {
'5', '6', '7', '8', '9', '-', '_'
};
public static String encode(String text) {
try {
return encode(text.getBytes("utf-8"));
} catch (UnsupportedEncodingException e) {
logger.error(e, "Can't encode {} in BASE64", text);
return "";
}
}
public static String encode(byte[] in) {
return encode(in, MAP);
}

View File

@ -70,6 +70,16 @@ public class Config {
* Skywalking team may ask for these files in order to resolve compatible problem.
*/
public static boolean IS_OPEN_DEBUGGING_CLASS = false;
/**
* Active V2 header in default
*/
public static boolean ACTIVE_V2_HEADER = true;
/**
* Deactive V1 header in default
*/
public static boolean ACTIVE_V1_HEADER = false;
}
public static class Collector {

View File

@ -16,11 +16,12 @@
*
*/
package org.apache.skywalking.apm.agent.core.context;
import java.io.Serializable;
import java.util.List;
import org.apache.skywalking.apm.agent.core.base64.Base64;
import org.apache.skywalking.apm.agent.core.conf.Config;
import org.apache.skywalking.apm.agent.core.context.ids.DistributedTraceId;
import org.apache.skywalking.apm.agent.core.context.ids.ID;
import org.apache.skywalking.apm.agent.core.context.ids.PropagatedTraceId;
@ -29,8 +30,8 @@ import org.apache.skywalking.apm.agent.core.dictionary.DictionaryUtil;
import org.apache.skywalking.apm.util.StringUtil;
/**
* {@link ContextCarrier} is a data carrier of {@link TracingContext}.
* It holds the snapshot (current state) of {@link TracingContext}.
* {@link ContextCarrier} is a data carrier of {@link TracingContext}. It holds the snapshot (current state) of {@link
* TracingContext}.
* <p>
* Created by wusheng on 2017/2/17.
*/
@ -41,8 +42,7 @@ public class ContextCarrier implements Serializable {
private ID traceSegmentId;
/**
* id of parent span.
* It is unique in parent trace segment.
* id of parent span. It is unique in parent trace segment.
*/
private int spanId = -1;
@ -62,14 +62,12 @@ public class ContextCarrier implements Serializable {
private String peerHost;
/**
* Operation/Service name of the first one in this distributed trace.
* This name may be compressed to an integer.
* Operation/Service name of the first one in this distributed trace. This name may be compressed to an integer.
*/
private String entryOperationName;
/**
* Operation/Service name of the parent one in this distributed trace.
* This name may be compressed to an integer.
* Operation/Service name of the parent one in this distributed trace. This name may be compressed to an integer.
*/
private String parentOperationName;
@ -79,28 +77,60 @@ public class ContextCarrier implements Serializable {
private DistributedTraceId primaryDistributedTraceId;
public CarrierItem items() {
SW3CarrierItem carrierItem = new SW3CarrierItem(this, null);
CarrierItemHead head = new CarrierItemHead(carrierItem);
CarrierItemHead head;
if (Config.Agent.ACTIVE_V2_HEADER && Config.Agent.ACTIVE_V1_HEADER) {
SW3CarrierItem carrierItem = new SW3CarrierItem(this, null);
SW6CarrierItem sw6CarrierItem = new SW6CarrierItem(this, carrierItem);
head = new CarrierItemHead(sw6CarrierItem);
} else if (Config.Agent.ACTIVE_V2_HEADER) {
SW6CarrierItem sw6CarrierItem = new SW6CarrierItem(this, null);
head = new CarrierItemHead(sw6CarrierItem);
} else if (Config.Agent.ACTIVE_V1_HEADER) {
SW3CarrierItem carrierItem = new SW3CarrierItem(this, null);
head = new CarrierItemHead(carrierItem);
} else {
throw new IllegalArgumentException("At least active v1 or v2 header.");
}
return head;
}
/**
* Serialize this {@link ContextCarrier} to a {@link String},
* with '|' split.
* Serialize this {@link ContextCarrier} to a {@link String}, with '|' split.
*
* @return the serialization string.
*/
String serialize() {
if (this.isValid()) {
return StringUtil.join('|',
this.getTraceSegmentId().encode(),
this.getSpanId() + "",
this.getParentApplicationInstanceId() + "",
this.getEntryApplicationInstanceId() + "",
this.getPeerHost(),
this.getEntryOperationName(),
this.getParentOperationName(),
this.getPrimaryDistributedTraceId().encode());
String serialize(HeaderVersion version) {
if (this.isValid(version)) {
if (HeaderVersion.v1.equals(version)) {
if (Config.Agent.ACTIVE_V1_HEADER) {
return StringUtil.join('|',
this.getTraceSegmentId().encode(),
this.getSpanId() + "",
this.getParentApplicationInstanceId() + "",
this.getEntryApplicationInstanceId() + "",
this.getPeerHost(),
this.getEntryOperationName(),
this.getParentOperationName(),
this.getPrimaryDistributedTraceId().encode());
} else {
return "";
}
} else {
if (Config.Agent.ACTIVE_V2_HEADER) {
return StringUtil.join('-',
"1",
Base64.encode(this.getPrimaryDistributedTraceId().encode()),
Base64.encode(this.getTraceSegmentId().encode()),
this.getSpanId() + "",
this.getParentApplicationInstanceId() + "",
this.getEntryApplicationInstanceId() + "",
Base64.encode(this.getPeerHost()),
Base64.encode(this.getEntryOperationName()),
Base64.encode(this.getParentOperationName()));
} else {
return "";
}
}
} else {
return "";
}
@ -111,42 +141,83 @@ public class ContextCarrier implements Serializable {
*
* @param text carries {@link #traceSegmentId} and {@link #spanId}, with '|' split.
*/
ContextCarrier deserialize(String text) {
ContextCarrier deserialize(String text, HeaderVersion version) {
if (text != null) {
String[] parts = text.split("\\|", 8);
if (parts.length == 8) {
try {
this.traceSegmentId = new ID(parts[0]);
this.spanId = Integer.parseInt(parts[1]);
this.parentApplicationInstanceId = Integer.parseInt(parts[2]);
this.entryApplicationInstanceId = Integer.parseInt(parts[3]);
this.peerHost = parts[4];
this.entryOperationName = parts[5];
this.parentOperationName = parts[6];
this.primaryDistributedTraceId = new PropagatedTraceId(parts[7]);
} catch (NumberFormatException e) {
// if this carrier is initialized by v1 or v2, don't do deserialize again for performance.
if (this.isValid(HeaderVersion.v1) || this.isValid(HeaderVersion.v2)) {
return this;
}
if (HeaderVersion.v1.equals(version)) {
String[] parts = text.split("\\|", 8);
if (parts.length == 8) {
try {
this.traceSegmentId = new ID(parts[0]);
this.spanId = Integer.parseInt(parts[1]);
this.parentApplicationInstanceId = Integer.parseInt(parts[2]);
this.entryApplicationInstanceId = Integer.parseInt(parts[3]);
this.peerHost = parts[4];
this.entryOperationName = parts[5];
this.parentOperationName = parts[6];
this.primaryDistributedTraceId = new PropagatedTraceId(parts[7]);
} catch (NumberFormatException e) {
}
}
} else if (HeaderVersion.v2.equals(version)) {
String[] parts = text.split("\\-", 9);
if (parts.length == 9) {
try {
// parts[0] is sample flag, always trace if header exists.
this.primaryDistributedTraceId = new PropagatedTraceId(Base64.decode2UTFString(parts[1]));
this.traceSegmentId = new ID(Base64.decode2UTFString(parts[2]));
this.spanId = Integer.parseInt(parts[3]);
this.parentApplicationInstanceId = Integer.parseInt(parts[4]);
this.entryApplicationInstanceId = Integer.parseInt(parts[5]);
this.peerHost = Base64.decode2UTFString(parts[6]);
this.entryOperationName = Base64.decode2UTFString(parts[7]);
this.parentOperationName = Base64.decode2UTFString(parts[8]);
} catch (NumberFormatException e) {
}
}
} else {
throw new IllegalArgumentException("Unimplemented header version." + version);
}
}
return this;
}
public boolean isValid() {
return isValid(HeaderVersion.v2) || isValid(HeaderVersion.v1);
}
/**
* Make sure this {@link ContextCarrier} has been initialized.
*
* @return true for unbroken {@link ContextCarrier} or no-initialized. Otherwise, false;
*/
public boolean isValid() {
return traceSegmentId != null
&& traceSegmentId.isValid()
&& getSpanId() > -1
&& parentApplicationInstanceId != DictionaryUtil.nullValue()
&& entryApplicationInstanceId != DictionaryUtil.nullValue()
&& !StringUtil.isEmpty(peerHost)
&& !StringUtil.isEmpty(entryOperationName)
&& !StringUtil.isEmpty(parentOperationName)
&& primaryDistributedTraceId != null;
boolean isValid(HeaderVersion version) {
if (HeaderVersion.v1.equals(version)) {
return traceSegmentId != null
&& traceSegmentId.isValid()
&& getSpanId() > -1
&& parentApplicationInstanceId != DictionaryUtil.nullValue()
&& entryApplicationInstanceId != DictionaryUtil.nullValue()
&& !StringUtil.isEmpty(peerHost)
&& !StringUtil.isEmpty(entryOperationName)
&& !StringUtil.isEmpty(parentOperationName)
&& primaryDistributedTraceId != null;
} else if (HeaderVersion.v2.equals(version)) {
return traceSegmentId != null
&& traceSegmentId.isValid()
&& getSpanId() > -1
&& parentApplicationInstanceId != DictionaryUtil.nullValue()
&& entryApplicationInstanceId != DictionaryUtil.nullValue()
&& !StringUtil.isEmpty(peerHost)
&& primaryDistributedTraceId != null;
} else {
throw new IllegalArgumentException("Unimplemented header version." + version);
}
}
public String getEntryOperationName() {
@ -229,4 +300,7 @@ public class ContextCarrier implements Serializable {
this.entryApplicationInstanceId = entryApplicationInstanceId;
}
public enum HeaderVersion {
v1, v2
}
}

View File

@ -16,14 +16,12 @@
*
*/
package org.apache.skywalking.apm.agent.core.context;
import java.util.List;
import org.apache.skywalking.apm.agent.core.context.ids.ID;
import org.apache.skywalking.apm.agent.core.context.ids.DistributedTraceId;
import org.apache.skywalking.apm.agent.core.context.ids.ID;
import org.apache.skywalking.apm.agent.core.dictionary.DictionaryUtil;
import org.apache.skywalking.apm.util.StringUtil;
/**
* The <code>ContextSnapshot</code> is a snapshot for current context. The snapshot carries the info for building
@ -98,9 +96,7 @@ public class ContextSnapshot {
return traceSegmentId != null
&& spanId > -1
&& entryApplicationInstanceId != DictionaryUtil.nullValue()
&& primaryDistributedTraceId != null
&& !StringUtil.isEmpty(entryOperationName)
&& !StringUtil.isEmpty(parentOperationName);
&& primaryDistributedTraceId != null;
}
public String getEntryOperationName() {
@ -114,7 +110,7 @@ public class ContextSnapshot {
public int getEntryApplicationInstanceId() {
return entryApplicationInstanceId;
}
public boolean isFromCurrent() {
return traceSegmentId.equals(ContextManager.capture().getTraceSegmentId());
}

View File

@ -27,12 +27,12 @@ public class SW3CarrierItem extends CarrierItem {
private ContextCarrier carrier;
public SW3CarrierItem(ContextCarrier carrier, CarrierItem next) {
super(HEADER_NAME, carrier.serialize(), next);
super(HEADER_NAME, carrier.serialize(ContextCarrier.HeaderVersion.v1), next);
this.carrier = carrier;
}
@Override
public void setHeadValue(String headValue) {
carrier.deserialize(headValue);
carrier.deserialize(headValue, ContextCarrier.HeaderVersion.v1);
}
}

View File

@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.skywalking.apm.agent.core.context;
/**
* @author wusheng
*/
public class SW6CarrierItem extends CarrierItem {
public static final String HEADER_NAME = "sw6";
private ContextCarrier carrier;
public SW6CarrierItem(ContextCarrier carrier, CarrierItem next) {
super(HEADER_NAME, carrier.serialize(ContextCarrier.HeaderVersion.v2), next);
this.carrier = carrier;
}
@Override
public void setHeadValue(String headValue) {
carrier.deserialize(headValue, ContextCarrier.HeaderVersion.v2);
}
}

View File

@ -38,6 +38,7 @@ import org.apache.skywalking.apm.agent.core.dictionary.PossibleFound;
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
import org.apache.skywalking.apm.agent.core.sampling.SamplingService;
import org.apache.skywalking.apm.util.StringUtil;
/**
* The <code>TracingContext</code> represents a core tracing logic controller. It build the final {@link
@ -94,8 +95,8 @@ public class TracingContext implements AbstractTracerContext {
* Inject the context into the given carrier, only when the active span is an exit one.
*
* @param carrier to carry the context for crossing process.
* @throws IllegalStateException if the active span isn't an exit one.
* Ref to {@link AbstractTracerContext#inject(ContextCarrier)}
* @throws IllegalStateException if the active span isn't an exit one. Ref to {@link
* AbstractTracerContext#inject(ContextCarrier)}
*/
@Override
public void inject(ContextCarrier carrier) {
@ -136,7 +137,9 @@ public class TracingContext implements AbstractTracerContext {
carrier.setEntryApplicationInstanceId(entryApplicationInstanceId);
if (operationId == DictionaryUtil.nullValue()) {
carrier.setEntryOperationName(operationName);
if (!StringUtil.isEmpty(operationName)) {
carrier.setEntryOperationName(operationName);
}
} else {
carrier.setEntryOperationId(operationId);
}
@ -154,8 +157,8 @@ public class TracingContext implements AbstractTracerContext {
/**
* Extract the carrier to build the reference for the pre segment.
*
* @param carrier carried the context from a cross-process segment.
* Ref to {@link AbstractTracerContext#extract(ContextCarrier)}
* @param carrier carried the context from a cross-process segment. Ref to {@link
* AbstractTracerContext#extract(ContextCarrier)}
*/
@Override
public void extract(ContextCarrier carrier) {
@ -171,8 +174,7 @@ public class TracingContext implements AbstractTracerContext {
/**
* Capture the snapshot of current context.
*
* @return the snapshot of context for cross-thread propagation
* Ref to {@link AbstractTracerContext#capture()}
* @return the snapshot of context for cross-thread propagation Ref to {@link AbstractTracerContext#capture()}
*/
@Override
public ContextSnapshot capture() {
@ -197,7 +199,9 @@ public class TracingContext implements AbstractTracerContext {
snapshot.setEntryApplicationInstanceId(entryApplicationInstanceId);
if (entryOperationId == DictionaryUtil.nullValue()) {
snapshot.setEntryOperationName(entryOperationName);
if (!StringUtil.isEmpty(entryOperationName)) {
snapshot.setEntryOperationName(entryOperationName);
}
} else {
snapshot.setEntryOperationId(entryOperationId);
}
@ -213,8 +217,7 @@ public class TracingContext implements AbstractTracerContext {
/**
* Continue the context from the given snapshot of parent thread.
*
* @param snapshot from {@link #capture()} in the parent thread.
* Ref to {@link AbstractTracerContext#continued(ContextSnapshot)}
* @param snapshot from {@link #capture()} in the parent thread. Ref to {@link AbstractTracerContext#continued(ContextSnapshot)}
*/
@Override
public void continued(ContextSnapshot snapshot) {
@ -236,8 +239,7 @@ public class TracingContext implements AbstractTracerContext {
* Create an entry span
*
* @param operationName most likely a service name
* @return span instance.
* Ref to {@link EntrySpan}
* @return span instance. Ref to {@link EntrySpan}
*/
@Override
public AbstractSpan createEntrySpan(final String operationName) {
@ -282,8 +284,7 @@ public class TracingContext implements AbstractTracerContext {
* Create a local span
*
* @param operationName most likely a local method signature, or business name.
* @return the span represents a local logic block.
* Ref to {@link LocalSpan}
* @return the span represents a local logic block. Ref to {@link LocalSpan}
*/
@Override
public AbstractSpan createLocalSpan(final String operationName) {

View File

@ -16,7 +16,6 @@
*
*/
package org.apache.skywalking.apm.agent.core.context.trace;
import org.apache.skywalking.apm.agent.core.conf.RemoteDownstreamConfig;
@ -24,11 +23,13 @@ import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
import org.apache.skywalking.apm.agent.core.context.ids.ID;
import org.apache.skywalking.apm.agent.core.dictionary.DictionaryUtil;
import org.apache.skywalking.apm.network.language.agent.*;
import org.apache.skywalking.apm.network.language.agent.RefType;
import org.apache.skywalking.apm.network.language.agent.TraceSegmentReference;
import org.apache.skywalking.apm.util.StringUtil;
/**
* {@link TraceSegmentRef} is like a pointer, which ref to another {@link TraceSegment},
* use {@link #spanId} point to the exact span of the ref {@link TraceSegment}.
* {@link TraceSegmentRef} is like a pointer, which ref to another {@link TraceSegment}, use {@link #spanId} point to
* the exact span of the ref {@link TraceSegment}.
* <p>
* Created by wusheng on 2017/2/17.
*/
@ -73,16 +74,20 @@ public class TraceSegmentRef {
this.peerId = Integer.parseInt(host);
}
String entryOperationName = carrier.getEntryOperationName();
if (entryOperationName.charAt(0) == '#') {
this.entryOperationName = entryOperationName.substring(1);
} else {
this.entryOperationId = Integer.parseInt(entryOperationName);
if (!StringUtil.isEmpty(entryOperationName)) {
if (entryOperationName.charAt(0) == '#') {
this.entryOperationName = entryOperationName.substring(1);
} else {
this.entryOperationId = Integer.parseInt(entryOperationName);
}
}
String parentOperationName = carrier.getParentOperationName();
if (parentOperationName.charAt(0) == '#') {
this.parentOperationName = parentOperationName.substring(1);
} else {
this.parentOperationId = Integer.parseInt(parentOperationName);
if (!StringUtil.isEmpty(parentOperationName)) {
if (parentOperationName.charAt(0) == '#') {
this.parentOperationName = parentOperationName.substring(1);
} else {
this.parentOperationId = Integer.parseInt(parentOperationName);
}
}
}
@ -93,16 +98,20 @@ public class TraceSegmentRef {
this.parentApplicationInstanceId = RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID;
this.entryApplicationInstanceId = snapshot.getEntryApplicationInstanceId();
String entryOperationName = snapshot.getEntryOperationName();
if (entryOperationName.charAt(0) == '#') {
this.entryOperationName = entryOperationName.substring(1);
} else {
this.entryOperationId = Integer.parseInt(entryOperationName);
if (!StringUtil.isEmpty(entryOperationName)) {
if (entryOperationName.charAt(0) == '#') {
this.entryOperationName = entryOperationName.substring(1);
} else {
this.entryOperationId = Integer.parseInt(entryOperationName);
}
}
String parentOperationName = snapshot.getParentOperationName();
if (parentOperationName.charAt(0) == '#') {
this.parentOperationName = parentOperationName.substring(1);
} else {
this.parentOperationId = Integer.parseInt(parentOperationName);
if (!StringUtil.isEmpty(parentOperationName)) {
if (parentOperationName.charAt(0) == '#') {
this.parentOperationName = parentOperationName.substring(1);
} else {
this.parentOperationId = Integer.parseInt(parentOperationName);
}
}
}
@ -135,13 +144,22 @@ public class TraceSegmentRef {
refBuilder.setEntryApplicationInstanceId(entryApplicationInstanceId);
refBuilder.setParentTraceSegmentId(traceSegmentId.transform());
refBuilder.setParentSpanId(spanId);
/**
* entryOperationId/entryOperationName and parentOperationId/parentOperationName could be empty at same time.
* This is accepted in v2 format.
*
*/
if (entryOperationId == DictionaryUtil.nullValue()) {
refBuilder.setEntryServiceName(entryOperationName);
if (!StringUtil.isEmpty(entryOperationName)) {
refBuilder.setEntryServiceName(entryOperationName);
}
} else {
refBuilder.setEntryServiceId(entryOperationId);
}
if (parentOperationId == DictionaryUtil.nullValue()) {
refBuilder.setParentServiceName(parentOperationName);
if (!StringUtil.isEmpty(parentOperationName)) {
refBuilder.setParentServiceName(parentOperationName);
}
} else {
refBuilder.setParentServiceId(parentOperationId);
}

View File

@ -0,0 +1,195 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.skywalking.apm.agent.core.context;
import java.util.ArrayList;
import java.util.List;
import org.apache.skywalking.apm.agent.core.conf.Config;
import org.apache.skywalking.apm.agent.core.context.ids.DistributedTraceId;
import org.apache.skywalking.apm.agent.core.context.ids.ID;
import org.apache.skywalking.apm.agent.core.context.ids.PropagatedTraceId;
import org.junit.Assert;
import org.junit.Test;
public class ContextCarrierV2HeaderTest {
@Test
public void testCompatibleHeaderKeys() {
Config.Agent.ACTIVE_V1_HEADER = true;
ContextCarrier contextCarrier = new ContextCarrier();
CarrierItem next = contextCarrier.items();
boolean hasSW3 = false;
boolean hasSW6 = false;
try {
while (next.hasNext()) {
next = next.next();
if (next.getHeadKey().equals("sw3")) {
hasSW3 = true;
} else if (next.getHeadKey().equals("sw6")) {
hasSW6 = true;
} else {
Assert.fail("unexpected key");
}
}
} finally {
Config.Agent.ACTIVE_V1_HEADER = false;
}
Assert.assertTrue(hasSW3);
Assert.assertTrue(hasSW6);
}
@Test
public void testDeserializeV2Header() {
ContextCarrier contextCarrier = new ContextCarrier();
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
if (next.getHeadKey().equals("sw3")) {
} else if (next.getHeadKey().equals("sw6")) {
next.setHeadValue("1-My40LjU=-MS4yLjM=-4-1-1-IzEyNy4wLjAuMTo4MDgw--");
} else {
Assert.fail("unexpected key");
}
}
Assert.assertTrue(contextCarrier.isValid());
Config.Agent.ACTIVE_V1_HEADER = true;
try {
contextCarrier = new ContextCarrier();
next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
if (next.getHeadKey().equals("sw3")) {
next.setHeadValue("1.2343.234234234|1|1|1|#127.0.0.1:8080|#/portal/|#/testEntrySpan|1.2343.234234234");
} else if (next.getHeadKey().equals("sw6")) {
} else {
Assert.fail("unexpected key");
}
}
} finally {
Config.Agent.ACTIVE_V1_HEADER = false;
}
Assert.assertTrue(contextCarrier.isValid());
}
@Test
public void testSerializeV2Header() {
List<DistributedTraceId> distributedTraceIds = new ArrayList<DistributedTraceId>();
distributedTraceIds.add(new PropagatedTraceId("3.4.5"));
ContextCarrier contextCarrier = new ContextCarrier();
contextCarrier.setTraceSegmentId(new ID(1, 2, 3));
contextCarrier.setDistributedTraceIds(distributedTraceIds);
contextCarrier.setSpanId(4);
contextCarrier.setEntryApplicationInstanceId(1);
contextCarrier.setParentApplicationInstanceId(1);
contextCarrier.setPeerHost("127.0.0.1:8080");
contextCarrier.setEntryOperationName("/portal");
contextCarrier.setParentOperationId(123);
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
if (next.getHeadKey().equals("sw3")) {
Assert.assertEquals("", next.getHeadValue());
} else if (next.getHeadKey().equals("sw6")) {
/**
* sampleFlag-traceId-segmentId-spanId-parentAppInstId-entryAppInstId-peerHost-entryEndpoint-parentEndpoint
*
* "1-3.4.5-1.2.3-4-1-1-#127.0.0.1:8080-#/portal-123"
*/
Assert.assertEquals("1-My40LjU=-MS4yLjM=-4-1-1-IzEyNy4wLjAuMTo4MDgw-Iy9wb3J0YWw=-MTIz", next.getHeadValue());
} else {
Assert.fail("unexpected key");
}
}
Config.Agent.ACTIVE_V1_HEADER = true;
try {
next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
if (next.getHeadKey().equals("sw3")) {
Assert.assertEquals("1.2.3|4|1|1|#127.0.0.1:8080|#/portal|123|3.4.5", next.getHeadValue());
} else if (next.getHeadKey().equals("sw6")) {
//TODO, no BASE64
Assert.assertEquals("1-My40LjU=-MS4yLjM=-4-1-1-IzEyNy4wLjAuMTo4MDgw-Iy9wb3J0YWw=-MTIz", next.getHeadValue());
} else {
Assert.fail("unexpected key");
}
}
} finally {
Config.Agent.ACTIVE_V1_HEADER = false;
}
Assert.assertTrue(contextCarrier.isValid());
}
@Test
public void testV2HeaderAccurate() {
List<DistributedTraceId> distributedTraceIds = new ArrayList<DistributedTraceId>();
distributedTraceIds.add(new PropagatedTraceId("3.4.5"));
ContextCarrier contextCarrier = new ContextCarrier();
contextCarrier.setTraceSegmentId(new ID(1, 2, 3));
contextCarrier.setDistributedTraceIds(distributedTraceIds);
contextCarrier.setSpanId(4);
contextCarrier.setEntryApplicationInstanceId(1);
contextCarrier.setParentApplicationInstanceId(1);
contextCarrier.setPeerHost("127.0.0.1:8080");
contextCarrier.setEntryOperationName("/portal");
contextCarrier.setParentOperationId(123);
CarrierItem next = contextCarrier.items();
String headerValue = null;
while (next.hasNext()) {
next = next.next();
if (next.getHeadKey().equals("sw3")) {
Assert.assertEquals("", next.getHeadValue());
} else if (next.getHeadKey().equals("sw6")) {
headerValue = next.getHeadValue();
} else {
Assert.fail("unexpected key");
}
}
ContextCarrier contextCarrier2 = new ContextCarrier();
next = contextCarrier2.items();
while (next.hasNext()) {
next = next.next();
if (next.getHeadKey().equals("sw3")) {
} else if (next.getHeadKey().equals("sw6")) {
next.setHeadValue(headerValue);
} else {
Assert.fail("unexpected key");
}
}
Assert.assertTrue(contextCarrier2.isValid());
Assert.assertEquals(contextCarrier.getSpanId(), contextCarrier2.getSpanId());
Assert.assertEquals(contextCarrier.getPeerHost(), contextCarrier2.getPeerHost());
Assert.assertEquals(contextCarrier.getDistributedTraceId(), contextCarrier2.getDistributedTraceId());
Assert.assertEquals(contextCarrier.getTraceSegmentId(), contextCarrier2.getTraceSegmentId());
Assert.assertEquals(contextCarrier.getEntryOperationName(), contextCarrier2.getEntryOperationName());
Assert.assertEquals(contextCarrier.getEntryApplicationInstanceId(), contextCarrier2.getEntryApplicationInstanceId());
Assert.assertEquals(contextCarrier.getParentApplicationInstanceId(), contextCarrier2.getParentApplicationInstanceId());
}
}

View File

@ -80,7 +80,7 @@ public class ContextManagerTest {
@Test
public void createSpanWithInvalidateContextCarrier() {
ContextCarrier contextCarrier = new ContextCarrier().deserialize("#AQA=#AQA=4WcWe0tQNQA=|1|#127.0.0.1:8080|#/testEntrySpan|#/testEntrySpan|#AQA=#AQA=Et0We0tQNQA=");
ContextCarrier contextCarrier = new ContextCarrier().deserialize("#AQA=#AQA=4WcWe0tQNQA=|1|#127.0.0.1:8080|#/testEntrySpan|#/testEntrySpan|#AQA=#AQA=Et0We0tQNQA=", ContextCarrier.HeaderVersion.v1);
AbstractSpan firstEntrySpan = ContextManager.createEntrySpan("/testEntrySpan", contextCarrier);
firstEntrySpan.setComponent(ComponentsDefine.TOMCAT);
@ -104,7 +104,7 @@ public class ContextManagerTest {
@Test
public void createMultipleEntrySpan() {
ContextCarrier contextCarrier = new ContextCarrier().deserialize("1.2343.234234234|1|1|1|#127.0.0.1:8080|#/portal/|#/testEntrySpan|1.2343.234234234");
ContextCarrier contextCarrier = new ContextCarrier().deserialize("1.2343.234234234|1|1|1|#127.0.0.1:8080|#/portal/|#/testEntrySpan|1.2343.234234234", ContextCarrier.HeaderVersion.v1);
assertTrue(contextCarrier.isValid());
AbstractSpan firstEntrySpan = ContextManager.createEntrySpan("/testFirstEntry", contextCarrier);
@ -227,7 +227,7 @@ public class ContextManagerTest {
@Test
public void testTransform() throws InvalidProtocolBufferException {
ContextCarrier contextCarrier = new ContextCarrier().deserialize("1.234.1983829|3|1|1|#127.0.0.1:8080|#/portal/|#/testEntrySpan|1.2343.234234234");
ContextCarrier contextCarrier = new ContextCarrier().deserialize("1.234.1983829|3|1|1|#127.0.0.1:8080|#/portal/|#/testEntrySpan|1.2343.234234234", ContextCarrier.HeaderVersion.v1);
assertTrue(contextCarrier.isValid());
AbstractSpan firstEntrySpan = ContextManager.createEntrySpan("/testFirstEntry", contextCarrier);

View File

@ -18,6 +18,7 @@
package org.apache.skywalking.apm.plugin.activemq;
import java.lang.reflect.Method;
import org.apache.activemq.command.MessageDispatch;
import org.apache.skywalking.apm.agent.core.context.CarrierItem;
import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
@ -30,8 +31,6 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceM
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
import java.lang.reflect.Method;
/**
* @author withlin
*/
@ -43,17 +42,19 @@ public class ActiveMQConsumerInterceptor implements InstanceMethodsAroundInterce
public static final byte TOPIC_TYPE = 2;
public static final byte TEMP_TOPIC_TYPE = 6;
public static final byte TEMP_QUEUE_TYPE = 5;
@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
ContextCarrier contextCarrier = new ContextCarrier();
String url = (String) objInst.getSkyWalkingDynamicField();
MessageDispatch messageDispatch = (MessageDispatch) allArguments[0];
String url = (String)objInst.getSkyWalkingDynamicField();
MessageDispatch messageDispatch = (MessageDispatch)allArguments[0];
AbstractSpan activeSpan = null;
if (messageDispatch.getDestination().getDestinationType() == QUEUE_TYPE || messageDispatch.getDestination().getDestinationType() == TEMP_QUEUE_TYPE) {
if (messageDispatch.getDestination().getDestinationType() == QUEUE_TYPE || messageDispatch.getDestination().getDestinationType() == TEMP_QUEUE_TYPE) {
activeSpan = ContextManager.createEntrySpan(OPERATE_NAME_PREFIX + "Queue/" + messageDispatch.getDestination().getPhysicalName() + CONSUMER_OPERATE_NAME_SUFFIX, null).start(System.currentTimeMillis());
Tags.MQ_BROKER.set(activeSpan, url);
Tags.MQ_QUEUE.set(activeSpan, messageDispatch.getDestination().getPhysicalName());
} else if (messageDispatch.getDestination().getDestinationType() == TOPIC_TYPE || messageDispatch.getDestination().getDestinationType() == TEMP_TOPIC_TYPE) {
} else if (messageDispatch.getDestination().getDestinationType() == TOPIC_TYPE || messageDispatch.getDestination().getDestinationType() == TEMP_TOPIC_TYPE) {
activeSpan = ContextManager.createEntrySpan(OPERATE_NAME_PREFIX + "Topic/" + messageDispatch.getDestination().getPhysicalName() + CONSUMER_OPERATE_NAME_SUFFIX, null).start(System.currentTimeMillis());
Tags.MQ_BROKER.set(activeSpan, url);
Tags.MQ_TOPIC.set(activeSpan, messageDispatch.getDestination().getPhysicalName());
@ -63,23 +64,26 @@ public class ActiveMQConsumerInterceptor implements InstanceMethodsAroundInterce
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
next.setHeadValue(messageDispatch.getMessage().getProperty(next.getHeadKey()).toString());
Object propertyValue = messageDispatch.getMessage().getProperty(next.getHeadKey());
if (propertyValue != null) {
next.setHeadValue(propertyValue.toString());
}
}
ContextManager.extract(contextCarrier);
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Object ret) throws Throwable {
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) throws Throwable {
ContextManager.stopSpan();
return ret;
}
@Override
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) {
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
ContextManager.activeSpan().errorOccurred().log(t);
}
}

View File

@ -16,7 +16,6 @@
*
*/
package org.apache.skywalking.apm.plugin.activemq;
import org.apache.activemq.command.ActiveMQDestination;
@ -24,6 +23,7 @@ import org.apache.activemq.command.Message;
import org.apache.activemq.command.MessageDispatch;
import org.apache.activemq.command.Response;
import org.apache.activemq.state.CommandVisitor;
import org.apache.skywalking.apm.agent.core.conf.Config;
import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
@ -62,7 +62,7 @@ public class ActiveMQConsumerInterceptorTest {
private MessageDispatch messageDispatch;
public class Des extends ActiveMQDestination {
public class Des extends ActiveMQDestination {
@Override
protected String getQualifiedPrefix() {
@ -80,7 +80,7 @@ public class ActiveMQConsumerInterceptorTest {
}
}
public class Msg extends Message {
public class Msg extends Message {
@Override
public Message copy() {
@ -126,22 +126,28 @@ public class ActiveMQConsumerInterceptorTest {
@Before
public void setUp() throws IOException {
Config.Agent.ACTIVE_V1_HEADER = true;
activeMQConsumerInterceptor = new ActiveMQConsumerInterceptor();
messageDispatch = new MessageDispatch();
Des des = new Des();
des.setPhysicalName("test");
messageDispatch.setDestination(des);
Message msg = new Msg();
msg.setProperty("sw3","");
Message msg = new Msg();
msg.setProperty("sw3", "");
messageDispatch.setMessage(msg);
arguments = new Object[] {messageDispatch};
argumentType = null;
}
@After
public void clear() {
Config.Agent.ACTIVE_V1_HEADER = false;
}
@Test
public void testConsumerWithoutMessage() throws Throwable {
activeMQConsumerInterceptor.beforeMethod(enhancedInstance,null,arguments,null,null);
activeMQConsumerInterceptor.beforeMethod(enhancedInstance, null, arguments, null, null);
activeMQConsumerInterceptor.afterMethod(enhancedInstance, null, arguments, null, null);
List<TraceSegment> traceSegments = segmentStorage.getTraceSegments();

View File

@ -44,6 +44,7 @@ import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
import org.hamcrest.CoreMatchers;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@ -93,6 +94,7 @@ public class DubboInterceptorTest {
@Before
public void setUp() throws Exception {
Config.Agent.ACTIVE_V1_HEADER = true;
dubboInterceptor = new DubboInterceptor();
PowerMockito.mockStatic(RpcContext.class);
@ -108,6 +110,11 @@ public class DubboInterceptorTest {
Config.Agent.APPLICATION_CODE = "DubboTestCases-APP";
}
@After
public void clear() {
Config.Agent.ACTIVE_V1_HEADER = false;
}
@Test
public void testServiceFromPlugin() {
PluginBootService service = ServiceManager.INSTANCE.findService(PluginBootService.class);

View File

@ -19,6 +19,7 @@
package org.apache.skywalking.apm.plugin.jetty.v9.server;
import java.util.List;
import org.apache.skywalking.apm.agent.core.conf.Config;
import org.apache.skywalking.apm.agent.core.context.SW3CarrierItem;
import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity;
@ -44,6 +45,7 @@ import org.eclipse.jetty.server.HttpInput;
import org.eclipse.jetty.server.HttpTransport;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@ -84,6 +86,7 @@ public class HandleInterceptorTest {
@Before
public void setUp() throws Exception {
Config.Agent.ACTIVE_V1_HEADER = true;
jettyInvokeInterceptor = new HandleInterceptor();
when(request.getRequestURI()).thenReturn("/test/testRequestURL");
when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/test/testRequestURL"));
@ -95,6 +98,11 @@ public class HandleInterceptorTest {
}
@After
public void clear() {
Config.Agent.ACTIVE_V1_HEADER = false;
}
@Test
public void testWithoutSerializedContextData() throws Throwable {
jettyInvokeInterceptor.beforeMethod(service, null, arguments, argumentType, methodInterceptResult);

View File

@ -24,6 +24,7 @@ import java.util.List;
import java.util.Map;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.common.TopicPartition;
import org.apache.skywalking.apm.agent.core.conf.Config;
import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
@ -39,6 +40,7 @@ import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
import org.apache.skywalking.apm.plugin.kafka.v1.ConsumerEnhanceRequiredInfo;
import org.apache.skywalking.apm.plugin.kafka.v1.KafkaConsumerInterceptor;
import org.hamcrest.MatcherAssert;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@ -78,6 +80,7 @@ public class KafkaConsumerInterceptorTest {
@Before
public void setUp() {
Config.Agent.ACTIVE_V1_HEADER = true;
consumerInterceptor = new KafkaConsumerInterceptor();
consumerEnhanceRequiredInfo = new ConsumerEnhanceRequiredInfo();
@ -99,6 +102,11 @@ public class KafkaConsumerInterceptorTest {
messages.put(topicPartition, records);
}
@After
public void clear() {
Config.Agent.ACTIVE_V1_HEADER = false;
}
@Test
public void testConsumerWithoutMessage() throws Throwable {
consumerInterceptor.beforeMethod(consumerInstance, null, new Object[0], new Class[0], null);

View File

@ -24,6 +24,7 @@ import com.weibo.api.motan.rpc.Response;
import com.weibo.api.motan.rpc.URL;
import java.util.HashMap;
import java.util.List;
import org.apache.skywalking.apm.agent.core.conf.Config;
import org.apache.skywalking.apm.agent.core.context.SW3CarrierItem;
import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
@ -37,6 +38,7 @@ import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
import org.apache.skywalking.apm.agent.test.tools.SpanAssert;
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
import org.hamcrest.MatcherAssert;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@ -81,6 +83,7 @@ public class MotanProviderInterceptorTest {
@Before
public void setUp() {
Config.Agent.ACTIVE_V1_HEADER = true;
invokeInterceptor = new MotanProviderInterceptor();
url = URL.valueOf("motan://127.0.0.1:34000/org.apache.skywalking.apm.test.TestService");
@ -92,6 +95,12 @@ public class MotanProviderInterceptorTest {
when(request.getParamtersDesc()).thenReturn("java.lang.String, java.lang.Object");
}
@After
public void clear() {
Config.Agent.ACTIVE_V1_HEADER = false;
}
@Test
public void testInvokerWithoutRefSegment() throws Throwable {
invokeInterceptor.beforeMethod(enhancedInstance, null, arguments, argumentType, null);

View File

@ -40,6 +40,7 @@ import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
import org.hamcrest.CoreMatchers;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@ -81,17 +82,18 @@ public class SofaRpcProviderInterceptorTest {
@Mock
private ProviderInvoker invoker;
private SofaRequest sofaRequest = PowerMockito.mock(SofaRequest.class);
private SofaRequest sofaRequest = PowerMockito.mock(SofaRequest.class);
@Mock
private MethodInterceptResult methodInterceptResult;
private SofaResponse sofaResponse = PowerMockito.mock(SofaResponse.class);
private Object[] allArguments;
private Class[] argumentTypes;
private Class[] argumentTypes;
@Before
public void setUp() throws Exception {
Config.Agent.ACTIVE_V1_HEADER = true;
sofaRpcProviderInterceptor = new SofaRpcProviderInterceptor();
PowerMockito.mockStatic(RpcInternalContext.class);
@ -111,11 +113,16 @@ public class SofaRpcProviderInterceptorTest {
Config.Agent.APPLICATION_CODE = "SOFARPC-TestCases-APP";
}
@After
public void clear() {
Config.Agent.ACTIVE_V1_HEADER = false;
}
@Test
public void testProviderWithAttachment() throws Throwable {
when(rpcContext.isConsumerSide()).thenReturn(false);
when(sofaRequest.getRequestProp(SKYWALKING_PREFIX + SW3CarrierItem.HEADER_NAME)).thenReturn(
"1.323.4433|3|1|1|#192.168.1.8 :18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
"1.323.4433|3|1|1|#192.168.1.8 :18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
sofaRpcProviderInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
sofaRpcProviderInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, sofaResponse);

View File

@ -23,7 +23,9 @@ import com.opensymphony.xwork2.ActionContext;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.skywalking.apm.agent.core.conf.Config;
import org.apache.struts2.StrutsStatics;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@ -92,6 +94,7 @@ public class Struts2InterceptorTest {
@Before
public void setUp() throws Exception {
Config.Agent.ACTIVE_V1_HEADER = true;
struts2Interceptor = new Struts2Interceptor();
when(request.getRequestURI()).thenReturn("/test/testRequestURL");
when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/test/testRequestURL"));
@ -110,6 +113,11 @@ public class Struts2InterceptorTest {
exceptionArgumentType = new Class[] {request.getClass(), response.getClass(), new RuntimeException().getClass()};
}
@After
public void clear() {
Config.Agent.ACTIVE_V1_HEADER = false;
}
@Test
public void testWithoutSerializedContextData() throws Throwable {
struts2Interceptor.beforeMethod(enhancedInstance, null, arguments, argumentType, methodInterceptResult);

View File

@ -16,12 +16,12 @@
*
*/
package org.apache.skywalking.apm.plugin.tomcat78x;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.skywalking.apm.agent.core.conf.Config;
import org.apache.skywalking.apm.agent.core.context.SW3CarrierItem;
import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
@ -31,6 +31,7 @@ import org.apache.skywalking.apm.agent.test.helper.SpanHelper;
import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
import org.apache.skywalking.apm.agent.test.tools.SpanAssert;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@ -82,6 +83,8 @@ public class TomcatInvokeInterceptorTest {
@Before
public void setUp() throws Exception {
Config.Agent.ACTIVE_V1_HEADER = true;
tomcatInvokeInterceptor = new TomcatInvokeInterceptor();
tomcatExceptionInterceptor = new TomcatExceptionInterceptor();
when(request.getRequestURI()).thenReturn("/test/testRequestURL");
@ -94,6 +97,11 @@ public class TomcatInvokeInterceptorTest {
exceptionArgumentType = new Class[] {request.getClass(), response.getClass(), new RuntimeException().getClass()};
}
@After
public void clear() {
Config.Agent.ACTIVE_V1_HEADER = false;
}
@Test
public void testWithoutSerializedContextData() throws Throwable {
tomcatInvokeInterceptor.beforeMethod(enhancedInstance, null, arguments, argumentType, methodInterceptResult);

View File

@ -18,6 +18,7 @@
package org.apache.skywalking.apm.plugin.undertow.v2x;
import org.apache.skywalking.apm.agent.core.conf.Config;
import org.apache.skywalking.apm.agent.core.context.SW3CarrierItem;
import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity;
@ -36,6 +37,7 @@ import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
import org.apache.skywalking.apm.agent.test.tools.SpanAssert;
import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
@ -89,6 +91,7 @@ public class ExecuteRootHandlerInterceptorTest {
@Before
public void setUp() throws Exception {
Config.Agent.ACTIVE_V1_HEADER = true;
executeRootHandlerInterceptor = new ExecuteRootHandlerInterceptor();
exchange = new HttpServerExchange(serverConnection, requestHeaders, responseHeaders, 0);
exchange.setRequestURI("/test/testRequestURL");
@ -96,8 +99,13 @@ public class ExecuteRootHandlerInterceptorTest {
exchange.setDestinationAddress(new InetSocketAddress("localhost", 8080));
exchange.setRequestScheme("http");
exchange.setRequestMethod(HttpString.tryFromString("POST"));
arguments = new Object[]{httpHandler, exchange};
argumentType = new Class[]{httpHandler.getClass(), exchange.getClass()};
arguments = new Object[] {httpHandler, exchange};
argumentType = new Class[] {httpHandler.getClass(), exchange.getClass()};
}
@After
public void clear() {
Config.Agent.ACTIVE_V1_HEADER = false;
}
@Test

View File

@ -16,31 +16,17 @@
*
*/
package org.apache.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.apache.skywalking.apm.agent.test.helper.SegmentHelper;
import org.apache.skywalking.apm.agent.test.tools.SegmentRefAssert;
import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
import org.apache.skywalking.apm.agent.test.tools.SpanAssert;
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.apache.skywalking.apm.agent.core.conf.Config;
import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
import org.apache.skywalking.apm.agent.core.context.SW3CarrierItem;
import org.apache.skywalking.apm.agent.core.context.ids.ID;
@ -48,7 +34,12 @@ import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.apache.skywalking.apm.agent.core.context.trace.TraceSegmentRef;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.test.helper.SegmentHelper;
import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
import org.apache.skywalking.apm.agent.test.tools.SegmentRefAssert;
import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
import org.apache.skywalking.apm.agent.test.tools.SpanAssert;
import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
import org.apache.skywalking.apm.toolkit.activation.opentracing.continuation.ActivateInterceptor;
import org.apache.skywalking.apm.toolkit.activation.opentracing.continuation.ConstructorInterceptor;
@ -62,12 +53,20 @@ import org.apache.skywalking.apm.toolkit.opentracing.SkywalkingContinuation;
import org.apache.skywalking.apm.toolkit.opentracing.SkywalkingSpan;
import org.apache.skywalking.apm.toolkit.opentracing.SkywalkingSpanBuilder;
import org.apache.skywalking.apm.toolkit.opentracing.TextMapContext;
import org.junit.After;
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 static org.apache.skywalking.apm.agent.test.tools.SpanAssert.assertComponent;
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.apache.skywalking.apm.agent.test.tools.SpanAssert.assertComponent;
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(TracingSegmentRunner.class)
@ -106,15 +105,16 @@ public class SkywalkingSpanActivationTest {
@Before
public void setUp() {
Config.Agent.ACTIVE_V1_HEADER = true;
spanBuilder = new SkywalkingSpanBuilder("test").withTag(Tags.COMPONENT.getKey(), "test");
constructorWithSpanBuilderInterceptor = new ConstructorWithSpanBuilderInterceptor();
spanLogInterceptor = new SpanLogInterceptor();
logArgument = new Object[]{111111111L, event};
logArgumentType = new Class[]{long.class, HashMap.class};
logArgument = new Object[] {111111111L, event};
logArgumentType = new Class[] {long.class, HashMap.class};
setOperationNameInterceptor = new SpanSetOperationNameInterceptor();
setOperationNameArgument = new Object[]{"testOperationName"};
setOperationNameArgumentType = new Class[]{String.class};
setOperationNameArgument = new Object[] {"testOperationName"};
setOperationNameArgumentType = new Class[] {String.class};
spanFinishInterceptor = new SpanFinishInterceptor();
@ -125,6 +125,11 @@ public class SkywalkingSpanActivationTest {
activateInterceptor = new ActivateInterceptor();
}
@After
public void clear() {
Config.Agent.ACTIVE_V1_HEADER = false;
}
@Test
public void testCreateLocalSpan() throws Throwable {
startSpan();
@ -167,7 +172,7 @@ public class SkywalkingSpanActivationTest {
@Test
public void testCreateExitSpanWithPeer() throws Throwable {
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");
.withTag(Tags.PEER_HOST_IPV4.getKey(), "127.0.0.1").withTag(Tags.PEER_PORT.getKey(), "8080");
startSpan();
stopSpan();
@ -189,7 +194,7 @@ public class SkywalkingSpanActivationTest {
@Test
public void testInject() throws Throwable {
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);
.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>();
@ -207,7 +212,7 @@ public class SkywalkingSpanActivationTest {
};
injectInterceptor.afterMethod(enhancedInstance, null,
new Object[]{new TextMapContext(), Format.Builtin.TEXT_MAP, carrier}, null, null);
new Object[] {new TextMapContext(), Format.Builtin.TEXT_MAP, carrier}, null, null);
String[] parts = values.get(SW3CarrierItem.HEADER_NAME).split("\\|", 8);
Assert.assertEquals("0", parts[1]);
@ -219,7 +224,7 @@ public class SkywalkingSpanActivationTest {
@Test
public void testExtractWithValidateContext() throws Throwable {
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);
.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() {
@ -238,7 +243,7 @@ public class SkywalkingSpanActivationTest {
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[]{Format.Builtin.TEXT_MAP, carrier}, new Class[]{}, null);
new Object[] {Format.Builtin.TEXT_MAP, carrier}, new Class[] {}, null);
stopSpan();
TraceSegment tracingSegment = assertTraceSemgnets();
@ -256,7 +261,7 @@ public class SkywalkingSpanActivationTest {
@Test
public void testExtractWithInValidateContext() throws Throwable {
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);
.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>();
@ -276,7 +281,7 @@ public class SkywalkingSpanActivationTest {
values.put(SW3CarrierItem.HEADER_NAME, "aaaaaaaa|3|#192.168.1.8:18002|#/portal/|#/testEntrySpan|1.234.444");
extractInterceptor.afterMethod(enhancedInstance, null,
new Object[]{Format.Builtin.TEXT_MAP, carrier}, new Class[]{}, null);
new Object[] {Format.Builtin.TEXT_MAP, carrier}, new Class[] {}, null);
stopSpan();
TraceSegment tracingSegment = assertTraceSemgnets();
@ -340,11 +345,11 @@ public class SkywalkingSpanActivationTest {
}
private void startSpan(MockEnhancedInstance enhancedInstance) throws Throwable {
constructorWithSpanBuilderInterceptor.onConstruct(enhancedInstance, new Object[]{spanBuilder});
constructorWithSpanBuilderInterceptor.onConstruct(enhancedInstance, new Object[] {spanBuilder});
spanLogInterceptor.afterMethod(enhancedInstance, null, logArgument, logArgumentType, null);
setOperationNameInterceptor.afterMethod(enhancedInstance, SkywalkingSpan.class.getMethod("setOperationName", String.class),
setOperationNameArgument, setOperationNameArgumentType, null);
setOperationNameArgument, setOperationNameArgumentType, null);
}
private class MockEnhancedInstance implements EnhancedInstance {

View File

@ -175,7 +175,15 @@ public class MultiScopesSpanListener implements EntrySpanListener, ExitSpanListe
sourceReceiver.receive(entrySourceBuilder.toEndpoint());
sourceReceiver.receive(entrySourceBuilder.toServiceRelation());
sourceReceiver.receive(entrySourceBuilder.toServiceInstanceRelation());
sourceReceiver.receive(entrySourceBuilder.toEndpointRelation());
EndpointRelation endpointRelation = entrySourceBuilder.toEndpointRelation();
/**
* Parent endpoint could be none, because in SkyWalking Cross Process Propagation Headers Protocol v2,
* endpoint in ref could be empty, based on that, endpoint relation maybe can't be established.
* So, I am making this source as optional.
*/
if (endpointRelation != null) {
sourceReceiver.receive(endpointRelation);
}
});
exitSourceBuilders.forEach(exitSourceBuilder -> {

View File

@ -19,6 +19,7 @@
package org.apache.skywalking.oap.server.receiver.trace.provider.parser.listener.endpoint;
import lombok.*;
import org.apache.skywalking.apm.util.StringUtil;
import org.apache.skywalking.oap.server.core.source.*;
/**
@ -145,6 +146,9 @@ class SourceBuilder {
}
EndpointRelation toEndpointRelation() {
if (StringUtil.isEmpty(sourceEndpointName) || StringUtil.isEmpty(destEndpointName)) {
return null;
}
EndpointRelation endpointRelation = new EndpointRelation();
endpointRelation.setEndpointId(sourceEndpointId);
endpointRelation.setEndpoint(sourceEndpointName);