Refactor the span context to use ALS
diff --git a/Dockerfile.agent.test b/Dockerfile.agent.test
deleted file mode 100644
index 0e66a05..0000000
--- a/Dockerfile.agent.test
+++ /dev/null
@@ -1,22 +0,0 @@
-# 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.
-
-FROM node:12
-
-WORKDIR /dependencies
-
-COPY package.json .
-
-RUN npm install
diff --git a/package-lock.json b/package-lock.json
index ca345e1..a4570cf 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
-  "name": "@ali/skywalking-nodejs",
-  "version": "0.0.21-RC",
+  "name": "skywalking",
+  "version": "0.1.0",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
@@ -1591,18 +1591,250 @@
       }
     },
     "grpc-tools": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npmjs.org/grpc-tools/-/grpc-tools-1.9.0.tgz",
-      "integrity": "sha512-du10qytFNDVNYGJQ/AxXTF6lXchgCZ7ls8BtBDCtnuinjGbnPFHpOIzoEAT8NsmgFg4RCpsWW8vsQ+RCyQ3SXA==",
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/grpc-tools/-/grpc-tools-1.8.0.tgz",
+      "integrity": "sha512-GzYHjPQ/sbV/DmnNRksapMlLj26Tvq2Qppmzjmd+lHYZNeWM1feiGsYCduzJLyy295P+3uYIPy2/w/1thAnOow==",
       "dev": true,
       "requires": {
         "node-pre-gyp": "^0.12.0"
       },
       "dependencies": {
+        "abbrev": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "ansi-regex": {
+          "version": "2.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "aproba": {
+          "version": "1.2.0",
+          "bundled": true,
+          "dev": true
+        },
+        "are-we-there-yet": {
+          "version": "1.1.5",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "delegates": "^1.0.0",
+            "readable-stream": "^2.0.6"
+          }
+        },
+        "balanced-match": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "brace-expansion": {
+          "version": "1.1.11",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "balanced-match": "^1.0.0",
+            "concat-map": "0.0.1"
+          }
+        },
+        "chownr": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "code-point-at": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true
+        },
+        "concat-map": {
+          "version": "0.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "console-control-strings": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true
+        },
+        "core-util-is": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "debug": {
+          "version": "2.6.9",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "deep-extend": {
+          "version": "0.6.0",
+          "bundled": true,
+          "dev": true
+        },
+        "delegates": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "detect-libc": {
+          "version": "1.0.3",
+          "bundled": true,
+          "dev": true
+        },
+        "fs-minipass": {
+          "version": "1.2.5",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "minipass": "^2.2.1"
+          }
+        },
+        "fs.realpath": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "gauge": {
+          "version": "2.7.4",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "aproba": "^1.0.3",
+            "console-control-strings": "^1.0.0",
+            "has-unicode": "^2.0.0",
+            "object-assign": "^4.1.0",
+            "signal-exit": "^3.0.0",
+            "string-width": "^1.0.1",
+            "strip-ansi": "^3.0.1",
+            "wide-align": "^1.1.0"
+          }
+        },
+        "glob": {
+          "version": "7.1.3",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "has-unicode": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "iconv-lite": {
+          "version": "0.4.24",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "safer-buffer": ">= 2.1.2 < 3"
+          }
+        },
+        "ignore-walk": {
+          "version": "3.0.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "minimatch": "^3.0.4"
+          }
+        },
+        "inflight": {
+          "version": "1.0.6",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "once": "^1.3.0",
+            "wrappy": "1"
+          }
+        },
+        "inherits": {
+          "version": "2.0.3",
+          "bundled": true,
+          "dev": true
+        },
+        "ini": {
+          "version": "1.3.5",
+          "bundled": true,
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "number-is-nan": "^1.0.0"
+          }
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "minimatch": {
+          "version": "3.0.4",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^1.1.7"
+          }
+        },
+        "minimist": {
+          "version": "0.0.8",
+          "bundled": true,
+          "dev": true
+        },
+        "minipass": {
+          "version": "2.3.5",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "safe-buffer": "^5.1.2",
+            "yallist": "^3.0.0"
+          }
+        },
+        "minizlib": {
+          "version": "1.2.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "minipass": "^2.2.1"
+          }
+        },
+        "mkdirp": {
+          "version": "0.5.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "minimist": "0.0.8"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "needle": {
+          "version": "2.2.4",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "debug": "^2.1.2",
+            "iconv-lite": "^0.4.4",
+            "sax": "^1.2.4"
+          }
+        },
         "node-pre-gyp": {
           "version": "0.12.0",
-          "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz",
-          "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==",
+          "bundled": true,
           "dev": true,
           "requires": {
             "detect-libc": "^1.0.2",
@@ -1615,15 +1847,226 @@
             "rimraf": "^2.6.1",
             "semver": "^5.3.0",
             "tar": "^4"
+          }
+        },
+        "nopt": {
+          "version": "4.0.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "abbrev": "1",
+            "osenv": "^0.1.4"
+          }
+        },
+        "npm-bundled": {
+          "version": "1.0.6",
+          "bundled": true,
+          "dev": true
+        },
+        "npm-packlist": {
+          "version": "1.4.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "ignore-walk": "^3.0.1",
+            "npm-bundled": "^1.0.1"
+          }
+        },
+        "npmlog": {
+          "version": "4.1.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "are-we-there-yet": "~1.1.2",
+            "console-control-strings": "~1.1.0",
+            "gauge": "~2.7.3",
+            "set-blocking": "~2.0.0"
+          }
+        },
+        "number-is-nan": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "object-assign": {
+          "version": "4.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "once": {
+          "version": "1.4.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "wrappy": "1"
+          }
+        },
+        "os-homedir": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "os-tmpdir": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "osenv": {
+          "version": "0.1.5",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "os-homedir": "^1.0.0",
+            "os-tmpdir": "^1.0.0"
+          }
+        },
+        "path-is-absolute": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "process-nextick-args": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "rc": {
+          "version": "1.2.8",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "deep-extend": "^0.6.0",
+            "ini": "~1.3.0",
+            "minimist": "^1.2.0",
+            "strip-json-comments": "~2.0.1"
           },
           "dependencies": {
-            "semver": {
-              "version": "5.7.1",
-              "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-              "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+            "minimist": {
+              "version": "1.2.0",
+              "bundled": true,
               "dev": true
             }
           }
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "rimraf": {
+          "version": "2.6.3",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "bundled": true,
+          "dev": true
+        },
+        "safer-buffer": {
+          "version": "2.1.2",
+          "bundled": true,
+          "dev": true
+        },
+        "sax": {
+          "version": "1.2.4",
+          "bundled": true,
+          "dev": true
+        },
+        "semver": {
+          "version": "5.6.0",
+          "bundled": true,
+          "dev": true
+        },
+        "set-blocking": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "signal-exit": {
+          "version": "3.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "code-point-at": "^1.0.0",
+            "is-fullwidth-code-point": "^1.0.0",
+            "strip-ansi": "^3.0.0"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^2.0.0"
+          }
+        },
+        "strip-json-comments": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "tar": {
+          "version": "4.4.8",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "chownr": "^1.1.1",
+            "fs-minipass": "^1.2.5",
+            "minipass": "^2.3.4",
+            "minizlib": "^1.1.1",
+            "mkdirp": "^0.5.0",
+            "safe-buffer": "^5.1.2",
+            "yallist": "^3.0.2"
+          }
+        },
+        "util-deprecate": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "wide-align": {
+          "version": "1.1.3",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "string-width": "^1.0.2 || 2"
+          }
+        },
+        "wrappy": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "yallist": {
+          "version": "3.0.3",
+          "bundled": true,
+          "dev": true
         }
       }
     },
