You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2018/11/07 15:32:43 UTC

[incubator-skywalking] branch sw6-header created (now 1d16d97)

This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a change to branch sw6-header
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking.git.


      at 1d16d97  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

This branch includes the following new commits:

     new 1d16d97  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

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[incubator-skywalking] 01/01: 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

Posted by wu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch sw6-header
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking.git

commit 1d16d97102b917d9002c93385794d06bb06e6a59
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Wed Nov 7 23:32:33 2018 +0800

    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
---
 .../skywalking/apm/agent/core/conf/Config.java     |  10 ++
 .../apm/agent/core/context/ContextCarrier.java     | 169 +++++++++++++++------
 .../apm/agent/core/context/SW3CarrierItem.java     |   4 +-
 .../{SW3CarrierItem.java => SW6CarrierItem.java}   |  13 +-
 .../agent/core/context/trace/TraceSegmentRef.java  |  42 +++--
 .../core/context/ContextCarrierV2HeaderTest.java   | 145 ++++++++++++++++++
 .../apm/agent/core/context/ContextManagerTest.java |   6 +-
 .../apm/plugin/dubbo/DubboInterceptorTest.java     |   7 +
 .../jetty/v9/server/HandleInterceptorTest.java     |   8 +
 .../plugin/motan/MotanProviderInterceptorTest.java |   9 ++
 .../apm/plugin/struts2/Struts2InterceptorTest.java |   8 +
 .../tomcat78x/TomcatInvokeInterceptorTest.java     |  10 +-
 12 files changed, 356 insertions(+), 75 deletions(-)

diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java
index dfdea53..b44f40f 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java
@@ -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 {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextCarrier.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextCarrier.java
index 52c5ae8..f3948fe 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextCarrier.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextCarrier.java
@@ -16,11 +16,11 @@
  *
  */
 
-
 package org.apache.skywalking.apm.agent.core.context;
 
 import java.io.Serializable;
 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;
@@ -29,8 +29,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 +41,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 +61,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 +76,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) {
+            SW6CarrierItem sw6CarrierItem = new SW6CarrierItem(this, null);
+            SW3CarrierItem carrierItem = new SW3CarrierItem(this, sw6CarrierItem);
+            head = new CarrierItemHead(carrierItem);
+        } 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",
+                        this.getTraceSegmentId().encode(),
+                        this.getSpanId() + "",
+                        this.getParentApplicationInstanceId() + "",
+                        this.getEntryApplicationInstanceId() + "",
+                        this.getPeerHost(),
+                        this.getPrimaryDistributedTraceId().encode(),
+                        this.getEntryOperationName(),
+                        this.getParentOperationName());
+                } else {
+                    return "";
+                }
+            }
         } else {
             return "";
         }
@@ -111,42 +140,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(parts[1]);
+                        this.traceSegmentId = new ID(parts[2]);
+                        this.spanId = Integer.parseInt(parts[3]);
+                        this.parentApplicationInstanceId = Integer.parseInt(parts[4]);
+                        this.entryApplicationInstanceId = Integer.parseInt(parts[5]);
+                        this.peerHost = parts[6];
+                        this.entryOperationName = parts[7];
+                        this.parentOperationName = 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 +299,7 @@ public class ContextCarrier implements Serializable {
         this.entryApplicationInstanceId = entryApplicationInstanceId;
     }
 
+    public enum HeaderVersion {
+        v1, v2
+    }
 }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW3CarrierItem.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW3CarrierItem.java
index f455ebd..5d05778 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW3CarrierItem.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW3CarrierItem.java
@@ -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);
     }
 }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW3CarrierItem.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW6CarrierItem.java
similarity index 76%
copy from apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW3CarrierItem.java
copy to apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW6CarrierItem.java
index f455ebd..8068fdf 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW3CarrierItem.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW6CarrierItem.java
@@ -16,23 +16,22 @@
  *
  */
 
-
 package org.apache.skywalking.apm.agent.core.context;
 
 /**
  * @author wusheng
  */
-public class SW3CarrierItem extends CarrierItem {
-    public static final String HEADER_NAME = "sw3";
+public class SW6CarrierItem extends CarrierItem {
+    public static final String HEADER_NAME = "sw6";
     private ContextCarrier carrier;
 
-    public SW3CarrierItem(ContextCarrier carrier, CarrierItem next) {
-        super(HEADER_NAME, carrier.serialize(), next);
+    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);
+        carrier.deserialize(headValue, ContextCarrier.HeaderVersion.v2);
     }
-}
+}
\ No newline at end of file
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/TraceSegmentRef.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/TraceSegmentRef.java
index 5ea44f6..6fab03e 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/TraceSegmentRef.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/TraceSegmentRef.java
@@ -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);
+            }
         }
     }
 
