You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ke...@apache.org on 2020/12/19 15:46:48 UTC
[skywalking-nodejs] branch master updated: Finalize 0.1.0 (#13)
This is an automated email from the ASF dual-hosted git repository.
kezhenxu94 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-nodejs.git
The following commit(s) were added to refs/heads/master by this push:
new dcf0a73 Finalize 0.1.0 (#13)
dcf0a73 is described below
commit dcf0a733d48d8b0cf936c73d9639ad4c4e1a6948
Author: Zhenxu Ke <ke...@apache.org>
AuthorDate: Sat Dec 19 23:46:41 2020 +0800
Finalize 0.1.0 (#13)
- Complete missing plugin tests.
- Fix bug of `startTime` and `endTime`.
- Fix bug that some env vars not work.
---
.../common/Dockerfile.agent => .editorconfig | 22 +-
README.md | 14 +-
dist/LICENSE | 256 ++++++++++
dist/NOTICE | 5 +
dist/licenses/LICENSE-on-finished.txt | 23 +
dist/licenses/LICENSE-protobuf-js.txt | 32 ++
dist/licenses/LICENSE-semver.txt | 15 +
dist/licenses/LICENSE-tslib.txt | 12 +
dist/licenses/LICENSE-uuid.txt | 21 +
dist/licenses/LICENSE-winston.txt | 19 +
package-lock.json | 524 ++++++++++++++++++++-
package.json | 7 +-
src/agent/Buffer.ts | 31 +-
src/agent/protocol/Protocol.ts | 4 +-
src/agent/protocol/grpc/GrpcProtocol.ts | 20 +-
src/agent/protocol/grpc/clients/HeartbeatClient.ts | 24 +-
.../protocol/grpc/clients/TraceReportClient.ts | 42 +-
src/core/PluginInstaller.ts | 59 ++-
src/index.ts | 9 +-
.../protocol/Protocol.ts => lib/EventEmitter.ts} | 17 +-
src/plugins/AxiosPlugin.ts | 18 +-
src/plugins/ExpressPlugin.ts | 28 +-
src/plugins/HttpPlugin.ts | 96 ++--
src/trace/Component.ts | 13 +-
src/trace/context/ContextManager.ts | 57 ++-
src/trace/context/SpanContext.ts | 28 +-
src/trace/span/EntrySpan.ts | 4 +-
src/trace/span/StackedSpan.ts | 4 -
tests/plugins/{http => axios}/client.ts | 16 +-
tests/plugins/{http => axios}/docker-compose.yml | 10 +-
tests/plugins/{http => axios}/expected.data.yaml | 99 ++--
tests/plugins/{http => axios}/server.ts | 16 +-
tests/plugins/{http => axios}/test.ts | 6 +-
tests/plugins/common/Dockerfile.agent | 1 -
tests/plugins/common/base-compose.yml | 1 -
tests/plugins/{http => express}/client.ts | 23 +-
tests/plugins/{http => express}/docker-compose.yml | 10 +-
tests/plugins/{http => express}/expected.data.yaml | 97 ++--
tests/plugins/{http => express}/server.ts | 23 +-
tests/plugins/{http => express}/test.ts | 6 +-
tests/plugins/http/client.ts | 16 +-
tests/plugins/http/docker-compose.yml | 2 -
tests/plugins/http/expected.data.yaml | 87 ++--
tests/plugins/http/server.ts | 16 +-
tests/plugins/http/test.ts | 4 +-
45 files changed, 1410 insertions(+), 427 deletions(-)
diff --git a/tests/plugins/common/Dockerfile.agent b/.editorconfig
similarity index 82%
copy from tests/plugins/common/Dockerfile.agent
copy to .editorconfig
index 4c51529..9e8ec25 100644
--- a/tests/plugins/common/Dockerfile.agent
+++ b/.editorconfig
@@ -1,3 +1,4 @@
+#
# 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.
@@ -12,16 +13,15 @@
# 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.
+#
-ARG SW_NODE_VERSION
-
-FROM node:${SW_NODE_VERSION}
-
-ARG ROOT=.
-
-WORKDIR /app
-
-ADD $ROOT /app
-
-RUN npm install request && npm install
+root = true
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+quote_type = single
diff --git a/README.md b/README.md
index dfb635f..d2eab71 100644
--- a/README.md
+++ b/README.md
@@ -15,12 +15,12 @@ microservices, cloud native and container-based (Docker, Kubernetes, Mesos) arch
## Set up NodeJS Agent
-SkyWalking NodeJS SDK requires SkyWalking 8.0+.
+SkyWalking NodeJS SDK requires SkyWalking backend (OAP) 8.0+ and NodeJS >= 10.
```typescript
-import Agent from 'skywalking';
+import agent from 'skywalking';
-Agent.start({
+agent.start({
serviceName: '',
serviceInstance: '',
collectorAddress: '',
@@ -38,15 +38,19 @@ Environment Variable | Description | Default
| `SW_AGENT_COLLECTOR_BACKEND_SERVICES` | The backend OAP server address | `127.0.0.1:11800` |
| `SW_AGENT_AUTHENTICATION` | The authentication token to verify that the agent is trusted by the backend OAP, as for how to configure the backend, refer to [the yaml](https://github.com/apache/skywalking/blob/4f0f39ffccdc9b41049903cc540b8904f7c9728e/oap-server/server-bootstrap/src/main/resources/application.yml#L155-L158). | not set |
| `SW_AGENT_LOGGING_LEVEL` | The logging level, could be one of `CRITICAL`, `FATAL`, `ERROR`, `WARN`(`WARNING`), `INFO`, `DEBUG` | `INFO` |
+| `SW_IGNORE_SUFFIX` | The suffices of endpoints that will be ignored (not traced), comma separated | `.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg` |
+| `SW_TRACE_IGNORE_PATH` | The paths of endpoints that will be ignored (not traced), comma separated | `` |
| `SW_AGENT_MAX_BUFFER_SIZE` | The maximum buffer size before sending the segment data to backend | `'1000'` |
## Supported Libraries
-There're some built-in plugins that support automatic instrumentation of NodeJS libraries, the complete lists are as follows:
+There are some built-in plugins that support automatic instrumentation of NodeJS libraries, the complete lists are as follows:
Library | Plugin Name
| :--- | :--- |
-| built-in `http` module | `sw_http` |
+| built-in `http` and `https` module | `http` |
+| [`express`](https://expressjs.com) | `express` |
+| [`axios`](https://github.com/axios/axios) | `axios` |
## License
Apache 2.0
diff --git a/dist/LICENSE b/dist/LICENSE
new file mode 100755
index 0000000..c103232
--- /dev/null
+++ b/dist/LICENSE
@@ -0,0 +1,256 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ Licensed 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.
+
+=======================================================================
+Apache SkyWalking NodeJS Agent Subcomponents:
+
+The Apache SkyWalking NodeJS Agent project contains subcomponents with separate copyright
+notices and license terms. Your use of the source code for the these
+subcomponents is subject to the terms and conditions of the following
+licenses.
+
+========================================================================
+Apache 2.0 licenses
+========================================================================
+
+The following components are provided under the Apache License. See project link for details.
+The text of each license is the standard Apache 2.0 license.
+
+ grpc-node 1.10.1: https://github.com/grpc/grpc-node, Apache 2.0
+
+========================================================================
+BSD licenses
+========================================================================
+
+The following components are provided under a BSD license. See project link for details.
+The text of each license is also included at licenses/LICENSE-[project].txt.
+
+ protobuf-js 3.14.0: https://github.com/protocolbuffers/protobuf/tree/master/js, BSD-3-Clause
+
+========================================================================
+0BSD licenses
+========================================================================
+
+The following components are provided under a BSD license. See project link for details.
+The text of each license is also included at licenses/LICENSE-[project].txt.
+
+ tslib 2.0.3: https://www.typescriptlang.org/, 0BSD
+
+========================================================================
+MIT licenses
+========================================================================
+
+The following components are provided under the MIT License. See project link for details.
+The text of each license is also included at licenses/LICENSE-[project].txt.
+
+ on-finished 2.3.0: https://github.com/jshttp/on-finished, MIT
+ uuid 8.1.0: https://github.com/uuidjs/uuid, MIT
+ winston 3.2.1: https://github.com/winstonjs/winston, MIT
+
+========================================================================
+ISC licenses
+========================================================================
+
+The following components are provided under the ISC License. See project link for details.
+The text of each license is also included at licenses/LICENSE-[project].txt.
+
+ semver 7.3.2: https://github.com/npm/node-semver, ISC
diff --git a/dist/NOTICE b/dist/NOTICE
new file mode 100755
index 0000000..e646f51
--- /dev/null
+++ b/dist/NOTICE
@@ -0,0 +1,5 @@
+Apache SkyWalking
+Copyright 2017-2020 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/dist/licenses/LICENSE-on-finished.txt b/dist/licenses/LICENSE-on-finished.txt
new file mode 100644
index 0000000..5931fd2
--- /dev/null
+++ b/dist/licenses/LICENSE-on-finished.txt
@@ -0,0 +1,23 @@
+(The MIT License)
+
+Copyright (c) 2013 Jonathan Ong <me...@jongleberry.com>
+Copyright (c) 2014 Douglas Christopher Wilson <do...@somethingdoug.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/dist/licenses/LICENSE-protobuf-js.txt b/dist/licenses/LICENSE-protobuf-js.txt
new file mode 100644
index 0000000..19b305b
--- /dev/null
+++ b/dist/licenses/LICENSE-protobuf-js.txt
@@ -0,0 +1,32 @@
+Copyright 2008 Google Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Code generated by the Protocol Buffer compiler is owned by the owner
+of the input file used when generating it. This code is not
+standalone and requires a support library to be linked with it. This
+support library is itself covered by the above license.
diff --git a/dist/licenses/LICENSE-semver.txt b/dist/licenses/LICENSE-semver.txt
new file mode 100644
index 0000000..19129e3
--- /dev/null
+++ b/dist/licenses/LICENSE-semver.txt
@@ -0,0 +1,15 @@
+The ISC License
+
+Copyright (c) Isaac Z. Schlueter and Contributors
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/dist/licenses/LICENSE-tslib.txt b/dist/licenses/LICENSE-tslib.txt
new file mode 100644
index 0000000..b72046c
--- /dev/null
+++ b/dist/licenses/LICENSE-tslib.txt
@@ -0,0 +1,12 @@
+Copyright (c) Microsoft Corporation.
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
diff --git a/dist/licenses/LICENSE-uuid.txt b/dist/licenses/LICENSE-uuid.txt
new file mode 100644
index 0000000..f8969d3
--- /dev/null
+++ b/dist/licenses/LICENSE-uuid.txt
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2010-2020 Robert Kieffer and other contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/dist/licenses/LICENSE-winston.txt b/dist/licenses/LICENSE-winston.txt
new file mode 100644
index 0000000..15fbbb5
--- /dev/null
+++ b/dist/licenses/LICENSE-winston.txt
@@ -0,0 +1,19 @@
+Copyright (c) 2010 Charlie Robbins
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/package-lock.json b/package-lock.json
index dbc294d..451b25a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1045,6 +1045,16 @@
"@babel/types": "^7.3.0"
}
},
+ "@types/body-parser": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npm.taobao.org/@types/body-parser/download/@types/body-parser-1.19.0.tgz?cache=0&sync_timestamp=1605052521338&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fbody-parser%2Fdownload%2F%40types%2Fbody-parser-1.19.0.tgz",
+ "integrity": "sha1-BoWzxH6zAG/+0RfN1VFkth+AU48=",
+ "dev": true,
+ "requires": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
"@types/bytebuffer": {
"version": "5.0.41",
"resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.41.tgz",
@@ -1060,6 +1070,15 @@
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
"dev": true
},
+ "@types/connect": {
+ "version": "3.4.34",
+ "resolved": "https://registry.npm.taobao.org/@types/connect/download/@types/connect-3.4.34.tgz?cache=0&sync_timestamp=1607458722751&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fconnect%2Fdownload%2F%40types%2Fconnect-3.4.34.tgz",
+ "integrity": "sha1-FwpAIjptZmAG2TyhKK8r6x2bGQE=",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
"@types/dockerode": {
"version": "2.5.34",
"resolved": "https://registry.npm.taobao.org/@types/dockerode/download/@types/dockerode-2.5.34.tgz",
@@ -1069,6 +1088,29 @@
"@types/node": "*"
}
},
+ "@types/express": {
+ "version": "4.17.9",
+ "resolved": "https://registry.npm.taobao.org/@types/express/download/@types/express-4.17.9.tgz?cache=0&sync_timestamp=1605057477768&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fexpress%2Fdownload%2F%40types%2Fexpress-4.17.9.tgz",
+ "integrity": "sha1-9fLfat1wP/KEKK3VK97IoQkbCng=",
+ "dev": true,
+ "requires": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "*",
+ "@types/qs": "*",
+ "@types/serve-static": "*"
+ }
+ },
+ "@types/express-serve-static-core": {
+ "version": "4.17.17",
+ "resolved": "https://registry.npm.taobao.org/@types/express-serve-static-core/download/@types/express-serve-static-core-4.17.17.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fexpress-serve-static-core%2Fdownload%2F%40types%2Fexpress-serve-static-core-4.17.17.tgz",
+ "integrity": "sha1-a6AkZRZbbJw9jbOije9rFvybcPU=",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*"
+ }
+ },
"@types/google-protobuf": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/@types/google-protobuf/-/google-protobuf-3.7.2.tgz",
@@ -1129,6 +1171,12 @@
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz",
"integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
},
+ "@types/mime": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npm.taobao.org/@types/mime/download/@types/mime-2.0.3.tgz",
+ "integrity": "sha1-yJO3NyHbc2mZQ7/DZTsd63+qSjo=",
+ "dev": true
+ },
"@types/node": {
"version": "14.0.13",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.13.tgz",
@@ -1140,12 +1188,33 @@
"integrity": "sha1-5IbQ2XOW15vu3QpuM/RTT/a0lz4=",
"dev": true
},
+ "@types/on-finished": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/@types/on-finished/-/on-finished-2.3.1.tgz",
+ "integrity": "sha512-mzVYaYcFs5Jd2n/O6uYIRUsFRR1cHyZLRvkLCU0E7+G5WhY0qBDAR5fUCeZbvecYOSh9ikhlesyi2UfI8B9ckQ==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
"@types/prettier": {
"version": "2.1.5",
"resolved": "https://registry.npm.taobao.org/@types/prettier/download/@types/prettier-2.1.5.tgz",
"integrity": "sha1-tqs7uinha4IdhOCez63tRiuBawA=",
"dev": true
},
+ "@types/qs": {
+ "version": "6.9.5",
+ "resolved": "https://registry.npm.taobao.org/@types/qs/download/@types/qs-6.9.5.tgz?cache=0&sync_timestamp=1605055106687&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fqs%2Fdownload%2F%40types%2Fqs-6.9.5.tgz",
+ "integrity": "sha1-Q0cRvdSete5p2QwdZ8NUqajssYs=",
+ "dev": true
+ },
+ "@types/range-parser": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npm.taobao.org/@types/range-parser/download/@types/range-parser-1.2.3.tgz?cache=0&sync_timestamp=1605055243791&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Frange-parser%2Fdownload%2F%40types%2Frange-parser-1.2.3.tgz",
+ "integrity": "sha1-fuMwunyq+5gJC+zoal7kQRWQTCw=",
+ "dev": true
+ },
"@types/semver": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.2.0.tgz",
@@ -1155,6 +1224,16 @@
"@types/node": "*"
}
},
+ "@types/serve-static": {
+ "version": "1.13.8",
+ "resolved": "https://registry.npm.taobao.org/@types/serve-static/download/@types/serve-static-1.13.8.tgz?cache=0&sync_timestamp=1605657655340&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fserve-static%2Fdownload%2F%40types%2Fserve-static-1.13.8.tgz",
+ "integrity": "sha1-hREp1DRDPHCCFIV0/+wmPVgwnEY=",
+ "dev": true,
+ "requires": {
+ "@types/mime": "*",
+ "@types/node": "*"
+ }
+ },
"@types/ssh2": {
"version": "0.5.45",
"resolved": "https://registry.npm.taobao.org/@types/ssh2/download/@types/ssh2-0.5.45.tgz?cache=0&sync_timestamp=1605057226497&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fssh2%2Fdownload%2F%40types%2Fssh2-0.5.45.tgz",
@@ -1212,6 +1291,16 @@
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
},
+ "accepts": {
+ "version": "1.3.7",
+ "resolved": "https://registry.npm.taobao.org/accepts/download/accepts-1.3.7.tgz",
+ "integrity": "sha1-UxvHJlF6OytB+FACHGzBXqq1B80=",
+ "dev": true,
+ "requires": {
+ "mime-types": "~2.1.24",
+ "negotiator": "0.6.2"
+ }
+ },
"acorn": {
"version": "7.4.1",
"resolved": "https://registry.npm.taobao.org/acorn/download/acorn-7.4.1.tgz",
@@ -1604,6 +1693,12 @@
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
"dev": true
},
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npm.taobao.org/array-flatten/download/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
+ "dev": true
+ },
"array-sort": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/array-sort/-/array-sort-0.1.4.tgz",
@@ -1842,6 +1937,47 @@
"tweetnacl": "^0.14.3"
}
},
+ "body-parser": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npm.taobao.org/body-parser/download/body-parser-1.19.0.tgz",
+ "integrity": "sha1-lrJwnlfJxOCab9Zqj9l5hE9p8Io=",
+ "dev": true,
+ "requires": {
+ "bytes": "3.1.0",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "on-finished": "~2.3.0",
+ "qs": "6.7.0",
+ "raw-body": "2.4.0",
+ "type-is": "~1.6.17"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566551397&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
+ "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433856030&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz",
+ "integrity": "sha1-QdwaAV49WB8WIXdr4xr7KHapsbw=",
+ "dev": true
+ }
+ }
+ },
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -1929,6 +2065,12 @@
"long": "~3"
}
},
+ "bytes": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npm.taobao.org/bytes/download/bytes-3.1.0.tgz",
+ "integrity": "sha1-9s95M6Ng4FiPqf3oVlHNx/gF0fY=",
+ "dev": true
+ },
"cache-base": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
@@ -2203,6 +2345,21 @@
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
},
+ "content-disposition": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npm.taobao.org/content-disposition/download/content-disposition-0.5.3.tgz",
+ "integrity": "sha1-4TDK9+cnkIfFYWwgB9BIVpiYT70=",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.2"
+ }
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npm.taobao.org/content-type/download/content-type-1.0.4.tgz",
+ "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=",
+ "dev": true
+ },
"convert-source-map": {
"version": "1.7.0",
"resolved": "https://registry.npm.taobao.org/convert-source-map/download/convert-source-map-1.7.0.tgz",
@@ -2212,6 +2369,18 @@
"safe-buffer": "~5.1.1"
}
},
+ "cookie": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npm.taobao.org/cookie/download/cookie-0.4.0.tgz",
+ "integrity": "sha1-vrQ35wIrO21JAZ0IhmUwPr6cFLo=",
+ "dev": true
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npm.taobao.org/cookie-signature/download/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
+ "dev": true
+ },
"copy-descriptor": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
@@ -2455,6 +2624,18 @@
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
},
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npm.taobao.org/depd/download/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+ "dev": true
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npm.taobao.org/destroy/download/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+ "dev": true
+ },
"detect-libc": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
@@ -2579,6 +2760,11 @@
"safer-buffer": "^2.1.0"
}
},
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
"emittery": {
"version": "0.7.2",
"resolved": "https://registry.npm.taobao.org/emittery/download/emittery-0.7.2.tgz",
@@ -2599,6 +2785,12 @@
"env-variable": "0.0.x"
}
},
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npm.taobao.org/encodeurl/download/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+ "dev": true
+ },
"end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npm.taobao.org/end-of-stream/download/end-of-stream-1.4.4.tgz",
@@ -2642,6 +2834,12 @@
"integrity": "sha1-Ck2uN9YA0VopukU9jvkg8YRDM/Y=",
"dev": true
},
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npm.taobao.org/escape-html/download/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+ "dev": true
+ },
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
@@ -2679,6 +2877,12 @@
"integrity": "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q=",
"dev": true
},
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npm.taobao.org/etag/download/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+ "dev": true
+ },
"exec-sh": {
"version": "0.3.4",
"resolved": "https://registry.npm.taobao.org/exec-sh/download/exec-sh-0.3.4.tgz",
@@ -2761,6 +2965,67 @@
"jest-regex-util": "^26.0.0"
}
},
+ "express": {
+ "version": "4.17.1",
+ "resolved": "https://registry.npm.taobao.org/express/download/express-4.17.1.tgz",
+ "integrity": "sha1-RJH8OGBc9R+GKdOcK10Cb5ikwTQ=",
+ "dev": true,
+ "requires": {
+ "accepts": "~1.3.7",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.19.0",
+ "content-disposition": "0.5.3",
+ "content-type": "~1.0.4",
+ "cookie": "0.4.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "~1.1.2",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.5",
+ "qs": "6.7.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.1.2",
+ "send": "0.17.1",
+ "serve-static": "1.14.1",
+ "setprototypeof": "1.1.1",
+ "statuses": "~1.5.0",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566551397&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
+ "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433856030&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz",
+ "integrity": "sha1-QdwaAV49WB8WIXdr4xr7KHapsbw=",
+ "dev": true
+ }
+ }
+ },
"extend": {
"version": "3.0.2",
"resolved": "https://registry.npm.taobao.org/extend/download/extend-3.0.2.tgz",
@@ -2884,6 +3149,38 @@
}
}
},
+ "finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npm.taobao.org/finalhandler/download/finalhandler-1.1.2.tgz",
+ "integrity": "sha1-t+fQAP/RGTjQ/bBTUG9uur6fWH0=",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566551397&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
+ "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433856030&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
"find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
@@ -2932,6 +3229,12 @@
"mime-types": "^2.1.12"
}
},
+ "forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npm.taobao.org/forwarded/download/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+ "dev": true
+ },
"fragment-cache": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@@ -2941,6 +3244,12 @@
"map-cache": "^0.2.2"
}
},
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npm.taobao.org/fresh/download/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+ "dev": true
+ },
"fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npm.taobao.org/fs-constants/download/fs-constants-1.0.0.tgz",
@@ -3098,9 +3407,9 @@
"dev": true
},
"google-protobuf": {
- "version": "3.12.2",
- "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.12.2.tgz",
- "integrity": "sha512-4CZhpuRr1d6HjlyrxoXoocoGFnRYgKULgMtikMddA9ztRyYR59Aondv2FioyxWVamRo0rF2XpYawkTCBEQOSkA=="
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.14.0.tgz",
+ "integrity": "sha512-bwa8dBuMpOxg7COyqkW6muQuvNnWgVN8TX/epDRGW5m0jcrmq2QJyCyiV8ZE2/6LaIIqJtiv9bYokFhfpy/o6w=="
},
"graceful-fs": {
"version": "4.2.4",
@@ -3489,6 +3798,27 @@
"kind-of": "^6.0.0"
}
},
+ "http-errors": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.2.tgz?cache=0&sync_timestamp=1593407611415&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-errors%2Fdownload%2Fhttp-errors-1.7.2.tgz",
+ "integrity": "sha1-T1ApzxMjnzEDblsuVSkrz7zIXI8=",
+ "dev": true,
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.1",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.0"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+ "dev": true
+ }
+ }
+ },
"http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npm.taobao.org/http-signature/download/http-signature-1.2.0.tgz?cache=0&sync_timestamp=1600868532049&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-signature%2Fdownload%2Fhttp-signature-1.2.0.tgz",
@@ -3580,6 +3910,12 @@
"integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
"dev": true
},
+ "ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npm.taobao.org/ipaddr.js/download/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha1-v/OFQ+64mEglB5/zoqjmy9RngbM=",
+ "dev": true
+ },
"is-accessor-descriptor": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
@@ -5489,12 +5825,30 @@
"object-visit": "^1.0.0"
}
},
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npm.taobao.org/media-typer/download/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+ "dev": true
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npm.taobao.org/merge-descriptors/download/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
+ "dev": true
+ },
"merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npm.taobao.org/merge-stream/download/merge-stream-2.0.0.tgz",
"integrity": "sha1-UoI2KaFN0AyXcPtq1H3GMQ8sH2A=",
"dev": true
},
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npm.taobao.org/methods/download/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+ "dev": true
+ },
"micromatch": {
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
@@ -5576,6 +5930,12 @@
}
}
},
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npm.taobao.org/mime/download/mime-1.6.0.tgz",
+ "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=",
+ "dev": true
+ },
"mime-db": {
"version": "1.44.0",
"resolved": "https://registry.npm.taobao.org/mime-db/download/mime-db-1.44.0.tgz?cache=0&sync_timestamp=1600831159918&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime-db%2Fdownload%2Fmime-db-1.44.0.tgz",
@@ -5773,6 +6133,12 @@
"sax": "^1.2.4"
}
},
+ "negotiator": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npm.taobao.org/negotiator/download/negotiator-0.6.2.tgz",
+ "integrity": "sha1-/qz3zPUlp3rpY0Q2pkiD/+yjRvs=",
+ "dev": true
+ },
"neo-async": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
@@ -5994,6 +6360,14 @@
"isobject": "^3.0.1"
}
},
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -6116,6 +6490,12 @@
"integrity": "sha1-9o5OW6GFKsLK3AD0VV//bCq7YXg=",
"dev": true
},
+ "parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npm.taobao.org/parseurl/download/parseurl-1.3.3.tgz",
+ "integrity": "sha1-naGee+6NEt/wUT7Vt2lXeTvC6NQ=",
+ "dev": true
+ },
"pascalcase": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
@@ -6145,6 +6525,12 @@
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
"dev": true
},
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-0.1.7.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-to-regexp%2Fdownload%2Fpath-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
+ "dev": true
+ },
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npm.taobao.org/performance-now/download/performance-now-2.1.0.tgz",
@@ -6239,6 +6625,16 @@
"yargs": "^3.10.0"
}
},
+ "proxy-addr": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npm.taobao.org/proxy-addr/download/proxy-addr-2.0.6.tgz",
+ "integrity": "sha1-/cIzZQVEfT8vLGOO0nLK9hS7sr8=",
+ "dev": true,
+ "requires": {
+ "forwarded": "~0.1.2",
+ "ipaddr.js": "1.9.1"
+ }
+ },
"psl": {
"version": "1.8.0",
"resolved": "https://registry.npm.taobao.org/psl/download/psl-1.8.0.tgz",
@@ -6267,6 +6663,24 @@
"integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=",
"dev": true
},
+ "range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npm.taobao.org/range-parser/download/range-parser-1.2.1.tgz",
+ "integrity": "sha1-PPNwI9GZ4cJNGlW4SADC8+ZGgDE=",
+ "dev": true
+ },
+ "raw-body": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npm.taobao.org/raw-body/download/raw-body-2.4.0.tgz",
+ "integrity": "sha1-oc5vucm8NWylLoklarWQWeE9AzI=",
+ "dev": true,
+ "requires": {
+ "bytes": "3.1.0",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ }
+ },
"rc": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
@@ -6640,6 +7054,64 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
},
+ "send": {
+ "version": "0.17.1",
+ "resolved": "https://registry.npm.taobao.org/send/download/send-0.17.1.tgz",
+ "integrity": "sha1-wdiwWfeQD3Rm3Uk4vcROEd2zdsg=",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "~1.7.2",
+ "mime": "1.6.0",
+ "ms": "2.1.1",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.1",
+ "statuses": "~1.5.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566551397&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
+ "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433856030&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.1.tgz?cache=0&sync_timestamp=1607433856030&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.1.tgz",
+ "integrity": "sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo=",
+ "dev": true
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npm.taobao.org/serve-static/download/serve-static-1.14.1.tgz",
+ "integrity": "sha1-Zm5jbcTwEPfvKZcKiKZ0MgiYsvk=",
+ "dev": true,
+ "requires": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.17.1"
+ }
+ },
"set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
@@ -6666,6 +7138,12 @@
"split-string": "^3.0.1"
}
},
+ "setprototypeof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.1.tgz",
+ "integrity": "sha1-fpWsskqpL1iF4KvvW6ExMw1K5oM=",
+ "dev": true
+ },
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npm.taobao.org/shebang-command/download/shebang-command-1.2.0.tgz",
@@ -6991,6 +7469,12 @@
}
}
},
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npm.taobao.org/statuses/download/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+ "dev": true
+ },
"stealthy-require": {
"version": "1.1.1",
"resolved": "https://registry.npm.taobao.org/stealthy-require/download/stealthy-require-1.1.1.tgz",
@@ -7423,6 +7907,12 @@
}
}
},
+ "toidentifier": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npm.taobao.org/toidentifier/download/toidentifier-1.0.0.tgz",
+ "integrity": "sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM=",
+ "dev": true
+ },
"tough-cookie": {
"version": "3.0.1",
"resolved": "https://registry.npm.taobao.org/tough-cookie/download/tough-cookie-3.0.1.tgz",
@@ -7614,6 +8104,16 @@
"integrity": "sha1-CeJJ696FHTseSNJ8EFREZn8XuD0=",
"dev": true
},
+ "type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npm.taobao.org/type-is/download/type-is-1.6.18.tgz",
+ "integrity": "sha1-TlUs0F3wlGfcvE73Od6J8s83wTE=",
+ "dev": true,
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ }
+ },
"typedarray-to-buffer": {
"version": "3.1.5",
"resolved": "https://registry.npm.taobao.org/typedarray-to-buffer/download/typedarray-to-buffer-3.1.5.tgz",
@@ -7671,6 +8171,12 @@
"set-value": "^2.0.1"
}
},
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npm.taobao.org/unpipe/download/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+ "dev": true
+ },
"unset-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
@@ -7737,6 +8243,12 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npm.taobao.org/utils-merge/download/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+ "dev": true
+ },
"uuid": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.1.0.tgz",
@@ -7771,6 +8283,12 @@
"spdx-expression-parse": "^3.0.0"
}
},
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+ "dev": true
+ },
"verror": {
"version": "1.10.0",
"resolved": "https://registry.npm.taobao.org/verror/download/verror-1.10.0.tgz",
diff --git a/package.json b/package.json
index 458bbef..c81aaa2 100644
--- a/package.json
+++ b/package.json
@@ -2,6 +2,7 @@
"name": "skywalking",
"version": "0.1.0",
"description": "The NodeJS agent for Apache SkyWalking",
+ "homepage": "skywalking.apache.org",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
"scripts": {
@@ -35,12 +36,15 @@
"email": "dev@skywalking.apache.org"
},
"devDependencies": {
+ "@types/express": "^4.17.9",
"@types/google-protobuf": "^3.7.2",
"@types/jest": "^26.0.15",
"@types/node": "^14.0.11",
+ "@types/on-finished": "^2.3.1",
"@types/semver": "^7.2.0",
"@types/uuid": "^8.0.0",
"axios": "^0.21.0",
+ "express": "^4.17.1",
"grpc-tools": "^1.10.0",
"grpc_tools_node_protoc_ts": "^4.0.0",
"jest": "^26.6.3",
@@ -55,8 +59,9 @@
"wait-for-expect": "^3.0.2"
},
"dependencies": {
- "google-protobuf": "^3.12.2",
+ "google-protobuf": "^3.14.0",
"grpc": "^1.10.1",
+ "on-finished": "^2.3.0",
"semver": "^7.3.2",
"tslib": "^2.0.3",
"uuid": "^8.1.0",
diff --git a/src/agent/Buffer.ts b/src/agent/Buffer.ts
index 8f4f061..99a18fb 100644
--- a/src/agent/Buffer.ts
+++ b/src/agent/Buffer.ts
@@ -18,18 +18,16 @@
*/
import { createLogger } from '../logging';
-import Segment from '../trace/context/Segment';
import config from '../config/AgentConfig';
-import TraceReportClient from '../agent/protocol/grpc/clients/TraceReportClient';
const logger = createLogger(__filename);
-class Buffer {
- maxSize: number;
- buffer: Segment[];
+export default class Buffer<T> {
+ private readonly maxSize: number;
+ private readonly buffer: T[];
- constructor(maxSize: number = 1000) {
- this.maxSize = maxSize;
+ constructor() {
+ this.maxSize = config.maxBufferSize;
this.buffer = [];
}
@@ -37,16 +35,17 @@ class Buffer {
return this.buffer.length;
}
- put(segment: Segment): this {
- if (this.buffer.length > this.maxSize) {
- logger.warn('Drop the data because of the buffer is oversized');
- return this;
+ put(element: T): boolean {
+ if (this.length > this.maxSize) {
+ logger.warn('Drop the data because of the buffer is oversize');
+ return false;
}
- this.buffer.push(segment);
- TraceReportClient.ref(); // this is currently hard-coded for grpc, if other protocols added need to change
+ this.buffer.push(element);
- return this;
+ return true;
}
-}
-export default new Buffer(config.maxBufferSize);
+ take(): T {
+ return this.buffer.splice(0, 1)[0];
+ }
+}
diff --git a/src/agent/protocol/Protocol.ts b/src/agent/protocol/Protocol.ts
index 7f87c6d..778437e 100644
--- a/src/agent/protocol/Protocol.ts
+++ b/src/agent/protocol/Protocol.ts
@@ -23,7 +23,7 @@
export default interface Protocol {
isConnected: boolean;
- heartbeat(): void;
+ heartbeat(): this;
- report(): void;
+ report(): this;
}
diff --git a/src/agent/protocol/grpc/GrpcProtocol.ts b/src/agent/protocol/grpc/GrpcProtocol.ts
index 4875459..df0bc1f 100644
--- a/src/agent/protocol/grpc/GrpcProtocol.ts
+++ b/src/agent/protocol/grpc/GrpcProtocol.ts
@@ -22,15 +22,25 @@ import HeartbeatClient from '../../../agent/protocol/grpc/clients/HeartbeatClien
import TraceReportClient from '../../../agent/protocol/grpc/clients/TraceReportClient';
export default class GrpcProtocol implements Protocol {
+ private readonly heartbeatClient: HeartbeatClient;
+ private readonly traceReportClient: TraceReportClient;
+
+ constructor() {
+ this.heartbeatClient = new HeartbeatClient();
+ this.traceReportClient = new TraceReportClient();
+ }
+
get isConnected(): boolean {
- return HeartbeatClient.isConnected && TraceReportClient.isConnected;
+ return this.heartbeatClient.isConnected && this.traceReportClient.isConnected;
}
- heartbeat() {
- HeartbeatClient.start();
+ heartbeat(): this {
+ this.heartbeatClient.start();
+ return this;
}
- report() {
- TraceReportClient.start();
+ report(): this {
+ this.traceReportClient.start();
+ return this;
}
}
diff --git a/src/agent/protocol/grpc/clients/HeartbeatClient.ts b/src/agent/protocol/grpc/clients/HeartbeatClient.ts
index bd36b7a..660d620 100755
--- a/src/agent/protocol/grpc/clients/HeartbeatClient.ts
+++ b/src/agent/protocol/grpc/clients/HeartbeatClient.ts
@@ -32,19 +32,21 @@ import * as os from 'os';
const logger = createLogger(__filename);
-class HeartbeatClient implements Client {
- heartbeatClient?: ManagementServiceClient;
- heartbeatTimer?: NodeJS.Timeout;
+export default class HeartbeatClient implements Client {
+ private readonly managementServiceClient: ManagementServiceClient;
+ private heartbeatTimer?: NodeJS.Timeout;
+
+ constructor() {
+ this.managementServiceClient = new ManagementServiceClient(config.collectorAddress, grpc.credentials.createInsecure(), {
+ interceptors: [AuthInterceptor],
+ });
+ }
get isConnected(): boolean {
- return this.heartbeatClient?.getChannel().getConnectivityState(true) === connectivityState.READY;
+ return this.managementServiceClient.getChannel().getConnectivityState(true) === connectivityState.READY;
}
start() {
- this.heartbeatClient = new ManagementServiceClient(config.collectorAddress, grpc.credentials.createInsecure(), {
- interceptors: [AuthInterceptor],
- });
-
if (this.heartbeatTimer) {
logger.warn(`
The heartbeat timer has already been scheduled,
@@ -69,7 +71,7 @@ class HeartbeatClient implements Client {
]);
this.heartbeatTimer = setInterval(() => {
- this.heartbeatClient?.reportInstanceProperties(
+ this.managementServiceClient.reportInstanceProperties(
instanceProperties,
(error, _) => {
@@ -78,7 +80,7 @@ class HeartbeatClient implements Client {
}
},
);
- this.heartbeatClient?.keepAlive(
+ this.managementServiceClient.keepAlive(
keepAlivePkg,
(error, _) => {
@@ -90,5 +92,3 @@ class HeartbeatClient implements Client {
}, 20000).unref();
}
}
-
-export default new HeartbeatClient();
diff --git a/src/agent/protocol/grpc/clients/TraceReportClient.ts b/src/agent/protocol/grpc/clients/TraceReportClient.ts
index 9a18032..fcc7fd8 100755
--- a/src/agent/protocol/grpc/clients/TraceReportClient.ts
+++ b/src/agent/protocol/grpc/clients/TraceReportClient.ts
@@ -24,32 +24,40 @@ import { createLogger } from '../../../../logging';
import Client from './Client';
import { TraceSegmentReportServiceClient } from '../../../../proto/language-agent/Tracing_grpc_pb';
import AuthInterceptor from '../AuthInterceptor';
-import buffer from '../../../../agent/Buffer';
+import Buffer from '../../../../agent/Buffer';
import SegmentObjectAdapter from '../SegmentObjectAdapter';
+import { emitter } from '../../../../lib/EventEmitter';
+import Segment from '../../../../trace/context/Segment';
const logger = createLogger(__filename);
-class TraceReportClient implements Client {
- reporterClient?: TraceSegmentReportServiceClient;
- timeout: any;
+export default class TraceReportClient implements Client {
+ private readonly reporterClient: TraceSegmentReportServiceClient;
+ private readonly buffer: Buffer<Segment>;
+ private timeout?: NodeJS.Timeout;
- get isConnected(): boolean {
- return this.reporterClient?.getChannel().getConnectivityState(true) === connectivityState.READY;
- }
-
- ref() {
- this.timeout.ref();
- }
-
- start() {
+ constructor() {
+ this.buffer = new Buffer();
this.reporterClient = new TraceSegmentReportServiceClient(
config.collectorAddress,
grpc.credentials.createInsecure(),
{ interceptors: [AuthInterceptor] },
);
+ emitter.on('segment-finished', (segment) => {
+ if (this.buffer.put(segment)) {
+ this.timeout?.ref();
+ }
+ });
+ }
+
+ get isConnected(): boolean {
+ return this.reporterClient?.getChannel().getConnectivityState(true) === connectivityState.READY;
+ }
+
+ start() {
const reportFunction = () => {
try {
- if (buffer.length === 0 || !this.reporterClient) {
+ if (this.buffer.length === 0) {
return;
}
@@ -59,8 +67,8 @@ class TraceReportClient implements Client {
}
});
- while (buffer.length > 0) {
- const segment = buffer.buffer.splice(0, 1)[0];
+ while (this.buffer.length > 0) {
+ const segment = this.buffer.take();
if (segment) {
if (logger.isDebugEnabled()) {
logger.debug('Sending segment ', { segment });
@@ -79,5 +87,3 @@ class TraceReportClient implements Client {
this.timeout = setTimeout(reportFunction, 1000).unref();
}
}
-
-export default new TraceReportClient();
diff --git a/src/core/PluginInstaller.ts b/src/core/PluginInstaller.ts
index 80ce569..e959501 100644
--- a/src/core/PluginInstaller.ts
+++ b/src/core/PluginInstaller.ts
@@ -26,12 +26,14 @@ import * as semver from 'semver';
const logger = createLogger(__filename);
let topModule = module;
-for (; topModule.parent; topModule = topModule.parent);
+while (topModule.parent) {
+ topModule = topModule.parent;
+}
-class PluginInstaller {
- pluginDir: string;
- require: (name: string) => any = topModule.require.bind(topModule);
- resolve = (request: string) => (module.constructor as any)._resolveFilename(request, topModule);
+export default class PluginInstaller {
+ private readonly pluginDir: string;
+ private readonly require: (name: string) => any = topModule.require.bind(topModule);
+ private readonly resolve = (request: string) => (module.constructor as any)._resolveFilename(request, topModule);
constructor() {
this.pluginDir = path.resolve(__dirname, '..', 'plugins');
@@ -72,33 +74,30 @@ class PluginInstaller {
install(): void {
fs.readdirSync(this.pluginDir)
- .filter((file) => !(file.endsWith('.d.ts') || file.endsWith('.js.map')))
- .forEach((file) => {
- let plugin;
- const pluginFile = path.join(this.pluginDir, file);
-
- try {
- plugin = require(pluginFile).default as SwPlugin;
- const { isSupported, version } = this.checkModuleVersion(plugin);
-
- if (!isSupported) {
- logger.info(`Plugin ${plugin.module} ${version} doesn't satisfy the supported version ${plugin.versions}`);
- return;
- }
-
- logger.info(`Installing plugin ${plugin.module} ${plugin.versions}`);
+ .filter((file) => !(file.endsWith('.d.ts') || file.endsWith('.js.map')))
+ .forEach((file) => {
+ let plugin;
+ const pluginFile = path.join(this.pluginDir, file);
+
+ try {
+ plugin = require(pluginFile).default as SwPlugin;
+ const { isSupported, version } = this.checkModuleVersion(plugin);
+
+ if (!isSupported) {
+ logger.info(`Plugin ${plugin.module} ${version} doesn't satisfy the supported version ${plugin.versions}`);
+ return;
+ }
- plugin.install();
+ logger.info(`Installing plugin ${plugin.module} ${plugin.versions}`);
- } catch (e) {
- if (plugin) {
- logger.error(`Error installing plugin ${plugin.module} ${plugin.versions}`);
- } else {
- logger.error(`Error processing plugin ${pluginFile}`);
- }
+ plugin.install();
+ } catch (e) {
+ if (plugin) {
+ logger.error(`Error installing plugin ${plugin.module} ${plugin.versions}`);
+ } else {
+ logger.error(`Error processing plugin ${pluginFile}`);
}
- });
+ }
+ });
}
}
-
-export default new PluginInstaller();
diff --git a/src/index.ts b/src/index.ts
index 698e22e..1dfae71 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -20,14 +20,12 @@
import config, { AgentConfig, finalizeConfig } from './config/AgentConfig';
import GrpcProtocol from './agent/protocol/grpc/GrpcProtocol';
import { createLogger } from './logging';
-import Protocol from './agent/protocol/Protocol';
import PluginInstaller from './core/PluginInstaller';
const logger = createLogger(__filename);
class Agent {
- started = false;
- protocol: Protocol = new GrpcProtocol();
+ private started = false;
start(options: AgentConfig = {}): void {
if (process.env.SW_DISABLE === 'true') {
@@ -45,10 +43,9 @@ class Agent {
this.started = true;
- PluginInstaller.install();
+ new PluginInstaller().install();
- this.protocol.heartbeat();
- this.protocol.report();
+ new GrpcProtocol().heartbeat().report();
}
}
diff --git a/src/agent/protocol/Protocol.ts b/src/lib/EventEmitter.ts
similarity index 68%
copy from src/agent/protocol/Protocol.ts
copy to src/lib/EventEmitter.ts
index 7f87c6d..9d4f708 100644
--- a/src/agent/protocol/Protocol.ts
+++ b/src/lib/EventEmitter.ts
@@ -17,13 +17,16 @@
*
*/
-/**
- * The transport protocol between the agent and the backend (OAP).
- */
-export default interface Protocol {
- isConnected: boolean;
+/* tslint:disable:unified-signatures */
+
+import { EventEmitter } from 'events';
+import Segment from '../trace/context/Segment';
- heartbeat(): void;
+declare interface SkyWalkingEventEmitter {
+ on(event: 'segment-finished', listener: (segment: Segment) => void): this;
+}
- report(): void;
+class SkyWalkingEventEmitter extends EventEmitter {
}
+
+export const emitter: SkyWalkingEventEmitter = new SkyWalkingEventEmitter();
diff --git a/src/plugins/AxiosPlugin.ts b/src/plugins/AxiosPlugin.ts
index 37e330c..1ce7191 100644
--- a/src/plugins/AxiosPlugin.ts
+++ b/src/plugins/AxiosPlugin.ts
@@ -25,14 +25,13 @@ import Span from '../trace/span/Span';
import Tag from '../Tag';
import { SpanLayer } from '../proto/language-agent/Tracing_pb';
import { createLogger } from '../logging';
-import PluginInstaller from '../core/PluginInstaller';
const logger = createLogger(__filename);
class AxiosPlugin implements SwPlugin {
readonly module = 'axios';
readonly versions = '*';
- axios = PluginInstaller.require('axios').default;
+ axios = require('axios').default;
install(): void {
if (logger.isDebugEnabled()) {
@@ -53,7 +52,7 @@ class AxiosPlugin implements SwPlugin {
}
span.stop();
- }
+ };
this.axios.interceptors.request.use(
(config: any) => {
@@ -71,7 +70,7 @@ class AxiosPlugin implements SwPlugin {
error.config.span.stop();
return Promise.reject(error);
- }
+ },
);
this.axios.interceptors.response.use(
@@ -87,26 +86,23 @@ class AxiosPlugin implements SwPlugin {
copyStatusAndStop(error.config.span, error.response);
return Promise.reject(error);
- }
+ },
);
const _request = this.axios.Axios.prototype.request;
- this.axios.Axios.prototype.request = function (config: any) {
+ this.axios.Axios.prototype.request = function(config: any) {
const { host, pathname: operation } = new URL(config.url); // TODO: this may throw invalid URL
const span = ContextManager.current.newExitSpan(operation, host).start();
try {
- span.component = Component.HTTP; // TODO: add Component.AXIOS (to main Skywalking project)
+ span.component = Component.AXIOS; // TODO: add Component.AXIOS (to main Skywalking project)
span.layer = SpanLayer.HTTP;
span.peer = host;
span.tag(Tag.httpURL(host + operation));
span.async();
- const request = _request.call(this, {...config, span});
-
- return request;
-
+ return _request.call(this, { ...config, span });
} catch (e) {
span.error(e);
span.stop();
diff --git a/src/plugins/ExpressPlugin.ts b/src/plugins/ExpressPlugin.ts
index 1cd3172..2ca1e8a 100644
--- a/src/plugins/ExpressPlugin.ts
+++ b/src/plugins/ExpressPlugin.ts
@@ -24,25 +24,18 @@ import { Component } from '../trace/Component';
import Tag from '../Tag';
import { SpanLayer } from '../proto/language-agent/Tracing_pb';
import { ContextCarrier } from '../trace/context/ContextCarrier';
-import { createLogger } from '../logging';
-import PluginInstaller from '../core/PluginInstaller';
-
-const logger = createLogger(__filename);
+import onFinished from 'on-finished';
class ExpressPlugin implements SwPlugin {
readonly module = 'express';
readonly versions = '*';
install(): void {
- if (logger.isDebugEnabled()) {
- logger.debug('installing express plugin');
- }
this.interceptServerRequest();
}
private interceptServerRequest() {
- const onFinished = PluginInstaller.require('on-finished');
- const router = PluginInstaller.require('express/lib/router');
+ const router = require('express/lib/router');
const _handle = router.handle;
router.handle = function(req: IncomingMessage, res: ServerResponse, out: any) {
@@ -58,13 +51,16 @@ class ExpressPlugin implements SwPlugin {
const span = ContextManager.current.newEntrySpan(operation, carrier).start();
let stopped = 0;
- const stopIfNotStopped = () => {
+ const stopIfNotStopped = (err: Error | null) => {
if (!stopped++) {
span.stop();
span.tag(Tag.httpStatusCode(res.statusCode));
if (res.statusCode && res.statusCode >= 400) {
span.errored = true;
}
+ if (err) {
+ span.error(err);
+ }
if (res.statusMessage) {
span.tag(Tag.httpStatusMsg(res.statusMessage));
}
@@ -78,21 +74,19 @@ class ExpressPlugin implements SwPlugin {
span.tag(Tag.httpURL(span.peer + req.url));
const ret = _handle.call(this, req, res, (err: Error) => {
- if (err)
+ if (err) {
span.error(err);
- else
+ } else {
span.errored = true;
+ }
out.call(this, err);
stopped -= 1; // skip first stop attempt, make sure stop executes once status code and message is set
- onFinished(req, stopIfNotStopped); // this must run after any handlers deferred in 'out'
});
- onFinished(req, stopIfNotStopped);
+ onFinished(res, stopIfNotStopped); // this must run after any handlers deferred in 'out'
return ret;
-
} catch (e) {
- span.error(e);
- stopIfNotStopped();
+ stopIfNotStopped(e);
throw e;
}
};
diff --git a/src/plugins/HttpPlugin.ts b/src/plugins/HttpPlugin.ts
index 2984cc5..5c2d8b2 100644
--- a/src/plugins/HttpPlugin.ts
+++ b/src/plugins/HttpPlugin.ts
@@ -26,19 +26,13 @@ import Tag from '../Tag';
import ExitSpan from '../trace/span/ExitSpan';
import { SpanLayer } from '../proto/language-agent/Tracing_pb';
import { ContextCarrier } from '../trace/context/ContextCarrier';
-import { createLogger } from '../logging';
-
-const logger = createLogger(__filename);
+import onFinished from 'on-finished';
class HttpPlugin implements SwPlugin {
readonly module = 'http';
readonly versions = '*';
install(): void {
- if (logger.isDebugEnabled()) {
- logger.debug('installing http plugin');
- }
-
const http = require('http');
const https = require('https');
@@ -51,7 +45,7 @@ class HttpPlugin implements SwPlugin {
private interceptClientRequest(module: any) {
const _request = module.request;
- module.request = function () {
+ module.request = function() {
const url: URL | string | RequestOptions = arguments[0];
const { host, pathname } =
@@ -60,16 +54,26 @@ class HttpPlugin implements SwPlugin {
: typeof url === 'string'
? new URL(url) // TODO: this may throw invalid URL
: {
- host: (url.host || url.hostname || 'unknown') + ':' + url.port,
- pathname: url.path || '/',
- };
+ host: (url.host || url.hostname || 'unknown') + ':' + (url.port || 80),
+ pathname: url.path || '/',
+ };
const operation = pathname.replace(/\?.*$/g, '');
- let stopped = 0; // compensating if request aborted right after creation 'close' is not emitted
- const stopIfNotStopped = () => !stopped++ ? span.stop() : null; // make sure we stop only once
const span: ExitSpan = ContextManager.current.newExitSpan(operation, host).start() as ExitSpan;
+ let stopped = 0; // compensating if request aborted right after creation 'close' is not emitted
+ const stopIfNotStopped = (err?: Error | null) => {
+ if (stopped++) {
+ return;
+ }
+ span.stop();
+ if (err) {
+ span.error(err);
+ }
+ };
+
try {
+ // TODO: these should go into span class
if (span.depth === 1) { // only set HTTP if this span is not overridden by a higher level one
span.component = Component.HTTP;
span.layer = SpanLayer.HTTP;
@@ -82,17 +86,13 @@ class HttpPlugin implements SwPlugin {
span.tag(Tag.httpURL(httpURL));
}
- const request: ClientRequest = _request.apply(this, arguments);
+ const req: ClientRequest = _request.apply(this, arguments);
span.inject().items.forEach((item) => {
- request.setHeader(item.key, item.value);
+ req.setHeader(item.key, item.value);
});
- request.on('close', stopIfNotStopped);
- request.on('abort', () => (span.errored = true, stopIfNotStopped()));
- request.on('error', (err) => (span.error(err), stopIfNotStopped()));
-
- request.prependListener('response', (res) => {
+ req.prependListener('response', (res) => {
span.resync();
span.tag(Tag.httpStatusCode(res.statusCode));
if (res.statusCode && res.statusCode >= 400) {
@@ -101,19 +101,15 @@ class HttpPlugin implements SwPlugin {
if (res.statusMessage) {
span.tag(Tag.httpStatusMsg(res.statusMessage));
}
- stopIfNotStopped();
});
+ onFinished(req, stopIfNotStopped);
span.async();
- return request;
+ return req;
} catch (e) {
- if (!stopped) { // don't want to set error if exception occurs after clean close
- span.error(e);
- stopIfNotStopped();
- }
-
+ stopIfNotStopped(e);
throw e;
}
};
@@ -122,7 +118,7 @@ class HttpPlugin implements SwPlugin {
private interceptServerRequest(module: any) {
const _emit = module.Server.prototype.emit;
- module.Server.prototype.emit = function () {
+ module.Server.prototype.emit = function() {
if (arguments[0] !== 'request') {
return _emit.apply(this, arguments);
}
@@ -138,27 +134,37 @@ class HttpPlugin implements SwPlugin {
const carrier = ContextCarrier.from(headersMap);
const operation = (req.url || '/').replace(/\?.*/g, '');
- const span = ContextManager.current.newEntrySpan(operation, carrier);
+ const span = ContextManager.current.newEntrySpan(operation, carrier).start();
- return ContextManager.withSpan(span, (self, args) => {
- span.component = Component.HTTP_SERVER;
- span.layer = SpanLayer.HTTP;
- span.peer = req.headers.host || '';
- span.tag(Tag.httpURL(span.peer + req.url));
+ span.component = Component.HTTP_SERVER;
+ span.layer = SpanLayer.HTTP;
+ span.peer = req.headers.host || '';
+ span.tag(Tag.httpURL(span.peer + req.url));
- const ret = _emit.apply(self, args);
-
- span.tag(Tag.httpStatusCode(res.statusCode));
- if (res.statusCode && res.statusCode >= 400) {
- span.errored = true;
- }
- if (res.statusMessage) {
- span.tag(Tag.httpStatusMsg(res.statusMessage));
+ let stopped = 0;
+ const stopIfNotStopped = (err: Error | null) => {
+ if (!stopped++) {
+ span.stop();
+ span.tag(Tag.httpStatusCode(res.statusCode));
+ if (res.statusCode && res.statusCode >= 400) {
+ span.errored = true;
+ }
+ if (err) {
+ span.error(err);
+ }
+ if (res.statusMessage) {
+ span.tag(Tag.httpStatusMsg(res.statusMessage));
+ }
}
+ };
+ onFinished(res, stopIfNotStopped);
- return ret;
-
- }, this, arguments);
+ try {
+ return _emit.apply(this, arguments);
+ } catch (e) {
+ stopIfNotStopped(e);
+ throw e;
+ }
};
}
}
diff --git a/src/trace/Component.ts b/src/trace/Component.ts
index 60c4c5d..1eb9597 100644
--- a/src/trace/Component.ts
+++ b/src/trace/Component.ts
@@ -18,11 +18,12 @@
*/
export class Component {
- static UNKNOWN = new Component(0);
- static HTTP = new Component(2);
- static MONGODB = new Component(9);
- static HTTP_SERVER = new Component(49);
- static EXPRESS = new Component(4002);
+ static readonly UNKNOWN = new Component(0);
+ static readonly HTTP = new Component(2);
+ static readonly MONGODB = new Component(9);
+ static readonly HTTP_SERVER = new Component(49);
+ static readonly EXPRESS = new Component(4002);
+ static readonly AXIOS = new Component(4005);
- constructor(public id: number) {}
+ constructor(public readonly id: number) {}
}
diff --git a/src/trace/context/ContextManager.ts b/src/trace/context/ContextManager.ts
index 3ed253e..a586856 100644
--- a/src/trace/context/ContextManager.ts
+++ b/src/trace/context/ContextManager.ts
@@ -21,26 +21,38 @@ import Context from '../../trace/context/Context';
import Span from '../../trace/span/Span';
import SpanContext from '../../trace/context/SpanContext';
-type AsyncState = {context: Context, spans: Span[]};
+import async_hooks from 'async_hooks';
-const async_hooks = require('async_hooks');
-let store: any;
+type AsyncState = { context: Context, spans: Span[] };
+
+let store: {
+ getStore(): AsyncState | undefined;
+ enterWith(s: AsyncState): void;
+};
if (async_hooks.AsyncLocalStorage) {
store = new async_hooks.AsyncLocalStorage();
-
} else { // Node 10 doesn't have AsyncLocalStore, so recreate it
const executionAsyncId = async_hooks.executionAsyncId;
- const asyncLocalStore: {[index: string]: any} = {};
+ const asyncLocalStore: { [index: string]: any } = {};
- store = new class {
- getStore(): AsyncState | undefined { return asyncLocalStore[executionAsyncId()] as unknown as AsyncState; }
- enterWith(store: AsyncState): void { asyncLocalStore[executionAsyncId()] = store; }
- }();
+ store = {
+ getStore(): AsyncState | undefined {
+ return asyncLocalStore[executionAsyncId()] as unknown as AsyncState;
+ },
+
+ enterWith(s: AsyncState): void {
+ asyncLocalStore[executionAsyncId()] = s;
+ },
+ };
async_hooks.createHook({
- init(asyncId: number, type: string, triggerId: number) { asyncLocalStore[asyncId] = asyncLocalStore[triggerId]; },
- destroy(asyncId: number) { delete asyncLocalStore[asyncId]; }
+ init(asyncId: number, type: string, triggerId: number) {
+ asyncLocalStore[asyncId] = asyncLocalStore[triggerId];
+ },
+ destroy(asyncId: number) {
+ delete asyncLocalStore[asyncId];
+ },
}).enable();
}
@@ -49,23 +61,28 @@ class ContextManager {
let asyncState = store.getStore();
if (asyncState === undefined) {
- asyncState = {context: new SpanContext(), spans: []};
+ asyncState = { context: new SpanContext(), spans: [] };
store.enterWith(asyncState);
}
return asyncState;
}
- get current(): Context { return this.asyncState.context; }
- get spans(): Span[] { return this.asyncState.spans; }
+ get current(): Context {
+ return this.asyncState.context;
+ }
+
+ get spans(): Span[] {
+ return this.asyncState.spans;
+ }
spansDup(): Span[] {
let asyncState = store.getStore();
if (asyncState === undefined) {
- asyncState = {context: new SpanContext(), spans: []};
+ asyncState = { context: new SpanContext(), spans: [] };
} else {
- asyncState = {context: asyncState.context, spans: [...asyncState.spans]};
+ asyncState = { context: asyncState.context, spans: [...asyncState.spans] };
}
store.enterWith(asyncState);
@@ -78,13 +95,12 @@ class ContextManager {
}
restore(context: Context, spans: Span[]): void {
- store.enterWith({context, spans: spans || []});
+ store.enterWith({ context, spans: spans || [] });
}
withSpan(span: Span, callback: (...args: any[]) => any, ...args: any[]): any {
- if(!span.startTime)
+ if (!span.startTime)
span.start();
-
try {
return callback(...args);
} catch (e) {
@@ -96,9 +112,8 @@ class ContextManager {
}
async withSpanAwait(span: Span, callback: (...args: any[]) => any, ...args: any[]): Promise<any> {
- if(!span.startTime)
+ if (!span.startTime)
span.start();
-
try {
return await callback(...args);
} catch (e) {
diff --git a/src/trace/context/SpanContext.ts b/src/trace/context/SpanContext.ts
index c08f524..6eb2c59 100644
--- a/src/trace/context/SpanContext.ts
+++ b/src/trace/context/SpanContext.ts
@@ -26,12 +26,12 @@ import Segment from '../../trace/context/Segment';
import EntrySpan from '../../trace/span/EntrySpan';
import ExitSpan from '../../trace/span/ExitSpan';
import LocalSpan from '../../trace/span/LocalSpan';
-import buffer from '../../agent/Buffer';
import { createLogger } from '../../logging';
import { executionAsyncId } from 'async_hooks';
import { ContextCarrier } from './ContextCarrier';
import ContextManager from './ContextManager';
import { SpanType } from '../../proto/language-agent/Tracing_pb';
+import { emitter } from '../../lib/EventEmitter';
const logger = createLogger(__filename);
@@ -155,7 +155,11 @@ export default class SpanContext implements Context {
}
start(span: Span): Context {
- logger.debug('Starting span', { span: span.operation, spans: ContextManager.spans, nSpans: this.nSpans });
+ logger.debug('Starting span', {
+ span: span.operation,
+ spans: ContextManager.spans,
+ nSpans: this.nSpans,
+ });
this.nSpans += 1;
if (ContextManager.spans.every((s) => s.id !== span.id)) {
@@ -166,7 +170,11 @@ export default class SpanContext implements Context {
}
stop(span: Span): boolean {
- logger.debug('Stopping span', { span: span.operation, spans: ContextManager.spans, nSpans: this.nSpans });
+ logger.debug('Stopping span', {
+ span: span.operation,
+ spans: ContextManager.spans,
+ nSpans: this.nSpans,
+ });
span.finish(this.segment);
@@ -176,7 +184,7 @@ export default class SpanContext implements Context {
}
if (--this.nSpans === 0) {
- buffer.put(this.segment);
+ emitter.emit('segment-finished', this.segment);
ContextManager.clear();
return true;
}
@@ -185,7 +193,11 @@ export default class SpanContext implements Context {
}
async(span: Span) {
- logger.debug('Async span', { span: span.operation, spans: ContextManager.spans, nSpans: this.nSpans });
+ logger.debug('Async span', {
+ span: span.operation,
+ spans: ContextManager.spans,
+ nSpans: this.nSpans,
+ });
const idx = ContextManager.spans.indexOf(span);
@@ -199,7 +211,11 @@ export default class SpanContext implements Context {
}
resync(span: Span) {
- logger.debug('Resync span', { span: span.operation, spans: ContextManager.spans, nSpans: this.nSpans });
+ logger.debug('Resync span', {
+ span: span.operation,
+ spans: ContextManager.spans,
+ nSpans: this.nSpans,
+ });
if ((span.context as SpanContext).nSpans === 1) {
ContextManager.restore(span.context, [span]);
diff --git a/src/trace/span/EntrySpan.ts b/src/trace/span/EntrySpan.ts
index 59e841b..6c49e9a 100644
--- a/src/trace/span/EntrySpan.ts
+++ b/src/trace/span/EntrySpan.ts
@@ -47,9 +47,7 @@ export default class EntrySpan extends StackedSpan {
const ref = SegmentRef.fromCarrier(carrier);
- if (!this.refs.includes(ref)) {
- this.refs.push(ref);
- }
+ this.refer(ref);
return this;
}
diff --git a/src/trace/span/StackedSpan.ts b/src/trace/span/StackedSpan.ts
index 8c1886f..3b1fc74 100644
--- a/src/trace/span/StackedSpan.ts
+++ b/src/trace/span/StackedSpan.ts
@@ -18,12 +18,8 @@
*/
import Span, { SpanCtorOptions } from '../../trace/span/Span';
-import Segment from '../../trace/context/Segment';
-import { createLogger } from '../../logging';
import { SpanType } from '../../proto/language-agent/Tracing_pb';
-const logger = createLogger(__filename);
-
export default class StackedSpan extends Span {
depth = 0;
diff --git a/tests/plugins/http/client.ts b/tests/plugins/axios/client.ts
similarity index 79%
copy from tests/plugins/http/client.ts
copy to tests/plugins/axios/client.ts
index 2c2ce5e..91f435d 100644
--- a/tests/plugins/http/client.ts
+++ b/tests/plugins/axios/client.ts
@@ -18,21 +18,19 @@
*/
import * as http from 'http';
-import Agent from '../../../src';
+import agent from '../../../src';
+import axios from 'axios';
-Agent.start({
+agent.start({
serviceName: 'client',
maxBufferSize: 1000,
});
const server = http.createServer((req, res) => {
- http
- .request(`http://${process.env.SERVER || 'localhost:5000'}${req.url}`, (r) => {
- let data = '';
- r.on('data', (chunk) => (data += chunk));
- r.on('end', () => res.end(data));
- })
- .end();
+ axios
+ .get(`http://${process.env.SERVER || 'localhost:5000'}${req.url}`)
+ .then((r) => res.end(JSON.stringify(r.data)))
+ .catch(err => res.end(JSON.stringify(err)));
});
server.listen(5001, () => console.info('Listening on port 5001...'));
diff --git a/tests/plugins/http/docker-compose.yml b/tests/plugins/axios/docker-compose.yml
similarity index 92%
copy from tests/plugins/http/docker-compose.yml
copy to tests/plugins/axios/docker-compose.yml
index 8905cdb..b88cbee 100644
--- a/tests/plugins/http/docker-compose.yml
+++ b/tests/plugins/axios/docker-compose.yml
@@ -15,7 +15,7 @@
# limitations under the License.
#
-version: '2.1'
+version: '3.8'
services:
collector:
@@ -29,17 +29,16 @@ services:
extends:
file: ../common/base-compose.yml
service: agent
- container_name: server
ports:
- 5000:5000
volumes:
- - .:/app/tests/plugins/http
+ - .:/app/tests/plugins/express
healthcheck:
test: [ "CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/5000" ]
interval: 5s
timeout: 60s
retries: 120
- entrypoint: [ 'bash', '-c', 'npx ts-node /app/tests/plugins/http/server.ts' ]
+ entrypoint: [ 'bash', '-c', 'npx ts-node /app/tests/plugins/axios/server.ts' ]
depends_on:
collector:
condition: service_healthy
@@ -48,7 +47,6 @@ services:
extends:
file: ../common/base-compose.yml
service: agent
- container_name: client
ports:
- 5001:5001
environment:
@@ -58,7 +56,7 @@ services:
interval: 5s
timeout: 60s
retries: 120
- entrypoint: [ 'bash', '-c', 'npx ts-node /app/tests/plugins/http/client.ts' ]
+ entrypoint: [ 'bash', '-c', 'npx ts-node /app/tests/plugins/axios/client.ts' ]
depends_on:
server:
condition: service_healthy
diff --git a/tests/plugins/http/expected.data.yaml b/tests/plugins/axios/expected.data.yaml
similarity index 62%
copy from tests/plugins/http/expected.data.yaml
copy to tests/plugins/axios/expected.data.yaml
index 29e6cff..1f24544 100644
--- a/tests/plugins/http/expected.data.yaml
+++ b/tests/plugins/axios/expected.data.yaml
@@ -21,74 +21,89 @@ segmentItems:
segments:
- segmentId: not null
spans:
- - operationName: /test
- operationId: 0
- parentSpanId: -1
- spanId: 0
- spanLayer: Http
- startTime: gt 0
- endTime: gt 0
- componentId: 49
- isError: false
- spanType: Entry
- peer: server:5000
- skipAnalysis: false
- tags:
- - { key: http.url, value: server:5000/test }
- - { key: http.status.code, value: '200' }
- refs:
- - { parentEndpoint: '', networkAddress: 'server:5000', refType: CrossProcess,
- parentSpanId: 1, parentTraceSegmentId: not null, parentServiceInstance: not null,
- parentService: client, traceId: not null }
- operationName: /json
operationId: 0
parentSpanId: 0
spanId: 1
spanLayer: Http
+ tags:
+ - key: http.url
+ value: httpbin.org:80/json
+ - key: http.status.code
+ value: '200'
+ - key: http.status.msg
+ value: OK
startTime: gt 0
endTime: gt 0
- componentId: 2
- isError: false
+ componentId: 4005
spanType: Exit
peer: httpbin.org
skipAnalysis: false
- tags:
- - { key: http.url, value: httpbin.org/json }
- - { key: http.status.code, value: '200' }
- - { key: http.status.msg, value: OK }
- - serviceName: client
- segmentSize: 1
- segments:
- - segmentId: not null
- spans:
- - operationName: /test
+ - operationName: /axios
operationId: 0
parentSpanId: -1
spanId: 0
spanLayer: Http
+ tags:
+ - key: http.url
+ value: server:5000/axios
+ - key: http.status.code
+ value: '200'
+ - key: http.status.msg
+ value: OK
+ refs:
+ - parentEndpoint: ''
+ networkAddress: server:5000
+ refType: CrossProcess
+ parentSpanId: 1
+ parentTraceSegmentId: not null
+ parentServiceInstance: not null
+ parentService: client
+ traceId: not null
startTime: gt 0
endTime: gt 0
componentId: 49
- isError: false
spanType: Entry
- peer: localhost:5001
+ peer: server:5000
skipAnalysis: false
- tags:
- - { key: http.url, value: localhost:5001/test }
- - { key: http.status.code, value: '200' }
- - operationName: /test
+ - serviceName: client
+ segmentSize: 1
+ segments:
+ - segmentId: not null
+ spans:
+ - operationName: /axios
operationId: 0
parentSpanId: 0
spanId: 1
spanLayer: Http
+ tags:
+ - key: http.url
+ value: server:5000/axios
+ - key: http.status.code
+ value: '200'
+ - key: http.status.msg
+ value: OK
startTime: gt 0
endTime: gt 0
- componentId: 2
- isError: false
+ componentId: 4005
spanType: Exit
peer: server:5000
skipAnalysis: false
+ - operationName: /axios
+ operationId: 0
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: Http
tags:
- - { key: http.url, value: 'server:5000/test' }
- - { key: http.status.code, value: '200' }
- - { key: http.status.msg, value: OK }
+ - key: http.url
+ value: localhost:5001/axios
+ - key: http.status.code
+ value: '200'
+ - key: http.status.msg
+ value: OK
+ startTime: gt 0
+ endTime: gt 0
+ componentId: 49
+ spanType: Entry
+ peer: localhost:5001
+ skipAnalysis: false
diff --git a/tests/plugins/http/server.ts b/tests/plugins/axios/server.ts
similarity index 77%
copy from tests/plugins/http/server.ts
copy to tests/plugins/axios/server.ts
index b9cbc2f..bbca28d 100644
--- a/tests/plugins/http/server.ts
+++ b/tests/plugins/axios/server.ts
@@ -17,22 +17,18 @@
*
*/
-import Agent from '../../../src';
+import agent from '../../../src';
import * as http from 'http';
+import axios from 'axios';
-Agent.start({
+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', () => res.end(data));
- })
- .end();
+const server = http.createServer(async (req, res) => {
+ const r = await axios.get('http://httpbin.org/json');
+ res.end(JSON.stringify(r.data));
});
server.listen(5000, () => console.info('Listening on port 5000...'));
diff --git a/tests/plugins/http/test.ts b/tests/plugins/axios/test.ts
similarity index 94%
copy from tests/plugins/http/test.ts
copy to tests/plugins/axios/test.ts
index 07966da..63156be 100644
--- a/tests/plugins/http/test.ts
+++ b/tests/plugins/axios/test.ts
@@ -30,8 +30,8 @@ describe('plugin tests', () => {
beforeAll(async () => {
compose = await new DockerComposeEnvironment(rootDir, 'docker-compose.yml')
- .withWaitStrategy('client', Wait.forHealthCheck())
- .up();
+ .withWaitStrategy('client', Wait.forHealthCheck())
+ .up();
});
afterAll(async () => {
@@ -39,7 +39,7 @@ describe('plugin tests', () => {
});
it(__filename, async () => {
- await waitForExpect(async () => expect((await axios.get('http://localhost:5001/test')).status).toBe(200));
+ await waitForExpect(async () => expect((await axios.get('http://localhost:5001/axios')).status).toBe(200));
const expectedData = await fs.readFile(path.join(rootDir, 'expected.data.yaml'), 'utf8');
diff --git a/tests/plugins/common/Dockerfile.agent b/tests/plugins/common/Dockerfile.agent
index 4c51529..5e907d4 100644
--- a/tests/plugins/common/Dockerfile.agent
+++ b/tests/plugins/common/Dockerfile.agent
@@ -24,4 +24,3 @@ WORKDIR /app
ADD $ROOT /app
RUN npm install request && npm install
-
diff --git a/tests/plugins/common/base-compose.yml b/tests/plugins/common/base-compose.yml
index 1e16c0a..677493b 100644
--- a/tests/plugins/common/base-compose.yml
+++ b/tests/plugins/common/base-compose.yml
@@ -22,7 +22,6 @@ services:
build:
context: ../../../
dockerfile: tests/plugins/common/Dockerfile.tool
- container_name: collector
ports:
- 12800:12800
networks:
diff --git a/tests/plugins/http/client.ts b/tests/plugins/express/client.ts
similarity index 69%
copy from tests/plugins/http/client.ts
copy to tests/plugins/express/client.ts
index 2c2ce5e..20e0487 100644
--- a/tests/plugins/http/client.ts
+++ b/tests/plugins/express/client.ts
@@ -18,21 +18,24 @@
*/
import * as http from 'http';
-import Agent from '../../../src';
+import agent from '../../../src';
+import express from 'express';
-Agent.start({
+agent.start({
serviceName: 'client',
maxBufferSize: 1000,
});
-const server = http.createServer((req, res) => {
+const app = express();
+
+app.get('/express', (req, res) => {
http
- .request(`http://${process.env.SERVER || 'localhost:5000'}${req.url}`, (r) => {
- let data = '';
- r.on('data', (chunk) => (data += chunk));
- r.on('end', () => res.end(data));
- })
- .end();
+ .request(`http://${process.env.SERVER || 'localhost:5000'}${req.url}`, (r) => {
+ let data = '';
+ r.on('data', (chunk) => (data += chunk));
+ r.on('end', () => res.send(data));
+ })
+ .end();
});
-server.listen(5001, () => console.info('Listening on port 5001...'));
+app.listen(5001, () => console.info('Listening on port 5001...'));
diff --git a/tests/plugins/http/docker-compose.yml b/tests/plugins/express/docker-compose.yml
similarity index 92%
copy from tests/plugins/http/docker-compose.yml
copy to tests/plugins/express/docker-compose.yml
index 8905cdb..224e4c6 100644
--- a/tests/plugins/http/docker-compose.yml
+++ b/tests/plugins/express/docker-compose.yml
@@ -15,7 +15,7 @@
# limitations under the License.
#
-version: '2.1'
+version: '3.8'
services:
collector:
@@ -29,17 +29,16 @@ services:
extends:
file: ../common/base-compose.yml
service: agent
- container_name: server
ports:
- 5000:5000
volumes:
- - .:/app/tests/plugins/http
+ - .:/app/tests/plugins/express
healthcheck:
test: [ "CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/5000" ]
interval: 5s
timeout: 60s
retries: 120
- entrypoint: [ 'bash', '-c', 'npx ts-node /app/tests/plugins/http/server.ts' ]
+ entrypoint: [ 'bash', '-c', 'npx ts-node /app/tests/plugins/express/server.ts' ]
depends_on:
collector:
condition: service_healthy
@@ -48,7 +47,6 @@ services:
extends:
file: ../common/base-compose.yml
service: agent
- container_name: client
ports:
- 5001:5001
environment:
@@ -58,7 +56,7 @@ services:
interval: 5s
timeout: 60s
retries: 120
- entrypoint: [ 'bash', '-c', 'npx ts-node /app/tests/plugins/http/client.ts' ]
+ entrypoint: [ 'bash', '-c', 'npx ts-node /app/tests/plugins/express/client.ts' ]
depends_on:
server:
condition: service_healthy
diff --git a/tests/plugins/http/expected.data.yaml b/tests/plugins/express/expected.data.yaml
similarity index 62%
copy from tests/plugins/http/expected.data.yaml
copy to tests/plugins/express/expected.data.yaml
index 29e6cff..4f6311a 100644
--- a/tests/plugins/http/expected.data.yaml
+++ b/tests/plugins/express/expected.data.yaml
@@ -21,74 +21,89 @@ segmentItems:
segments:
- segmentId: not null
spans:
- - operationName: /test
- operationId: 0
- parentSpanId: -1
- spanId: 0
- spanLayer: Http
- startTime: gt 0
- endTime: gt 0
- componentId: 49
- isError: false
- spanType: Entry
- peer: server:5000
- skipAnalysis: false
- tags:
- - { key: http.url, value: server:5000/test }
- - { key: http.status.code, value: '200' }
- refs:
- - { parentEndpoint: '', networkAddress: 'server:5000', refType: CrossProcess,
- parentSpanId: 1, parentTraceSegmentId: not null, parentServiceInstance: not null,
- parentService: client, traceId: not null }
- operationName: /json
operationId: 0
parentSpanId: 0
spanId: 1
spanLayer: Http
+ tags:
+ - key: http.url
+ value: httpbin.org/json
+ - key: http.status.code
+ value: '200'
+ - key: http.status.msg
+ value: OK
startTime: gt 0
endTime: gt 0
componentId: 2
- isError: false
spanType: Exit
peer: httpbin.org
skipAnalysis: false
- tags:
- - { key: http.url, value: httpbin.org/json }
- - { key: http.status.code, value: '200' }
- - { key: http.status.msg, value: OK }
- - serviceName: client
- segmentSize: 1
- segments:
- - segmentId: not null
- spans:
- - operationName: /test
+ - operationName: /express
operationId: 0
parentSpanId: -1
spanId: 0
spanLayer: Http
+ tags:
+ - key: http.url
+ value: server:5000/express
+ - key: http.status.code
+ value: '200'
+ - key: http.status.msg
+ value: OK
+ refs:
+ - parentEndpoint: ''
+ networkAddress: server:5000
+ refType: CrossProcess
+ parentSpanId: 1
+ parentTraceSegmentId: not null
+ parentServiceInstance: not null
+ parentService: client
+ traceId: not null
startTime: gt 0
endTime: gt 0
- componentId: 49
- isError: false
+ componentId: 4002
spanType: Entry
- peer: localhost:5001
+ peer: server:5000
skipAnalysis: false
- tags:
- - { key: http.url, value: localhost:5001/test }
- - { key: http.status.code, value: '200' }
- - operationName: /test
+ - serviceName: client
+ segmentSize: 1
+ segments:
+ - segmentId: not null
+ spans:
+ - operationName: /express
operationId: 0
parentSpanId: 0
spanId: 1
spanLayer: Http
+ tags:
+ - key: http.url
+ value: server:5000/express
+ - key: http.status.code
+ value: '200'
+ - key: http.status.msg
+ value: OK
startTime: gt 0
endTime: gt 0
componentId: 2
- isError: false
spanType: Exit
peer: server:5000
skipAnalysis: false
+ - operationName: /express
+ operationId: 0
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: Http
tags:
- - { key: http.url, value: 'server:5000/test' }
- - { key: http.status.code, value: '200' }
- - { key: http.status.msg, value: OK }
+ - key: http.url
+ value: localhost:5001/express
+ - key: http.status.code
+ value: '200'
+ - key: http.status.msg
+ value: OK
+ startTime: gt 0
+ endTime: gt 0
+ componentId: 4002
+ spanType: Entry
+ peer: localhost:5001
+ skipAnalysis: false
diff --git a/tests/plugins/http/server.ts b/tests/plugins/express/server.ts
similarity index 70%
copy from tests/plugins/http/server.ts
copy to tests/plugins/express/server.ts
index b9cbc2f..9ce3346 100644
--- a/tests/plugins/http/server.ts
+++ b/tests/plugins/express/server.ts
@@ -17,22 +17,25 @@
*
*/
-import Agent from '../../../src';
+import agent from '../../../src';
import * as http from 'http';
-Agent.start({
+import express from 'express';
+
+agent.start({
serviceName: 'server',
maxBufferSize: 1000,
});
+const app = express();
-const server = http.createServer((req, res) => {
+app.get('/express', (req, res) => {
http
- .request('http://httpbin.org/json', (r) => {
- let data = '';
- r.on('data', (chunk) => (data += chunk));
- r.on('end', () => res.end(data));
- })
- .end();
+ .request('http://httpbin.org/json', (r) => {
+ let data = '';
+ r.on('data', (chunk) => (data += chunk));
+ r.on('end', () => res.send(data));
+ })
+ .end();
});
-server.listen(5000, () => console.info('Listening on port 5000...'));
+app.listen(5000, () => console.info('Listening on port 5000...'));
diff --git a/tests/plugins/http/test.ts b/tests/plugins/express/test.ts
similarity index 94%
copy from tests/plugins/http/test.ts
copy to tests/plugins/express/test.ts
index 07966da..b046f34 100644
--- a/tests/plugins/http/test.ts
+++ b/tests/plugins/express/test.ts
@@ -30,8 +30,8 @@ describe('plugin tests', () => {
beforeAll(async () => {
compose = await new DockerComposeEnvironment(rootDir, 'docker-compose.yml')
- .withWaitStrategy('client', Wait.forHealthCheck())
- .up();
+ .withWaitStrategy('client', Wait.forHealthCheck())
+ .up();
});
afterAll(async () => {
@@ -39,7 +39,7 @@ describe('plugin tests', () => {
});
it(__filename, async () => {
- await waitForExpect(async () => expect((await axios.get('http://localhost:5001/test')).status).toBe(200));
+ await waitForExpect(async () => expect((await axios.get('http://localhost:5001/express')).status).toBe(200));
const expectedData = await fs.readFile(path.join(rootDir, 'expected.data.yaml'), 'utf8');
diff --git a/tests/plugins/http/client.ts b/tests/plugins/http/client.ts
index 2c2ce5e..c1ee8a9 100644
--- a/tests/plugins/http/client.ts
+++ b/tests/plugins/http/client.ts
@@ -18,21 +18,21 @@
*/
import * as http from 'http';
-import Agent from '../../../src';
+import agent from '../../../src';
-Agent.start({
+agent.start({
serviceName: 'client',
maxBufferSize: 1000,
});
const server = http.createServer((req, res) => {
http
- .request(`http://${process.env.SERVER || 'localhost:5000'}${req.url}`, (r) => {
- let data = '';
- r.on('data', (chunk) => (data += chunk));
- r.on('end', () => res.end(data));
- })
- .end();
+ .request(`http://${process.env.SERVER || 'localhost:5000'}${req.url}`, (r) => {
+ let data = '';
+ r.on('data', (chunk) => (data += chunk));
+ r.on('end', () => res.end(data));
+ })
+ .end();
});
server.listen(5001, () => console.info('Listening on port 5001...'));
diff --git a/tests/plugins/http/docker-compose.yml b/tests/plugins/http/docker-compose.yml
index 8905cdb..e5d8ca7 100644
--- a/tests/plugins/http/docker-compose.yml
+++ b/tests/plugins/http/docker-compose.yml
@@ -29,7 +29,6 @@ services:
extends:
file: ../common/base-compose.yml
service: agent
- container_name: server
ports:
- 5000:5000
volumes:
@@ -48,7 +47,6 @@ services:
extends:
file: ../common/base-compose.yml
service: agent
- container_name: client
ports:
- 5001:5001
environment:
diff --git a/tests/plugins/http/expected.data.yaml b/tests/plugins/http/expected.data.yaml
index 29e6cff..1e9e6f2 100644
--- a/tests/plugins/http/expected.data.yaml
+++ b/tests/plugins/http/expected.data.yaml
@@ -21,25 +21,6 @@ segmentItems:
segments:
- segmentId: not null
spans:
- - operationName: /test
- operationId: 0
- parentSpanId: -1
- spanId: 0
- spanLayer: Http
- startTime: gt 0
- endTime: gt 0
- componentId: 49
- isError: false
- spanType: Entry
- peer: server:5000
- skipAnalysis: false
- tags:
- - { key: http.url, value: server:5000/test }
- - { key: http.status.code, value: '200' }
- refs:
- - { parentEndpoint: '', networkAddress: 'server:5000', refType: CrossProcess,
- parentSpanId: 1, parentTraceSegmentId: not null, parentServiceInstance: not null,
- parentService: client, traceId: not null }
- operationName: /json
operationId: 0
parentSpanId: 0
@@ -48,19 +29,16 @@ segmentItems:
startTime: gt 0
endTime: gt 0
componentId: 2
- isError: false
spanType: Exit
peer: httpbin.org
skipAnalysis: false
tags:
- - { key: http.url, value: httpbin.org/json }
- - { key: http.status.code, value: '200' }
- - { key: http.status.msg, value: OK }
- - serviceName: client
- segmentSize: 1
- segments:
- - segmentId: not null
- spans:
+ - key: http.url
+ value: httpbin.org/json
+ - key: http.status.code
+ value: '200'
+ - key: http.status.msg
+ value: OK
- operationName: /test
operationId: 0
parentSpanId: -1
@@ -69,13 +47,30 @@ segmentItems:
startTime: gt 0
endTime: gt 0
componentId: 49
- isError: false
spanType: Entry
- peer: localhost:5001
+ peer: server:5000
skipAnalysis: false
tags:
- - { key: http.url, value: localhost:5001/test }
- - { key: http.status.code, value: '200' }
+ - key: http.url
+ value: server:5000/test
+ - key: http.status.code
+ value: '200'
+ - key: http.status.msg
+ value: OK
+ refs:
+ - parentEndpoint: ''
+ networkAddress: server:5000
+ refType: CrossProcess
+ parentSpanId: 1
+ parentTraceSegmentId: not null
+ parentServiceInstance: not null
+ parentService: client
+ traceId: not null
+ - serviceName: client
+ segmentSize: 1
+ segments:
+ - segmentId: not null
+ spans:
- operationName: /test
operationId: 0
parentSpanId: 0
@@ -84,11 +79,31 @@ segmentItems:
startTime: gt 0
endTime: gt 0
componentId: 2
- isError: false
spanType: Exit
peer: server:5000
skipAnalysis: false
tags:
- - { key: http.url, value: 'server:5000/test' }
- - { key: http.status.code, value: '200' }
- - { key: http.status.msg, value: OK }
+ - key: http.url
+ value: server:5000/test
+ - key: http.status.code
+ value: '200'
+ - key: http.status.msg
+ value: OK
+ - operationName: /test
+ operationId: 0
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: Http
+ startTime: gt 0
+ endTime: gt 0
+ componentId: 49
+ spanType: Entry
+ peer: localhost:5001
+ skipAnalysis: false
+ tags:
+ - key: http.url
+ value: localhost:5001/test
+ - key: http.status.code
+ value: '200'
+ - key: http.status.msg
+ value: OK
diff --git a/tests/plugins/http/server.ts b/tests/plugins/http/server.ts
index b9cbc2f..bf362c7 100644
--- a/tests/plugins/http/server.ts
+++ b/tests/plugins/http/server.ts
@@ -17,22 +17,22 @@
*
*/
-import Agent from '../../../src';
+import agent from '../../../src';
import * as http from 'http';
-Agent.start({
+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', () => res.end(data));
- })
- .end();
+ .request('http://httpbin.org/json', (r) => {
+ let data = '';
+ r.on('data', (chunk) => (data += chunk));
+ r.on('end', () => res.end(data));
+ })
+ .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 07966da..3550b0e 100644
--- a/tests/plugins/http/test.ts
+++ b/tests/plugins/http/test.ts
@@ -30,8 +30,8 @@ describe('plugin tests', () => {
beforeAll(async () => {
compose = await new DockerComposeEnvironment(rootDir, 'docker-compose.yml')
- .withWaitStrategy('client', Wait.forHealthCheck())
- .up();
+ .withWaitStrategy('client', Wait.forHealthCheck())
+ .up();
});
afterAll(async () => {