@@ -4092,9 +4535,9 @@
       }
     },
     "tslib": {
-      "version": "1.13.0",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
-      "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
+      "version": "2.0.3",
+      "resolved": "https://registry.npm.taobao.org/tslib/download/tslib-2.0.3.tgz?cache=0&sync_timestamp=1602286724979&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-2.0.3.tgz",
+      "integrity": "sha1-jgdBrEX8DCJuWKF7/D5kubxsphw=",
       "dev": true
     },
     "tslint": {
@@ -4123,6 +4566,12 @@
           "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
           "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
           "dev": true
+        },
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npm.taobao.org/tslib/download/tslib-1.14.1.tgz?cache=0&sync_timestamp=1602286724979&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-1.14.1.tgz",
+          "integrity": "sha1-zy04vcNKE0vK8QkcQfZhni9nLQA=",
+          "dev": true
         }
       }
     },
@@ -4139,6 +4588,14 @@
       "dev": true,
       "requires": {
         "tslib": "^1.8.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npm.taobao.org/tslib/download/tslib-1.14.1.tgz?cache=0&sync_timestamp=1602286724979&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-1.14.1.tgz",
+          "integrity": "sha1-zy04vcNKE0vK8QkcQfZhni9nLQA=",
+          "dev": true
+        }
       }
     },
     "type-detect": {
diff --git a/package.json b/package.json
index 69656c5..094963e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "skywalking",
-  "version": "0.0.1",
+  "version": "0.1.0",
   "description": "The NodeJS agent for Apache SkyWalking",
   "main": "lib/index.js",
   "typings": "lib/index.d.ts",
@@ -11,11 +11,7 @@
     "lint": "tslint -p tsconfig.json",
     "test": "mocha -r ts-node/register 'tests/**/test.ts'",
     "format": "prettier --write \"src/**/*.ts\"",
-    "clean": "(rm -rf src/proto || true) && (rm -rf src/proto || true) && (rm -rf lib || true)",
-    "dev": "node node_modules/ts-node/dist/bin -r tsconfig-paths/register tests/dev.ts"
-  },
-  "publishConfig": {
-    "registry": "https://registry.npm.alibaba-inc.com"
+    "clean": "(rm -rf src/proto || true) && (rm -rf src/proto || true) && (rm -rf lib || true)"
   },
   "files": [
     "lib/**/*"
@@ -24,12 +20,14 @@
     "SkyWalking",
     "APM",
     "Dapper",
-    "Tracing"
+    "Tracing",
+    "Agent",
+    "Instrumentation"
   ],
   "author": "Apache SkyWalking Team",
   "license": "Apache 2.0",
   "bugs": {
-    "url": "http://github.com/apache/skywalking/issues",
+    "url": "https://github.com/apache/skywalking/issues",
     "email": "dev@skywalking.apache.org"
   },
   "devDependencies": {
@@ -41,7 +39,7 @@
     "@types/semver": "^7.2.0",
     "@types/uuid": "^8.0.0",
     "chai": "^4.2.0",
-    "grpc-tools": "^1.9.0",
+    "grpc-tools": "^1.8.0",
     "grpc_tools_node_protoc_ts": "^4.0.0",
     "mocha": "^8.0.1",
     "mongodb": "^3.5.9",
@@ -49,6 +47,7 @@
     "prettier": "^2.0.5",
     "ts-node": "^8.10.2",
     "tsconfig-paths": "^3.9.0",
+    "tslib": "^2.0.3",
     "tslint": "^6.1.2",
     "tslint-config-prettier": "^1.18.0",
     "typescript": "^3.9.5",
diff --git a/src/agent/protocol/grpc/SegmentObjectAdapter.ts b/src/agent/protocol/grpc/SegmentObjectAdapter.ts
index 0ffa8e8..2844763 100644
--- a/src/agent/protocol/grpc/SegmentObjectAdapter.ts
+++ b/src/agent/protocol/grpc/SegmentObjectAdapter.ts
@@ -28,46 +28,61 @@
 export default class SegmentObjectAdapter extends SegmentObject {
   constructor(segment: Segment) {
     super();
-    this.setService(config.serviceName)
-      .setServiceinstance(config.serviceInstance)
-      .setTraceid(segment.relatedTraces[0].toString())
-      .setTracesegmentid(segment.segmentId.toString())
-      .setSpansList(
-        segment.spans.map((span) =>
-          new SpanObject()
-            .setSpanid(span.id)
-            .setParentspanid(span.parentId)
-            .setStarttime(span.startTime)
-            .setEndtime(span.endTime)
-            .setOperationname(span.operation)
-            .setPeer(span.peer)
-            .setSpantype(span.type)
-            .setSpanlayer(span.layer)
-            .setComponentid(span.component.id)
-            .setIserror(span.errored)
-            .setLogsList(
-              span.logs.map((log) =>
-                new Log()
-                  .setTime(log.timestamp)
-                  .setDataList(
-                    log.items.map((logItem) => new KeyStringValuePair().setKey(logItem.key).setValue(logItem.val)),
-                  ),
-              ),
-            )
-            .setTagsList(span.tags.map((tag) => new KeyStringValuePair().setKey(tag.key).setValue(tag.val)))
-            .setRefsList(
-              span.refs.map((ref) =>
-                new SegmentReference()
-                  .setReftype(RefType.CROSSPROCESS)
-                  .setTraceid(ref.traceId.toString())
-                  .setParenttracesegmentid(ref.segmentId.toString())
-                  .setParentspanid(ref.spanId)
-                  .setParentservice(ref.service)
-                  .setParentserviceinstance(ref.serviceInstance)
-                  .setNetworkaddressusedatpeer(ref.clientAddress),
-              ),
-            ),
-        ),
-      );
+    this.setService(config.serviceName);
+    this.setServiceinstance(config.serviceInstance);
+    this.setTraceid(segment.relatedTraces[0].toString());
+    this.setTracesegmentid(segment.segmentId.toString());
+    this.setSpansList(
+      segment.spans.map((span) => {
+        const spanObj = new SpanObject();
+        spanObj.setSpanid(span.id);
+        spanObj.setParentspanid(span.parentId);
+        spanObj.setStarttime(span.startTime);
+        spanObj.setEndtime(span.endTime);
+        spanObj.setOperationname(span.operation);
+        spanObj.setPeer(span.peer);
+        spanObj.setSpantype(span.type);
+        spanObj.setSpanlayer(span.layer);
+        spanObj.setComponentid(span.component.id);
+        spanObj.setIserror(span.errored);
+        spanObj.setLogsList(
+          span.logs.map((log) => {
+            const l = new Log();
+            l.setTime(log.timestamp);
+            l.setDataList(
+              log.items.map((logItem) => {
+                const item = new KeyStringValuePair();
+                item.setKey(logItem.key);
+                item.setValue(logItem.val);
+                return item;
+              }),
+            );
+            return l;
+          }),
+        );
+        spanObj.setTagsList(
+          span.tags.map((tag) => {
+            const item = new KeyStringValuePair();
+            item.setKey(tag.key);
+            item.setValue(tag.val);
+            return item;
+          }),
+        );
+        spanObj.setRefsList(
+          span.refs.map((ref) => {
+            const segmentRef = new SegmentReference();
+            segmentRef.setReftype(RefType.CROSSPROCESS);
+            segmentRef.setTraceid(ref.traceId.toString());
+            segmentRef.setParenttracesegmentid(ref.segmentId.toString());
+            segmentRef.setParentspanid(ref.spanId);
+            segmentRef.setParentservice(ref.service);
+            segmentRef.setParentserviceinstance(ref.serviceInstance);
+            segmentRef.setNetworkaddressusedatpeer(ref.clientAddress);
+            return segmentRef;
+          }),
+        );
+        return spanObj;
+      }),
+    );
   }
 }
diff --git a/src/agent/protocol/grpc/clients/HeartbeatClient.ts b/src/agent/protocol/grpc/clients/HeartbeatClient.ts
index 3c51713..5bebc81 100644
--- a/src/agent/protocol/grpc/clients/HeartbeatClient.ts
+++ b/src/agent/protocol/grpc/clients/HeartbeatClient.ts
@@ -56,19 +56,39 @@
       return;
     }
 