@@ -135,13 +140,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);
         }
diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/ContextCarrierV2HeaderTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/ContextCarrierV2HeaderTest.java
new file mode 100644
index 0000000..c4f4777
--- /dev/null
+++ b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/ContextCarrierV2HeaderTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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);
+    }
+
+    /**
+     * sampleFlag-segmentId-parentAppInstId-entryAppInstId-peerHost-traceId-entryEndpoint-parentEndpoint
+     */
+    @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")) {
+                //TODO, wait for base64 solution
+                next.setHeadValue("1-3.4.5-1.2.3-2-10-11-#127.0.0.1:8080--");
+            } 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")) {
+                //TODO, no BASE64
+                Assert.assertEquals("1-1.2.3-4-1-1-#127.0.0.1:8080-3.4.5-#/portal-123", 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-1.2.3-4-1-1-#127.0.0.1:8080-3.4.5-#/portal-123", next.getHeadValue());
+                } else {
+                    Assert.fail("unexpected key");
+                }
+            }
+
+        } finally {
+            Config.Agent.ACTIVE_V1_HEADER = false;
+        }
+
+        Assert.assertTrue(contextCarrier.isValid());
+    }
+}
diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/ContextManagerTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/ContextManagerTest.java
index 659fe32..9da466a 100644
--- a/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/ContextManagerTest.java
+++ b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/ContextManagerTest.java
@@ -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);
diff --git a/apm-sniffer/apm-sdk-plugin/dubbo-plugin/src/test/java/org/apache/skywalking/apm/plugin/dubbo/DubboInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/dubbo-plugin/src/test/java/org/apache/skywalking/apm/plugin/dubbo/DubboInterceptorTest.java
index 4011eb3..a9b0fd4 100644
--- a/apm-sniffer/apm-sdk-plugin/dubbo-plugin/src/test/java/org/apache/skywalking/apm/plugin/dubbo/DubboInterceptorTest.java
+++ b/apm-sniffer/apm-sdk-plugin/dubbo-plugin/src/test/java/org/apache/skywalking/apm/plugin/dubbo/DubboInterceptorTest.java
@@ -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);
diff --git a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jetty/v9/server/HandleInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jetty/v9/server/HandleInterceptorTest.java
index bafc483..bf6958b 100644
--- a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jetty/v9/server/HandleInterceptorTest.java
+++ b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jetty/v9/server/HandleInterceptorTest.java
@@ -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);
diff --git a/apm-sniffer/apm-sdk-plugin/motan-plugin/src/test/java/org/apache/skywalking/apm/plugin/motan/MotanProviderInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/motan-plugin/src/test/java/org/apache/skywalking/apm/plugin/motan/MotanProviderInterceptorTest.java
index f0dae8f..cfe42d1 100644
--- a/apm-sniffer/apm-sdk-plugin/motan-plugin/src/test/java/org/apache/skywalking/apm/plugin/motan/MotanProviderInterceptorTest.java
+++ b/apm-sniffer/apm-sdk-plugin/motan-plugin/src/test/java/org/apache/skywalking/apm/plugin/motan/MotanProviderInterceptorTest.java
@@ -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);
diff --git a/apm-sniffer/apm-sdk-plugin/struts2-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/struts2/Struts2InterceptorTest.java b/apm-sniffer/apm-sdk-plugin/struts2-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/struts2/Struts2InterceptorTest.java
index 214183c..a5957d1 100644
--- a/apm-sniffer/apm-sdk-plugin/struts2-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/struts2/Struts2InterceptorTest.java
+++ b/apm-sniffer/apm-sdk-plugin/struts2-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/struts2/Struts2InterceptorTest.java
@@ -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);
diff --git a/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/tomcat78x/TomcatInvokeInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/tomcat78x/TomcatInvokeInterceptorTest.java
index b230128..7b5a8f4 100644
--- a/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/tomcat78x/TomcatInvokeInterceptorTest.java
+++ b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/tomcat78x/TomcatInvokeInterceptorTest.java
@@ -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);