-    const keepAlivePkg = new InstancePingPkg()
-      .setService(config.serviceName)
-      .setServiceinstance(config.serviceInstance);
+    const keepAlivePkg = new InstancePingPkg();
+    keepAlivePkg.setService(config.serviceName);
+    keepAlivePkg.setServiceinstance(config.serviceInstance);
 
-    const instanceProperties = new InstanceProperties()
-      .setService(config.serviceName)
-      .setServiceinstance(config.serviceInstance)
-      .setPropertiesList([
-        new KeyStringValuePair().setKey('language').setValue('NodeJS'),
-        new KeyStringValuePair().setKey('OS Name').setValue(os.platform()),
-        new KeyStringValuePair().setValue('hostname').setValue(os.hostname()),
-        new KeyStringValuePair().setValue('Process No.').setValue(`${process.pid}`),
-      ]);
+    const instanceProperties = new InstanceProperties();
+    instanceProperties.setService(config.serviceName);
+    instanceProperties.setServiceinstance(config.serviceInstance);
+    instanceProperties.setPropertiesList([
+      (() => {
+        const lang = new KeyStringValuePair();
+        lang.setKey('language');
+        lang.setValue('NodeJS');
+        return lang;
+      })(),
+      (() => {
+        const osName = new KeyStringValuePair();
+        osName.setKey('OS Name');
+        osName.setValue(os.platform());
+        return osName;
+      })(),
+      (() => {
+        const hostname = new KeyStringValuePair();
+        hostname.setValue('hostname');
+        hostname.setValue(os.hostname());
+        return hostname;
+      })(),
+      (() => {
+        const p = new KeyStringValuePair();
+        p.setValue('Process No.');
+        p.setValue(`${process.pid}`);
+        return p;
+      })(),
+    ]);
 
     this.heartbeatTimer = setInterval(() => {
       this.heartbeatClient.reportInstanceProperties(
diff --git a/src/plugins/HttpPlugin.ts b/src/plugins/HttpPlugin.ts
index a7caf18..56f8911 100644
--- a/src/plugins/HttpPlugin.ts
+++ b/src/plugins/HttpPlugin.ts
@@ -34,6 +34,9 @@
   readonly versions = '*';
 
   install(): void {
+    if (logger.isDebugEnabled()) {
+      logger.debug('installing http plugin');
+    }
     this.interceptClientRequest();
     this.interceptServerRequest();
   }
@@ -43,11 +46,7 @@
 
     ((original) => {
       http.request = function () {
-        const argc = arguments.length;
-
         const url: URL | string | RequestOptions = arguments[0];
-        const options = argc > 1 ? (typeof arguments[1] === 'function' ? {} : arguments[1]) : {};
-        const callback = typeof arguments[argc - 1] === 'function' ? arguments[argc - 1] : undefined;
 
         const { host, pathname } =
           url instanceof URL
@@ -65,32 +64,17 @@
         span.layer = SpanLayer.HTTP;
         span.tag(Tag.httpURL(host + pathname));
 
-        const snapshot = ContextManager.current.capture();
-
         const request: ClientRequest = original.apply(this, arguments);
 
         span.extract().items.forEach((item) => {
           request.setHeader(item.key, item.value);
         });
 
-        request.on('response', (res) => {
-          res.prependListener('end', () => {
-            span.tag(Tag.httpStatusCode(res.statusCode)).tag(Tag.httpStatusMsg(res.statusMessage));
+        span.async();
 
-            const callbackSpan = ContextManager.current.newLocalSpan('callback').start();
-            callbackSpan.layer = SpanLayer.HTTP;
-            callbackSpan.component = Component.HTTP;
-
-            ContextManager.current.restore(snapshot);
-
-            if (callback) {
-              callback(res);
-            }
-
-            callbackSpan.stop();
-          });
+        request.on('close', () => {
+          span.await().stop();
         });
-        span.stop();
 
         return request;
       };
@@ -106,26 +90,36 @@
           return original.apply(this, arguments);
         }
 
-        const [req, res] = [arguments[1] as IncomingMessage, arguments[2] as ServerResponse];
+        const args = arguments;
+        const self = this;
 
-        const headers = req.rawHeaders || [];
-        const headersMap: { [key: string]: string } = {};
+        return ContextManager.withContext(() => {
+          const [req, res] = [args[1] as IncomingMessage, args[2] as ServerResponse];
 
-        for (let i = 0; i < headers.length / 2; i += 2) {
-          headersMap[headers[i]] = headers[i + 1];
-        }
+          const headers = req.rawHeaders || [];
+          const headersMap: { [key: string]: string } = {};
 
-        const carrier = ContextCarrier.from(headersMap);
+          for (let i = 0; i < headers.length / 2; i += 2) {
+            headersMap[headers[i]] = headers[i + 1];
+          }
 
-        const span = ContextManager.current.newEntrySpan('/', carrier).start();
-        span.operation = (req.url || '/').replace(/\?.*/g, '');
-        span.component = Component.HTTP_SERVER;
-        span.layer = SpanLayer.HTTP;
-        span.tag(Tag.httpURL(req.url));
+          const carrier = ContextCarrier.from(headersMap);
 
-        span.tag(Tag.httpStatusCode(res.statusCode)).tag(Tag.httpStatusMsg(res.statusMessage)).stop();
+          const span = ContextManager.current.newEntrySpan('/', carrier).start();
+          span.operation = (req.url || '/').replace(/\?.*/g, '');
+          span.component = Component.HTTP_SERVER;
+          span.layer = SpanLayer.HTTP;
+          span.tag(Tag.httpURL(req.url));
 
-        return original.apply(this, arguments);
+          span.tag(Tag.httpStatusCode(res.statusCode)).tag(Tag.httpStatusMsg(res.statusMessage));
+
+          res.on('close', () => {
+            console.info('jjj');
+            span.stop();
+          });
+
+          return original.apply(self, args);
+        });
       };
     })(http.Server.prototype.emit);
   }
diff --git a/src/trace/context/Context.ts b/src/trace/context/Context.ts
index 7393887..984033d 100644
--- a/src/trace/context/Context.ts
+++ b/src/trace/context/Context.ts
@@ -41,4 +41,8 @@
   capture(): Snapshot;
 
   restore(snapshot: Snapshot): void;
+
+  async(span: Span): void;
+
+  await(span: Span): void;
 }
diff --git a/src/trace/context/ContextCarrier.ts b/src/trace/context/ContextCarrier.ts
index c8f046f..8d94053 100644
--- a/src/trace/context/ContextCarrier.ts
+++ b/src/trace/context/ContextCarrier.ts
@@ -46,13 +46,13 @@
   get value(): string {
     return [
       '1',
-      this.encode(this.traceId!.toString()),
-      this.encode(this.segmentId!.toString()),
-      this.spanId!.toString(),
-      this.encode(this.service!),
-      this.encode(this.serviceInstance!),
-      this.encode(this.endpoint!),
-      this.encode(this.clientAddress!),
+      this.encode(this.traceId?.toString() || ''),
+      this.encode(this.segmentId?.toString() || ''),
+      this.spanId?.toString(),
+      this.encode(this.service || ''),
+      this.encode(this.serviceInstance || ''),
+      this.encode(this.endpoint || ''),
+      this.encode(this.clientAddress || ''),
     ].join('-');
   }
 
diff --git a/src/trace/context/ContextManager.ts b/src/trace/context/ContextManager.ts
index e49bbb0..538a6d1 100644
--- a/src/trace/context/ContextManager.ts
+++ b/src/trace/context/ContextManager.ts
@@ -19,25 +19,17 @@
 
 import Context from '../../trace/context/Context';
 import SpanContext from '../../trace/context/SpanContext';
-import { executionAsyncId, createHook } from 'async_hooks';
+import { AsyncLocalStorage } from 'async_hooks';
+
+const store = new AsyncLocalStorage<Context>();
 
 class ContextManager {
-  contextKeyedByAsyncId: { [asyncId: number]: Context } = {};
-
-  constructor() {
-    createHook({
-      destroy: (asyncId: number) => {
-        delete this.contextKeyedByAsyncId[asyncId];
-      },
-    }).enable();
+  get current(): Context {
+    return store.getStore() || new SpanContext();
   }
 
-  get current(): Context {
-    const thisAsyncId = executionAsyncId();
-
-    this.contextKeyedByAsyncId[thisAsyncId] = this.contextKeyedByAsyncId[thisAsyncId] || new SpanContext(thisAsyncId);
-
-    return this.contextKeyedByAsyncId[thisAsyncId];
+  withContext(callback: (...args: any[]) => void, ...args: any[]) {
+    return store.run(new SpanContext(), callback);
   }
 }
 
diff --git a/src/trace/context/DummyContext.ts b/src/trace/context/DummyContext.ts
index 54a98e8..e7fc720 100644
--- a/src/trace/context/DummyContext.ts
+++ b/src/trace/context/DummyContext.ts
@@ -73,6 +73,14 @@
   }
 
   restore(snapshot: Snapshot) {
-    // Big Bang ~
+    return;
+  }
+
+  async(span: Span) {
+    return;
+  }
+
+  await(span: Span) {
+    return;
   }
 }
diff --git a/src/trace/context/Segment.ts b/src/trace/context/Segment.ts
index 8d9346c..9c8a7fd 100644
--- a/src/trace/context/Segment.ts
+++ b/src/trace/context/Segment.ts
@@ -25,7 +25,6 @@
 export default class Segment {
   segmentId = new ID();
   spans: Span[] = [];
-  timestamp: number = 0;
   relatedTraces: ID[] = [new NewID()];
   references: SegmentRef[] = [];
 
diff --git a/src/trace/context/SpanContext.ts b/src/trace/context/SpanContext.ts
index d7c53b0..b4e4d3c 100644
--- a/src/trace/context/SpanContext.ts
+++ b/src/trace/context/SpanContext.ts
@@ -23,7 +23,6 @@
 import EntrySpan from '../../trace/span/EntrySpan';
 import ExitSpan from '../../trace/span/ExitSpan';
 import LocalSpan from '../../trace/span/LocalSpan';
-import * as packageInfo from '../../../package.json';
 import buffer from '../../agent/Buffer';
 import { createLogger } from '../../logging';
 import { executionAsyncId } from 'async_hooks';
@@ -37,8 +36,7 @@
   spanId = 0;
   spans: Span[] = [];
   segment: Segment = new Segment();
-
-  constructor(public asyncId: number) {}
+  asyncCount: number = 0;
 
   get parent(): Span | null {
     if (this.spans.length > 0) {
@@ -117,20 +115,15 @@
   stop(span: Span): boolean {
     logger.info('Stopping span', { span, spans: this.spans });
 
-    if (this.spans[this.spans.length - 1] !== span) {
-      logger.error(`Stopping unexpected span. Consider report this to ${packageInfo.bugs.url}`);
-      return true;
-    }
-
     if (this.tryFinish(span)) {
-      this.spans.splice(0, 1);
+      this.spans.splice(this.spans.length - 1, 1);
     }
 
-    return this.spans.length === 0;
+    return this.asyncCount === 0 && this.spans.length === 0;
   }
 
   tryFinish(span: Span): boolean {
-    if (span.finish(this.segment)) {
+    if (span.finish(this.segment) && !span.isAsync) {
       if (logger.isDebugEnabled()) {
         logger.debug('Finishing span', { span });
       }
@@ -159,4 +152,13 @@
     this.currentSpan()?.refer(ref);
     this.segment.relate(ref.traceId);
   }
+
+  async(span: Span) {
+    this.asyncCount++;
+    this.spans.splice(this.spans.indexOf(span), 1);
+  }
+
+  await(span: Span) {
+    this.asyncCount--;
+  }
 }
diff --git a/src/trace/span/Span.ts b/src/trace/span/Span.ts
index decfcf3..1ad868e 100644
--- a/src/trace/span/Span.ts
+++ b/src/trace/span/Span.ts
@@ -59,6 +59,8 @@
   endTime = 0;
   errored = false;
 
+  _async = false;
+
   constructor(options: SpanCtorOptions & { type: SpanType }) {
     this.context = options.context;
     this.operation = options.operation;
@@ -94,7 +96,7 @@
   // noinspection JSUnusedLocalSymbols
   extract(): ContextCarrier {
     throw new Error(`
-      can only inject context carrier into ExitSpan, this may be a potential bug in the agent,
+      can only extract context carrier into ExitSpan, this may be a potential bug in the agent,
       please report this in ${packageInfo.bugs.url} if you encounter this.
     `);
   }
@@ -141,4 +143,20 @@
     }
     return this;
   }
+
+  async(): this {
+    this._async = true;
+    this.context.async(this);
+    return this;
+  }
+
+  await(): this {
+    this._async = false;
+    this.context.await(this);
+    return this;
+  }
+
+  get isAsync(): boolean {
+    return this._async;
+  }
 }
diff --git a/tests/plugins/common/Dockerfile.agent b/tests/plugins/common/Dockerfile.agent
index 0722c25..b81f372 100644
--- a/tests/plugins/common/Dockerfile.agent
+++ b/tests/plugins/common/Dockerfile.agent
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-FROM nodejs-dependencies
+FROM node:12
 
 ARG ROOT=.
 
@@ -21,4 +21,5 @@
 
 ADD $ROOT /app
 
-RUN cp -R /dependencies/node_modules /app/
+RUN npm install
+
diff --git a/tests/plugins/http/client.ts b/tests/plugins/http/client.ts
new file mode 100644
index 0000000..bc01846
--- /dev/null
+++ b/tests/plugins/http/client.ts
@@ -0,0 +1,38 @@
+/*!
+ *
+ * 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.
+ *
+ */
+
+import * as http from 'http';
+import Agent from '../../../src';
+
+Agent.start({
+  serviceName: 'client',
+  maxBufferSize: 1000,
+});
+
+http
+  .request('http://localhost:5000', (res) => {
+    let data = '';
+    res.on('data', (chunk) => (data += chunk));
+    res.on('end', () => console.info(data));
+  })
+  .end();
+
+setTimeout(() => {
+  console.info();
+}, 3000);
diff --git a/tests/plugins/http/server.ts b/tests/plugins/http/server.ts
new file mode 100644
index 0000000..2885c56
--- /dev/null
+++ b/tests/plugins/http/server.ts
@@ -0,0 +1,46 @@
+/*!
+ *
+ * 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.
+ *
+ */
+
+import Agent from '../../../src';
+import * as http from 'http';
+
+Agent.start({
+  serviceName: 'server',
+  maxBufferSize: 1000,
+});
+
+const server = http.createServer((req, res) => {
+  http
+    .request('http://httpbin.org/json', (r) => {
+      let data = '';
+      r.on('data', (chunk) => (data += chunk));
+      r.on('end', () => setImmediate(() => res.write(data)));
+    })
+    .end();
+
+  http
+    .request('http://httpbin.org/xml', async (r) => {
+      let data = '';
+      r.on('data', (chunk) => (data += chunk));
+      r.on('end', () => setTimeout(() => res.end(data), 1000));
+    })
+    .end();
+});
+
+server.listen(5000, () => console.info('Listening on port 5000...'));
diff --git a/tests/plugins/http/test.ts b/tests/plugins/http/test.ts
index 00e44ce..3e9770e 100644
--- a/tests/plugins/http/test.ts
+++ b/tests/plugins/http/test.ts
@@ -25,7 +25,7 @@
 
 describe('', () => {
   before(function () {
-    this.timeout(10_000);
+    this.timeout(60_000);
 
     return setUp(composeFile, () => true);
   });
@@ -37,7 +37,7 @@
   });
 
   it(`test ${__dirname}`, function (done) {
-    this.timeout(10_000);
+    this.timeout(60_000);
 
     done();
   });
diff --git a/tests/tsconfig.json b/tests/tsconfig.json
new file mode 100644
index 0000000..e73078b
--- /dev/null
+++ b/tests/tsconfig.json
@@ -0,0 +1,18 @@
+{
+  "compilerOptions": {
+    "target": "es5",
+    "module": "commonjs",
+    "strict": true,
+    "importHelpers": true,
+    "moduleResolution": "node",
+    "experimentalDecorators": true,
+    "esModuleInterop": true,
+    "allowSyntheticDefaultImports": true,
+    "rootDir": "..",
+    "baseUrl": "..",
+    "resolveJsonModule": true,
+    "declaration": true,
+    "allowJs": true,
+    "sourceMap": true
+  }
+}
diff --git a/tsconfig.json b/tsconfig.json
index 0afd6e6..f6ebc11 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -5,9 +5,14 @@
     "baseUrl": ".",
     "outDir": ".",
     "resolveJsonModule": true,
-    "composite": true
+    "composite": true,
+    "esModuleInterop": true
   },
   "files": [
     "package.json"
+  ],
+  "include": [
+    "src/**/*",
+    "tests/**/*"
   ]
 }