From 6a87d2427a7c164b50f7b5257f81d7443078e128 Mon Sep 17 00:00:00 2001 From: jmjoy <918734043@qq.com> Date: Mon, 11 Jul 2022 18:16:56 +0800 Subject: [PATCH 01/12] Move e2e to workspace. --- .dockerignore | 1 - .github/licenserc.yaml | 2 - .gitignore | 2 + Cargo.toml | 6 + e2e/Cargo.lock | 1270 ---------------------------------------- e2e/Cargo.toml | 1 + e2e/docker/Dockerfile | 6 +- 7 files changed, 12 insertions(+), 1276 deletions(-) delete mode 100644 e2e/Cargo.lock diff --git a/.dockerignore b/.dockerignore index c1c154f..303c2fb 100644 --- a/.dockerignore +++ b/.dockerignore @@ -16,4 +16,3 @@ # under the License. # target/ -e2e/target \ No newline at end of file diff --git a/.github/licenserc.yaml b/.github/licenserc.yaml index 61cb41e..e9f23ff 100644 --- a/.github/licenserc.yaml +++ b/.github/licenserc.yaml @@ -29,9 +29,7 @@ header: - '**/.gitignore' - '**/.gitmodules' - 'vendor' - - 'e2e/vendor' - '.cargo' - - 'e2e/.cargo' - '.vscode' comment: on-failure diff --git a/.gitignore b/.gitignore index c26d977..47dc92d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ /e2e/target .idea/ /Cargo.lock +/.cargo/config.toml +/vendor diff --git a/Cargo.toml b/Cargo.toml index aa7b9d7..7f55728 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,12 @@ # under the License. # +[workspace] +members = [ + ".", + "e2e", +] + [package] name = "skywalking" version = "0.2.0" diff --git a/e2e/Cargo.lock b/e2e/Cargo.lock deleted file mode 100644 index e6c6232..0000000 --- a/e2e/Cargo.lock +++ /dev/null @@ -1,1270 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -version = 3 - -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - -[[package]] -name = "anyhow" -version = "1.0.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" - -[[package]] -name = "async-stream" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" -dependencies = [ - "async-stream-impl", - "futures-core", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "async-trait" -version = "0.1.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "axum" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab2504b827a8bef941ba3dd64bdffe9cf56ca182908a147edd6189c95fbcae7d" -dependencies = [ - "async-trait", - "axum-core", - "bitflags", - "bytes", - "futures-util", - "http", - "http-body", - "hyper", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "serde", - "sync_wrapper", - "tokio", - "tower", - "tower-http", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da31c0ed7b4690e2c78fe4b880d21cd7db04a346ebc658b4270251b695437f17" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "mime", -] - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "cc" -version = "1.0.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clap" -version = "2.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" -dependencies = [ - "ansi_term", - "atty", - "bitflags", - "strsim", - "textwrap", - "unicode-width", - "vec_map", -] - -[[package]] -name = "cmake" -version = "0.1.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a" -dependencies = [ - "cc", -] - -[[package]] -name = "e2e" -version = "0.2.0" -dependencies = [ - "hyper", - "skywalking", - "structopt", - "tokio", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "fastrand" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" -dependencies = [ - "instant", -] - -[[package]] -name = "fixedbitset" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279fb028e20b3c4c320317955b77c5e0c9701f05a1d309905d6fc702cdc5053e" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "futures-channel" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" -dependencies = [ - "futures-core", -] - -[[package]] -name = "futures-core" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" - -[[package]] -name = "futures-macro" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" - -[[package]] -name = "futures-task" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" - -[[package]] -name = "futures-util" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" -dependencies = [ - "futures-core", - "futures-macro", - "futures-task", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "getrandom" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.10.2+wasi-snapshot-preview1", -] - -[[package]] -name = "h2" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "heck" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "http" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff8670570af52249509a86f5e3e18a08c60b177071826898fde8997cf5f6bfbb" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "http-range-header" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" - -[[package]] -name = "httparse" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" - -[[package]] -name = "httpdate" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" - -[[package]] -name = "hyper" -version = "0.14.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-timeout" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" -dependencies = [ - "hyper", - "pin-project-lite", - "tokio", - "tokio-io-timeout", -] - -[[package]] -name = "indexmap" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a" -dependencies = [ - "autocfg", - "hashbrown", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "itertools" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" - -[[package]] -name = "lock_api" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "matchit" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "mio" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799" -dependencies = [ - "libc", - "log", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", -] - -[[package]] -name = "multimap" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" - -[[package]] -name = "num_cpus" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-sys", -] - -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "petgraph" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" -dependencies = [ - "fixedbitset", - "indexmap", -] - -[[package]] -name = "pin-project" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "ppv-lite86" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" - -[[package]] -name = "prettyplease" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28f53e8b192565862cf99343194579a022eb9c7dd3a8d03134734803c7b3125" -dependencies = [ - "proc-macro2", - "syn", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prost" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-build" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae5a4388762d5815a9fc0dea33c56b021cdc8dde0c55e0c9ca57197254b0cab" -dependencies = [ - "bytes", - "cfg-if", - "cmake", - "heck 0.4.0", - "itertools", - "lazy_static", - "log", - "multimap", - "petgraph", - "prost", - "prost-types", - "regex", - "tempfile", - "which", -] - -[[package]] -name = "prost-derive" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "prost-types" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d0a014229361011dc8e69c8a1ec6c2e8d0f2af7c91e3ea3f5b2170298461e68" -dependencies = [ - "bytes", - "prost", -] - -[[package]] -name = "quote" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "redox_syscall" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" -dependencies = [ - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "serde" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" - -[[package]] -name = "signal-hook-registry" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" -dependencies = [ - "libc", -] - -[[package]] -name = "skywalking" -version = "0.2.0" -dependencies = [ - "async-stream", - "base64", - "bytes", - "futures-core", - "futures-util", - "prost", - "prost-derive", - "thiserror", - "tokio", - "tonic", - "tonic-build", - "tracing", - "uuid", -] - -[[package]] -name = "slab" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" - -[[package]] -name = "smallvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" - -[[package]] -name = "socket2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "structopt" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" -dependencies = [ - "clap", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck 0.3.3", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "syn" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8" - -[[package]] -name = "tempfile" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "thiserror" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio" -version = "1.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4903bf0427cf68dddd5aa6a93220756f8be0c34fcfa9f5e6191e103e15a31395" -dependencies = [ - "bytes", - "libc", - "memchr", - "mio", - "num_cpus", - "once_cell", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "winapi", -] - -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-macros" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio-stream" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f988a1a1adc2fb21f9c12aa96441da33a1728193ae0b95d2be22dbd17fcb4e5c" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - -[[package]] -name = "tonic" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be9d60db39854b30b835107500cf0aca0b0d14d6e1c3de124217c23a29c2ddb" -dependencies = [ - "async-stream", - "async-trait", - "axum", - "base64", - "bytes", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost", - "prost-derive", - "tokio", - "tokio-stream", - "tokio-util", - "tower", - "tower-layer", - "tower-service", - "tracing", - "tracing-futures", -] - -[[package]] -name = "tonic-build" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9263bf4c9bfaae7317c1c2faf7f18491d2fe476f70c414b73bf5d445b00ffa1" -dependencies = [ - "prettyplease", - "proc-macro2", - "prost-build", - "quote", - "syn", -] - -[[package]] -name = "tower" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a89fd63ad6adf737582df5db40d286574513c69a11dac5214dc3b5603d6713e" -dependencies = [ - "futures-core", - "futures-util", - "indexmap", - "pin-project", - "pin-project-lite", - "rand", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-http" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d342c6d58709c0a6d48d48dabbb62d4ef955cf5f0f3bbfd845838e7ae88dbae" -dependencies = [ - "bitflags", - "bytes", - "futures-core", - "futures-util", - "http", - "http-body", - "http-range-header", - "pin-project-lite", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62" - -[[package]] -name = "tower-service" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" - -[[package]] -name = "tracing" -version = "0.1.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" -dependencies = [ - "cfg-if", - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7" -dependencies = [ - "once_cell", -] - -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project", - "tracing", -] - -[[package]] -name = "try-lock" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" - -[[package]] -name = "unicode-ident" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" - -[[package]] -name = "unicode-segmentation" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" - -[[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - -[[package]] -name = "uuid" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93bbc61e655a4833cf400d0d15bf3649313422fa7572886ad6dab16d79886365" -dependencies = [ - "getrandom", - "serde", -] - -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "want" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -dependencies = [ - "log", - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "which" -version = "4.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" -dependencies = [ - "either", - "lazy_static", - "libc", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" -dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - -[[package]] -name = "windows_i686_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - -[[package]] -name = "windows_i686_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" diff --git a/e2e/Cargo.toml b/e2e/Cargo.toml index 8ffc6e4..f3f65e4 100644 --- a/e2e/Cargo.toml +++ b/e2e/Cargo.toml @@ -21,6 +21,7 @@ version = "0.2.0" authors = ["Shikugawa "] edition = "2021" publish = false +license = "Apache-2.0" [dependencies] skywalking = { path = ".." } diff --git a/e2e/docker/Dockerfile b/e2e/docker/Dockerfile index 43c1cec..7b7c6c6 100644 --- a/e2e/docker/Dockerfile +++ b/e2e/docker/Dockerfile @@ -16,8 +16,8 @@ # under the License. # FROM rust:1.57 +RUN apt-get update && apt-get install -y cmake WORKDIR /build COPY . /build/ -RUN apt-get update && apt-get install -y cmake -RUN cd e2e && cargo build --release --locked -ENTRYPOINT ["/build/e2e/target/release/e2e"] +RUN cargo build --release --workspace +ENTRYPOINT ["/build/target/release/e2e"] From 19cfb94df268b29e2b2046bc4b470fe5dfb77175 Mon Sep 17 00:00:00 2001 From: jmjoy <918734043@qq.com> Date: Mon, 11 Jul 2022 22:23:41 +0800 Subject: [PATCH 02/12] Update authors. --- Cargo.toml | 2 +- e2e/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7f55728..3314008 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ members = [ [package] name = "skywalking" version = "0.2.0" -authors = ["Apache SkyWalking Developers (dev@skywalking.apache.org)"] +authors = ["Apache Software Foundation"] edition = "2021" description = "Apache SkyWalking Rust Agent" license = "Apache-2.0" diff --git a/e2e/Cargo.toml b/e2e/Cargo.toml index f3f65e4..9d523b4 100644 --- a/e2e/Cargo.toml +++ b/e2e/Cargo.toml @@ -18,7 +18,7 @@ [package] name = "e2e" version = "0.2.0" -authors = ["Shikugawa "] +authors = ["Apache Software Foundation"] edition = "2021" publish = false license = "Apache-2.0" From 4391d6bb0fbff50f344834a3f2bc8ba86530c454 Mon Sep 17 00:00:00 2001 From: jmjoy <918734043@qq.com> Date: Tue, 12 Jul 2022 23:10:57 +0800 Subject: [PATCH 03/12] Using weak. --- Cargo.toml | 1 + src/common/mod.rs | 1 - src/common/time.rs | 20 --- src/context/mod.rs | 1 + src/context/system_time.rs | 33 +++-- src/context/trace_context.rs | 253 ++++++++++++++++++++++++----------- src/context/tracer.rs | 128 +++++++++++++----- src/reporter/grpc.rs | 9 +- src/reporter/mod.rs | 9 +- tests/propagation.rs | 2 +- tests/trace_context.rs | 6 +- 11 files changed, 301 insertions(+), 162 deletions(-) delete mode 100644 src/common/time.rs diff --git a/Cargo.toml b/Cargo.toml index 3314008..3107eb9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,7 @@ repository = "https://github.com/apache/skywalking-rust" async-stream = "0.3.3" base64 = "0.13.0" bytes = "1.1.0" +cfg-if = "1.0.0" futures-core = "0.3.21" futures-util = "0.3.21" prost = "0.10.4" diff --git a/src/common/mod.rs b/src/common/mod.rs index cd8c341..7bb6d17 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -15,4 +15,3 @@ // pub mod random_generator; -pub mod time; diff --git a/src/common/time.rs b/src/common/time.rs deleted file mode 100644 index 8c28600..0000000 --- a/src/common/time.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one or more -// contributor license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright ownership. -// The ASF licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -pub trait TimeFetcher { - // Get current UNIX timestamp with sec resolution. - fn get(&self) -> i64; -} diff --git a/src/context/mod.rs b/src/context/mod.rs index 99ddb08..19bc6a1 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -15,6 +15,7 @@ // pub mod propagation; +#[doc(hidden)] pub mod system_time; pub mod trace_context; pub mod tracer; diff --git a/src/context/system_time.rs b/src/context/system_time.rs index c5e29cc..3bb72f7 100644 --- a/src/context/system_time.rs +++ b/src/context/system_time.rs @@ -14,17 +14,30 @@ // limitations under the License. // -use crate::common::time::TimeFetcher; -use std::time::{SystemTime, UNIX_EPOCH}; +use cfg_if::cfg_if; -#[derive(Default)] -pub struct UnixTimeStampFetcher {} +pub enum TimePeriod { + Start, + Log, + End, +} -impl TimeFetcher for UnixTimeStampFetcher { - fn get(&self) -> i64 { - SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_millis() as i64 +cfg_if! { + if #[cfg(test)] { + pub fn fetch_time(period: TimePeriod) -> i64 { + match period { + TimePeriod::Start => 1, + TimePeriod::Log => 10, + TimePeriod::End => 100, + } + } + } else { + pub fn fetch_time(_period: TimePeriod) -> i64 { + use std::time::{SystemTime, UNIX_EPOCH}; + SystemTime::now() + .duration_since(UNIX_EPOCH) + .map(|dur| dur.as_millis() as i64) + .unwrap_or_default() + } } } diff --git a/src/context/trace_context.rs b/src/context/trace_context.rs index 0934519..21d6db6 100644 --- a/src/context/trace_context.rs +++ b/src/context/trace_context.rs @@ -14,19 +14,21 @@ // limitations under the License. // +use super::system_time::{fetch_time, TimePeriod}; use crate::common::random_generator::RandomGenerator; -use crate::common::time::TimeFetcher; use crate::context::propagation::context::PropagationContext; use crate::skywalking_proto::v3::{ KeyStringValuePair, Log, RefType, SegmentObject, SegmentReference, SpanLayer, SpanObject, SpanType, }; +use std::borrow::Borrow; +use std::cell::RefCell; use std::collections::LinkedList; use std::fmt::Formatter; +use std::ops::Deref; +use std::rc::{Rc, Weak}; use std::sync::Arc; -use super::system_time::UnixTimeStampFetcher; - /// Span is a concept that represents trace information for a single RPC. /// The Rust SDK supports Entry Span to represent inbound to a service /// and Exit Span to represent outbound from a service. @@ -58,9 +60,9 @@ use super::system_time::UnixTimeStampFetcher; /// } /// } /// ``` +#[derive(Clone)] pub struct Span { - span_internal: SpanObject, - time_fetcher: Arc, + span_internal: Rc>, } impl std::fmt::Debug for Span { @@ -83,12 +85,11 @@ impl Span { span_type: SpanType, span_layer: SpanLayer, skip_analysis: bool, - time_fetcher: Arc, ) -> Self { let span_internal = SpanObject { span_id, parent_span_id, - start_time: time_fetcher.get(), + start_time: fetch_time(TimePeriod::Start), end_time: 0, // not set refs: Vec::::new(), operation_name, @@ -103,28 +104,36 @@ impl Span { }; Span { - span_internal, - time_fetcher, + span_internal: Rc::new(RefCell::new(span_internal)), } } /// Close span. It only registers end time to the span. pub fn close(&mut self) { - self.span_internal.end_time = self.time_fetcher.get(); + self.with_span_object_mut(|span| span.end_time = fetch_time(TimePeriod::End)); + } + + pub fn with_span_object(&self, f: impl FnOnce(&SpanObject) -> T) -> T { + f(&self.span_internal.deref().borrow()) } - pub fn span_object(&self) -> &SpanObject { - &self.span_internal + pub fn with_span_object_mut(&mut self, f: impl FnOnce(&mut SpanObject) -> T) -> T { + f(&mut self.span_internal.deref().borrow_mut()) } - pub fn span_object_mut(&mut self) -> &mut SpanObject { - &mut self.span_internal + pub fn span_id(&self) -> i32 { + self.with_span_object(|span| span.span_id) } /// Add logs to the span. - pub fn add_log(&mut self, message: Vec<(&str, &str)>) { + pub fn add_log(&mut self, message: I) + where + K: ToString, + V: ToString, + I: IntoIterator, + { let log = Log { - time: self.time_fetcher.get(), + time: fetch_time(TimePeriod::Log), data: message .into_iter() .map(|v| { @@ -136,33 +145,61 @@ impl Span { }) .collect(), }; - self.span_internal.logs.push(log); + self.with_span_object_mut(|span| span.logs.push(log)); } /// Add tag to the span. pub fn add_tag(&mut self, tag: (&str, &str)) { let (key, value) = tag; - self.span_internal.tags.push(KeyStringValuePair { - key: key.to_string(), - value: value.to_string(), - }); + self.with_span_object_mut(|span| { + span.tags.push(KeyStringValuePair { + key: key.to_string(), + value: value.to_string(), + }) + }) } fn add_segment_reference(&mut self, segment_reference: SegmentReference) { - self.span_internal.refs.push(segment_reference); + self.with_span_object_mut(|span| span.refs.push(segment_reference)); + } + + fn downgrade(&self) -> WeakSpan { + WeakSpan { + span_internal: Rc::downgrade(&self.span_internal), + } } } +pub(crate) struct WeakSpan { + span_internal: Weak>, +} + +impl WeakSpan { + pub fn span_id(&self) -> Option { + self.upgrade().map(|span| span.span_id()) + } + + fn upgrade(&self) -> Option { + self.span_internal + .upgrade() + .map(|span_internal| Span { span_internal }) + } +} + +struct Inner { + +} + pub struct TracingContext { pub trace_id: String, pub trace_segment_id: String, pub service: String, pub service_instance: String, pub next_span_id: i32, - pub spans: Vec>, - time_fetcher: Arc, + pub spans: Vec, segment_link: Option, - active_span_id_stack: LinkedList, + active_span_stack: LinkedList, + primary_endpoint_name: String, } impl std::fmt::Debug for TracingContext { @@ -181,26 +218,17 @@ impl std::fmt::Debug for TracingContext { impl TracingContext { /// Generate a new trace context. Typically called when no context has /// been propagated and a new trace is to be started. - pub fn default(service_name: &str, instance_name: &str) -> Self { - let unix_time_fetcher = UnixTimeStampFetcher {}; - TracingContext::default_internal(Arc::new(unix_time_fetcher), service_name, instance_name) - } - - pub fn default_internal( - time_fetcher: Arc, - service_name: &str, - instance_name: &str, - ) -> Self { + pub fn new(service_name: impl ToString, instance_name: impl ToString) -> Self { TracingContext { trace_id: RandomGenerator::generate(), trace_segment_id: RandomGenerator::generate(), - service: String::from(service_name), - service_instance: String::from(instance_name), + service: service_name.to_string(), + service_instance: instance_name.to_string(), next_span_id: 0, - time_fetcher, spans: Vec::new(), segment_link: None, - active_span_id_stack: LinkedList::new(), + active_span_stack: LinkedList::new(), + primary_endpoint_name: Default::default(), } } @@ -208,23 +236,8 @@ impl TracingContext { /// They should be propagated on `sw8` header in HTTP request with encoded form. /// You can retrieve decoded context with `skywalking::context::propagation::encoder::encode_propagation` pub fn from_propagation_context( - service_name: &str, - instance_name: &str, - context: PropagationContext, - ) -> Self { - let unix_time_fetcher = UnixTimeStampFetcher {}; - TracingContext::from_propagation_context_internal( - Arc::new(unix_time_fetcher), - service_name, - instance_name, - context, - ) - } - - pub fn from_propagation_context_internal( - time_fetcher: Arc, - service_name: &str, - instance_name: &str, + service_name: impl ToString, + instance_name: impl ToString, context: PropagationContext, ) -> Self { TracingContext { @@ -233,10 +246,10 @@ impl TracingContext { service: service_name.to_string(), service_instance: instance_name.to_string(), next_span_id: 0, - time_fetcher, spans: Vec::new(), segment_link: Some(context), - active_span_id_stack: LinkedList::new(), + active_span_stack: LinkedList::new(), + primary_endpoint_name: Default::default(), } } @@ -251,7 +264,7 @@ impl TracingContext { ) -> crate::Result<()> { match self.create_entry_span(operation_name) { Ok(mut span) => { - process_fn(span.as_ref()); + process_fn(&span); span.close(); Ok(()) } @@ -262,14 +275,14 @@ impl TracingContext { /// Create a new entry span, which is an initiator of collection of spans. /// This should be called by invocation of the function which is triggered by /// external service. - pub fn create_entry_span(&mut self, operation_name: &str) -> crate::Result> { + pub fn create_entry_span(&mut self, operation_name: &str) -> crate::Result { if self.next_span_id >= 1 { return Err(crate::Error::CreateSpan("entry span have already exist.")); } let parent_span_id = self.peek_active_span_id().unwrap_or(-1); - let mut span = Box::new(Span::new( + let mut span = Span::new( self.next_span_id, parent_span_id, operation_name.to_string(), @@ -277,8 +290,7 @@ impl TracingContext { SpanType::Entry, SpanLayer::Http, false, - self.time_fetcher.clone(), - )); + ); if self.segment_link.is_some() { span.add_segment_reference(SegmentReference { @@ -313,8 +325,7 @@ impl TracingContext { }); } self.next_span_id += 1; - self.active_span_id_stack - .push_back(span.span_internal.span_id); + self.push_active_span(&span); Ok(span) } @@ -330,7 +341,7 @@ impl TracingContext { ) -> crate::Result<()> { match self.create_exit_span(operation_name, remote_peer) { Ok(mut span) => { - process_fn(span.as_ref()); + process_fn(&span); span.close(); Ok(()) } @@ -345,14 +356,14 @@ impl TracingContext { &mut self, operation_name: &str, remote_peer: &str, - ) -> crate::Result> { + ) -> crate::Result { if self.next_span_id == 0 { return Err(crate::Error::CreateSpan("entry span must be existed.")); } let parent_span_id = self.peek_active_span_id().unwrap_or(-1); - let span = Box::new(Span::new( + let span = Span::new( self.next_span_id, parent_span_id, operation_name.to_string(), @@ -360,28 +371,49 @@ impl TracingContext { SpanType::Exit, SpanLayer::Http, false, - self.time_fetcher.clone(), - )); + ); + self.next_span_id += 1; + self.push_active_span(&span); + Ok(span) + } + + // Create a new local span. + pub fn create_local_span(&mut self, operation_name: &str) -> crate::Result { + if self.next_span_id == 0 { + return Err(crate::Error::CreateSpan("entry span must be existed.")); + } + + let parent_span_id = self.peek_active_span_id().unwrap_or(-1); + + let span = Span::new( + self.next_span_id, + parent_span_id, + operation_name.to_string(), + Default::default(), + SpanType::Local, + SpanLayer::Unknown, + false, + ); self.next_span_id += 1; - self.active_span_id_stack - .push_back(span.span_internal.span_id); + self.push_active_span(&span); Ok(span) } /// Close span. We can't use closed span after finalize called. - pub fn finalize_span(&mut self, mut span: Box) { + pub fn finalize_span(&mut self, mut span: Span) { span.close(); self.spans.push(span); - self.active_span_id_stack.pop_back(); + self.pop_active_span(); } /// It converts tracing context into segment object. /// This conversion should be done before sending segments into OAP. - pub fn convert_segment_object(&self) -> SegmentObject { - let mut objects = Vec::::new(); + pub fn convert_segment_object(self) -> SegmentObject { + let mut objects = Vec::::with_capacity(self.spans.len()); - for span in self.spans.iter() { - objects.push(span.span_internal.clone()); + for span in self.spans { + let span = Rc::try_unwrap(span.span_internal).unwrap(); + objects.push(span.into_inner()); } SegmentObject { @@ -394,7 +426,70 @@ impl TracingContext { } } + pub fn capture(&self) -> ContextSnapshot { + ContextSnapshot { + trace_id: self.trace_id.clone(), + trace_segment_id: self.trace_segment_id.clone(), + span_id: self.peek_active_span_id().unwrap_or(-1), + parent_endpoint: self.primary_endpoint_name.clone(), + } + } + + pub fn continued(&mut self, snapshot: ContextSnapshot) { + if snapshot.is_valid() { + let segment_ref = SegmentReference { + ref_type: RefType::CrossThread as i32, + trace_id: snapshot.trace_id, + parent_trace_segment_id: snapshot.trace_segment_id, + parent_span_id: snapshot.span_id, + parent_service: todo!(), + parent_service_instance: todo!(), + parent_endpoint: snapshot.parent_endpoint, + network_address_used_at_peer: Default::default(), + }; + let mut span = self.peek_active_span().unwrap().upgrade().unwrap(); + span.add_segment_reference(segment_ref); + // TraceSegmentRef segmentRef = new TraceSegmentRef(snapshot); + // this.segment.ref(segmentRef); + // this.activeSpan().ref(segmentRef); + // this.segment.relatedGlobalTrace(snapshot.getTraceId()); + // this.correlationContext.continued(snapshot); + // this.extensionContext.continued(snapshot); + // this.extensionContext.handle(this.activeSpan()); + } + } + pub(crate) fn peek_active_span_id(&self) -> Option { - self.active_span_id_stack.back().copied() + self.peek_active_span().map(|span| span.span_id().unwrap()) + } + + pub(crate) fn peek_active_span(&self) -> Option<&WeakSpan> { + self.active_span_stack.back() + } + + fn push_active_span(&mut self, span: &Span) { + self.primary_endpoint_name = span.with_span_object(|span| span.operation_name.clone()); + self.active_span_stack.push_back(span.downgrade()); + } + + fn pop_active_span(&mut self) { + self.active_span_stack.pop_back(); + } +} + +pub struct ContextSnapshot { + trace_id: String, + trace_segment_id: String, + span_id: i32, + parent_endpoint: String, +} + +impl ContextSnapshot { + pub fn is_from_current(&self, context: &TracingContext) -> bool { + !self.trace_segment_id.is_empty() && self.trace_segment_id == context.trace_segment_id + } + + pub fn is_valid(&self) -> bool { + !self.trace_segment_id.is_empty() && self.span_id > -1 && !self.trace_id.is_empty() } } diff --git a/src/context/tracer.rs b/src/context/tracer.rs index 7ca4bd1..fa47526 100644 --- a/src/context/tracer.rs +++ b/src/context/tracer.rs @@ -16,11 +16,13 @@ use super::propagation::context::PropagationContext; use crate::{ - context::trace_context::TracingContext, reporter::Reporter, skywalking_proto::v3::SegmentObject, + context::trace_context::TracingContext, reporter::DynReporter, reporter::Reporter, + skywalking_proto::v3::SegmentObject, }; -use futures_util::stream; use std::future::Future; +use std::sync::Weak; use std::{collections::LinkedList, sync::Arc}; +use tokio::sync::OnceCell; use tokio::{ sync::{ mpsc::{self, UnboundedReceiver}, @@ -29,32 +31,75 @@ use tokio::{ task::JoinHandle, }; -/// Skywalking tracer. -pub struct Tracer { +static GLOBAL_TRACER: OnceCell = OnceCell::const_new(); + +pub fn set_global_tracer(tracer: Tracer) { + if GLOBAL_TRACER.set(tracer).is_err() { + panic!("global tracer has setted") + } +} + +pub fn global_tracer() -> &'static Tracer { + GLOBAL_TRACER.get().expect("global tracer haven't setted") +} + +/// Create trace conetxt. +pub fn create_trace_context() -> TracingContext { + global_tracer().create_trace_context() +} + +/// Create trace conetxt from propagation. +pub fn create_trace_context_from_propagation(context: PropagationContext) -> TracingContext { + global_tracer().create_trace_context_from_propagation(context) +} + +pub fn finalize_context(context: TracingContext) { + global_tracer().finalize_context(context) +} + +pub fn reporting( + shutdown_signal: impl Future + Send + Sync + 'static, +) -> JoinHandle<()> { + global_tracer().reporting(shutdown_signal) +} + +struct Inner { service_name: String, instance_name: String, - reporter: Arc>, segment_sender: mpsc::UnboundedSender, - segment_receiver: Arc>>, + segment_receiver: Mutex>, + reporter: Box>, +} + +/// Skywalking tracer. +#[derive(Clone)] +pub struct Tracer { + inner: Arc, } -impl Tracer { +impl Tracer { /// New with service info and reporter. - pub fn new(service_name: impl ToString, instance_name: impl ToString, reporter: R) -> Self { + pub fn new( + service_name: impl ToString, + instance_name: impl ToString, + reporter: impl Reporter + Send + Sync + 'static, + ) -> Self { let (segment_sender, segment_receiver) = mpsc::unbounded_channel(); Self { - service_name: service_name.to_string(), - instance_name: instance_name.to_string(), - reporter: Arc::new(Mutex::new(reporter)), - segment_sender, - segment_receiver: Arc::new(Mutex::new(segment_receiver)), + inner: Arc::new(Inner { + service_name: service_name.to_string(), + instance_name: instance_name.to_string(), + segment_sender, + segment_receiver: Mutex::new(segment_receiver), + reporter: Box::new(Mutex::new(reporter)), + }), } } /// Create trace conetxt. pub fn create_trace_context(&self) -> TracingContext { - TracingContext::default(&self.service_name, &self.instance_name) + TracingContext::new(&self.inner.service_name, &self.inner.instance_name) } /// Create trace conetxt from propagation. @@ -62,13 +107,17 @@ impl Tracer { &self, context: PropagationContext, ) -> TracingContext { - TracingContext::from_propagation_context(&self.service_name, &self.instance_name, context) + TracingContext::from_propagation_context( + &self.inner.service_name, + &self.inner.instance_name, + context, + ) } /// Finalize the trace context. pub fn finalize_context(&self, context: TracingContext) { let segment_object = context.convert_segment_object(); - if self.segment_sender.send(segment_object).is_err() { + if self.inner.segment_sender.send(segment_object).is_err() { tracing::warn!("segment object channel has closed"); } } @@ -80,25 +129,15 @@ impl Tracer { &self, shutdown_signal: impl Future + Send + Sync + 'static, ) -> JoinHandle<()> { - let reporter = self.reporter.clone(); - let segment_receiver = self.segment_receiver.clone(); - tokio::spawn(Self::do_reporting( - reporter, - segment_receiver, - shutdown_signal, - )) + tokio::spawn(Self::do_reporting(self.clone(), shutdown_signal)) } - async fn do_reporting( - reporter: Arc>, - segment_receiver: Arc>>, - shutdown_signal: impl Future + Send + Sync + 'static, - ) { + async fn do_reporting(self, shutdown_signal: impl Future + Send + Sync + 'static) { let (shutdown_tx, mut shutdown_rx) = mpsc::unbounded_channel(); let handle = tokio::spawn(async move { loop { - let mut segment_receiver = segment_receiver.lock().await; + let mut segment_receiver = self.inner.segment_receiver.lock().await; let mut segments = LinkedList::new(); tokio::select! { @@ -108,8 +147,7 @@ impl Tracer { if let Some(segment) = segment { // TODO Implement batch collect in future. segments.push_back(segment); - let mut reporter = reporter.lock().await; - Self::report_segment_object(&mut reporter, segments).await; + Self::report_segment_object(&self.inner.reporter, segments).await; } else { break; } @@ -119,13 +157,12 @@ impl Tracer { } // Flush. - let mut segment_receiver = segment_receiver.lock().await; + let mut segment_receiver = self.inner.segment_receiver.lock().await; let mut segments = LinkedList::new(); while let Ok(segment) = segment_receiver.try_recv() { segments.push_back(segment); } - let mut reporter = reporter.lock().await; - Self::report_segment_object(&mut reporter, segments).await; + Self::report_segment_object(&self.inner.reporter, segments).await; }); shutdown_signal.await; @@ -138,10 +175,27 @@ impl Tracer { } } - async fn report_segment_object(reporter: &mut R, segments: LinkedList) { - let stream = stream::iter(segments); - if let Err(e) = reporter.collect(stream).await { + async fn report_segment_object( + reporter: &Mutex, + segments: LinkedList, + ) { + if let Err(e) = reporter.lock().await.collect(segments).await { tracing::error!("Collect failed: {:?}", e); } } + + fn downgrade(&self) -> WeakTracer { + WeakTracer { inner: Arc::downgrade(&self.inner) } + } +} + +#[derive(Clone)] +struct WeakTracer { + inner: Weak, +} + +impl WeakTracer { + fn upgrade(&self) -> Option { + Weak::upgrade(&self.inner).map(|inner| Tracer { inner }) + } } diff --git a/src/reporter/grpc.rs b/src/reporter/grpc.rs index 499ccf5..afdd2d2 100644 --- a/src/reporter/grpc.rs +++ b/src/reporter/grpc.rs @@ -18,7 +18,8 @@ use super::Reporter; use crate::skywalking_proto::v3::{ trace_segment_report_service_client::TraceSegmentReportServiceClient, SegmentObject, }; -use futures_core::Stream; +use futures_util::stream; +use std::collections::LinkedList; use tonic::{ async_trait, transport::{self, Channel, Endpoint}, @@ -46,10 +47,8 @@ impl GrpcReporter { #[async_trait] impl Reporter for GrpcReporter { - async fn collect( - &mut self, - stream: impl Stream + Send + 'static, - ) -> crate::Result<()> { + async fn collect(&mut self, segments: LinkedList) -> crate::Result<()> { + let stream = stream::iter(segments); self.client.collect(stream).await?; Ok(()) } diff --git a/src/reporter/mod.rs b/src/reporter/mod.rs index 1261020..0fc54c1 100644 --- a/src/reporter/mod.rs +++ b/src/reporter/mod.rs @@ -17,13 +17,12 @@ pub mod grpc; use crate::skywalking_proto::v3::SegmentObject; -use futures_core::Stream; +use std::collections::LinkedList; use tonic::async_trait; +pub(crate) type DynReporter = dyn Reporter + Send + Sync + 'static; + #[async_trait] pub trait Reporter { - async fn collect( - &mut self, - stream: impl Stream + Send + 'static, - ) -> crate::Result<()>; + async fn collect(&mut self, stream: LinkedList) -> crate::Result<()>; } diff --git a/tests/propagation.rs b/tests/propagation.rs index 52e5435..39eca87 100644 --- a/tests/propagation.rs +++ b/tests/propagation.rs @@ -72,7 +72,7 @@ fn invalid_sample() { #[test] fn basic_encode() { let time_fetcher = MockTimeFetcher {}; - let tc = TracingContext::default_internal(Arc::new(time_fetcher), "mesh", "instance"); + let tc = TracingContext::new(Arc::new(time_fetcher), "mesh", "instance"); let res = encode_propagation(&tc, "/api/v1/health", "example.com:8080"); let res2 = decode_propagation(&res).unwrap(); assert!(res2.do_sample); diff --git a/tests/trace_context.rs b/tests/trace_context.rs index f50dff6..fbd0f10 100644 --- a/tests/trace_context.rs +++ b/tests/trace_context.rs @@ -53,8 +53,7 @@ impl TimeFetcher for MockTimeFetcher { #[test] fn create_span() { let time_fetcher = MockTimeFetcher {}; - let mut context = - TracingContext::default_internal(Arc::new(time_fetcher), "service", "instance"); + let mut context = TracingContext::new(Arc::new(time_fetcher), "service", "instance"); assert_eq!(context.service, "service"); assert_eq!(context.service_instance, "instance"); @@ -201,8 +200,7 @@ fn create_span_from_context() { #[test] fn crossprocess_test() { let time_fetcher1 = MockTimeFetcher {}; - let mut context1 = - TracingContext::default_internal(Arc::new(time_fetcher1), "service", "instance"); + let mut context1 = TracingContext::new(Arc::new(time_fetcher1), "service", "instance"); assert_eq!(context1.service, "service"); assert_eq!(context1.service_instance, "instance"); From 397ccf226c7f09c9a38ed97b65c326841b509f4d Mon Sep 17 00:00:00 2001 From: jmjoy <918734043@qq.com> Date: Wed, 13 Jul 2022 00:25:35 +0800 Subject: [PATCH 04/12] Pass trace context. --- src/context/propagation/encoder.rs | 8 +- src/context/trace_context.rs | 287 ++++++++++++++++++----------- src/context/tracer.rs | 23 ++- 3 files changed, 200 insertions(+), 118 deletions(-) diff --git a/src/context/propagation/encoder.rs b/src/context/propagation/encoder.rs index c018e77..431b7a8 100644 --- a/src/context/propagation/encoder.rs +++ b/src/context/propagation/encoder.rs @@ -23,11 +23,11 @@ pub fn encode_propagation(context: &TracingContext, endpoint: &str, address: &st let mut res = String::new(); res += "1-"; - res += format!("{}-", encode(context.trace_id.to_string())).as_str(); - res += format!("{}-", encode(context.trace_segment_id.to_string())).as_str(); + res += format!("{}-", encode(context.trace_id())).as_str(); + res += format!("{}-", encode(context.trace_segment_id())).as_str(); res += format!("{}-", context.peek_active_span_id().unwrap_or(0)).as_str(); - res += format!("{}-", encode(context.service.as_str())).as_str(); - res += format!("{}-", encode(context.service_instance.as_str())).as_str(); + res += format!("{}-", encode(context.service())).as_str(); + res += format!("{}-", encode(context.service_instance())).as_str(); res += format!("{}-", encode(endpoint)).as_str(); res += &encode(address); res diff --git a/src/context/trace_context.rs b/src/context/trace_context.rs index 21d6db6..7fea710 100644 --- a/src/context/trace_context.rs +++ b/src/context/trace_context.rs @@ -15,6 +15,7 @@ // use super::system_time::{fetch_time, TimePeriod}; +use super::tracer::WeakTracer; use crate::common::random_generator::RandomGenerator; use crate::context::propagation::context::PropagationContext; use crate::skywalking_proto::v3::{ @@ -22,7 +23,7 @@ use crate::skywalking_proto::v3::{ SpanType, }; use std::borrow::Borrow; -use std::cell::RefCell; +use std::cell::{RefCell, Cell}; use std::collections::LinkedList; use std::fmt::Formatter; use std::ops::Deref; @@ -163,46 +164,46 @@ impl Span { self.with_span_object_mut(|span| span.refs.push(segment_reference)); } - fn downgrade(&self) -> WeakSpan { - WeakSpan { - span_internal: Rc::downgrade(&self.span_internal), - } + fn unwrap_inner(self) -> SpanObject { + Rc::try_unwrap(self.span_internal).unwrap().into_inner() } -} -pub(crate) struct WeakSpan { - span_internal: Weak>, + // fn downgrade(&self) -> WeakSpan { + // WeakSpan { + // span_internal: Rc::downgrade(&self.span_internal), + // } + // } } -impl WeakSpan { - pub fn span_id(&self) -> Option { - self.upgrade().map(|span| span.span_id()) - } +// pub(crate) struct WeakSpan { +// span_internal: Weak>, +// } - fn upgrade(&self) -> Option { - self.span_internal - .upgrade() - .map(|span_internal| Span { span_internal }) - } -} +// impl WeakSpan { +// pub fn span_id(&self) -> Option { +// self.upgrade().map(|span| span.span_id()) +// } -struct Inner { +// fn upgrade(&self) -> Option { +// self.span_internal +// .upgrade() +// .map(|span_internal| Span { span_internal }) +// } +// } -} - -pub struct TracingContext { - pub trace_id: String, - pub trace_segment_id: String, - pub service: String, - pub service_instance: String, - pub next_span_id: i32, - pub spans: Vec, +struct Inner { + trace_id: String, + trace_segment_id: String, + service: String, + service_instance: String, + next_span_id: Cell, + spans: RefCell>, segment_link: Option, - active_span_stack: LinkedList, - primary_endpoint_name: String, + active_span_stack: RefCell>, + primary_endpoint_name: RefCell, } -impl std::fmt::Debug for TracingContext { +impl std::fmt::Debug for Inner { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("TracingContext") .field("trace_id", &self.trace_id) @@ -215,43 +216,119 @@ impl std::fmt::Debug for TracingContext { } } +#[derive(Clone)] +pub struct TracingContext { + inner: Rc, + tracer: WeakTracer, +} + +impl std::fmt::Debug for TracingContext { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +std::fmt::Debug::fmt(&self.inner,f) + } +} + impl TracingContext { /// Generate a new trace context. Typically called when no context has /// been propagated and a new trace is to be started. - pub fn new(service_name: impl ToString, instance_name: impl ToString) -> Self { + pub(crate) fn new( + service_name: impl ToString, + instance_name: impl ToString, + tracer: WeakTracer, + ) -> Self { TracingContext { - trace_id: RandomGenerator::generate(), - trace_segment_id: RandomGenerator::generate(), - service: service_name.to_string(), - service_instance: instance_name.to_string(), - next_span_id: 0, - spans: Vec::new(), - segment_link: None, - active_span_stack: LinkedList::new(), - primary_endpoint_name: Default::default(), + inner: Rc::new(Inner { + trace_id: RandomGenerator::generate(), + trace_segment_id: RandomGenerator::generate(), + service: service_name.to_string(), + service_instance: instance_name.to_string(), + next_span_id: Default::default(), + spans: Default::default(), + segment_link: None, + active_span_stack: Default::default(), + primary_endpoint_name: Default::default(), + }), + tracer, } } /// Generate a new trace context using the propagated context. /// They should be propagated on `sw8` header in HTTP request with encoded form. /// You can retrieve decoded context with `skywalking::context::propagation::encoder::encode_propagation` - pub fn from_propagation_context( + pub(crate) fn from_propagation_context( service_name: impl ToString, instance_name: impl ToString, context: PropagationContext, + tracer: WeakTracer, ) -> Self { TracingContext { - trace_id: context.parent_trace_id.clone(), - trace_segment_id: RandomGenerator::generate(), - service: service_name.to_string(), - service_instance: instance_name.to_string(), - next_span_id: 0, - spans: Vec::new(), - segment_link: Some(context), - active_span_stack: LinkedList::new(), - primary_endpoint_name: Default::default(), + inner: Rc::new(Inner { + trace_id: context.parent_trace_id.clone(), + trace_segment_id: RandomGenerator::generate(), + service: service_name.to_string(), + service_instance: instance_name.to_string(), + next_span_id: Default::default(), + spans: Default::default(), + segment_link: Some(context), + active_span_stack: Default::default(), + primary_endpoint_name: Default::default(), + }), + tracer, } } + + #[inline] + pub fn trace_id(&self) -> &str { + &self.inner.trace_id + } + + #[inline] + pub fn trace_segment_id(&self) -> &str { + &self.inner.trace_segment_id + } + + #[inline] + pub fn service(&self) -> &str { + &self.inner.service + } + + #[inline] + pub fn service_instance(&self) -> &str { + &self.inner.service_instance + } + + #[inline] + fn next_span_id(&self) -> i32 { + self.inner.next_span_id.get() + } + + fn inc_next_span_id(&self) { + self.inner.next_span_id.set(self.next_span_id() + 1) + } + + fn with_spans(&self, f: impl FnOnce(&Vec) -> T) -> T { + f(&self.inner.spans.borrow()) + } + + fn with_spans_mut(&mut self, f: impl FnOnce(&mut Vec) -> T) -> T { + f(&mut self.inner.spans.borrow_mut()) + } + + fn with_active_span_stack(&self, f: impl FnOnce(&LinkedList) -> T) -> T { + f(&self.inner.active_span_stack.borrow()) + } + + fn with_active_span_stack_mut(&mut self, f: impl FnOnce(&mut LinkedList) -> T) -> T { + f(&mut self.inner.active_span_stack.borrow_mut()) + } + + fn with_primary_endpoint_name(&self, f: impl FnOnce(&String) -> T) -> T { + f(&self.inner.primary_endpoint_name.borrow()) + } + + fn with_primary_endpoint_name_mut(&mut self, f: impl FnOnce(&mut String) -> T) -> T { + f(&mut self.inner.primary_endpoint_name.borrow_mut()) + } /// A wrapper of create entry span, which close generated span automatically. /// Note that, we may use async operation in closure. But that is not unstable feature in 2021/12. @@ -276,14 +353,14 @@ impl TracingContext { /// This should be called by invocation of the function which is triggered by /// external service. pub fn create_entry_span(&mut self, operation_name: &str) -> crate::Result { - if self.next_span_id >= 1 { + if self.next_span_id() >= 1 { return Err(crate::Error::CreateSpan("entry span have already exist.")); } let parent_span_id = self.peek_active_span_id().unwrap_or(-1); let mut span = Span::new( - self.next_span_id, + self.inner.next_span_id.get(), parent_span_id, operation_name.to_string(), String::default(), @@ -292,39 +369,19 @@ impl TracingContext { false, ); - if self.segment_link.is_some() { + if let Some(segment_link) = &self.inner.segment_link { span.add_segment_reference(SegmentReference { ref_type: RefType::CrossProcess as i32, - trace_id: self.trace_id.clone(), - parent_trace_segment_id: self - .segment_link - .as_ref() - .unwrap() - .parent_trace_segment_id - .clone(), - parent_span_id: self.segment_link.as_ref().unwrap().parent_span_id, - parent_service: self.segment_link.as_ref().unwrap().parent_service.clone(), - parent_service_instance: self - .segment_link - .as_ref() - .unwrap() - .parent_service_instance - .clone(), - parent_endpoint: self - .segment_link - .as_ref() - .unwrap() - .destination_endpoint - .clone(), - network_address_used_at_peer: self - .segment_link - .as_ref() - .unwrap() - .destination_address - .clone(), + trace_id: self.inner.trace_id.clone(), + parent_trace_segment_id: segment_link.parent_trace_segment_id.clone(), + parent_span_id: segment_link.parent_span_id, + parent_service: segment_link.parent_service.clone(), + parent_service_instance: segment_link.parent_service_instance.clone(), + parent_endpoint: segment_link.destination_endpoint.clone(), + network_address_used_at_peer: segment_link.destination_address.clone(), }); } - self.next_span_id += 1; + self.inc_next_span_id(); self.push_active_span(&span); Ok(span) } @@ -357,14 +414,14 @@ impl TracingContext { operation_name: &str, remote_peer: &str, ) -> crate::Result { - if self.next_span_id == 0 { + if self.next_span_id() == 0 { return Err(crate::Error::CreateSpan("entry span must be existed.")); } let parent_span_id = self.peek_active_span_id().unwrap_or(-1); let span = Span::new( - self.next_span_id, + self.inner.next_span_id.get(), parent_span_id, operation_name.to_string(), remote_peer.to_string(), @@ -372,21 +429,21 @@ impl TracingContext { SpanLayer::Http, false, ); - self.next_span_id += 1; + self.inc_next_span_id(); self.push_active_span(&span); Ok(span) } // Create a new local span. pub fn create_local_span(&mut self, operation_name: &str) -> crate::Result { - if self.next_span_id == 0 { + if self.next_span_id() == 0 { return Err(crate::Error::CreateSpan("entry span must be existed.")); } let parent_span_id = self.peek_active_span_id().unwrap_or(-1); let span = Span::new( - self.next_span_id, + self.inner.next_span_id.get(), parent_span_id, operation_name.to_string(), Default::default(), @@ -394,7 +451,7 @@ impl TracingContext { SpanLayer::Unknown, false, ); - self.next_span_id += 1; + self.inc_next_span_id(); self.push_active_span(&span); Ok(span) } @@ -402,52 +459,58 @@ impl TracingContext { /// Close span. We can't use closed span after finalize called. pub fn finalize_span(&mut self, mut span: Span) { span.close(); - self.spans.push(span); + self.with_spans_mut(|spans| spans.push(span)); self.pop_active_span(); } /// It converts tracing context into segment object. /// This conversion should be done before sending segments into OAP. pub fn convert_segment_object(self) -> SegmentObject { - let mut objects = Vec::::with_capacity(self.spans.len()); + let mut objects = Vec::with_capacity(self.with_spans(|spans| spans.len())); - for span in self.spans { - let span = Rc::try_unwrap(span.span_internal).unwrap(); - objects.push(span.into_inner()); + let trace_id = self.trace_id().to_owned(); + let trace_segment_id = self.trace_segment_id().to_owned(); + let service = self.service().to_owned(); + let service_instance = self.service_instance().to_owned(); + let inner = self.unwrap_inner(); + + for span in inner.spans.into_inner() { + objects.push(span.unwrap_inner()); } SegmentObject { - trace_id: self.trace_id.to_string(), - trace_segment_id: self.trace_segment_id.to_string(), + trace_id, + trace_segment_id, spans: objects, - service: self.service.clone(), - service_instance: self.service_instance.clone(), + service, + service_instance, is_size_limited: false, } } pub fn capture(&self) -> ContextSnapshot { ContextSnapshot { - trace_id: self.trace_id.clone(), - trace_segment_id: self.trace_segment_id.clone(), + trace_id: self.inner.trace_id.clone(), + trace_segment_id: self.inner.trace_segment_id.clone(), span_id: self.peek_active_span_id().unwrap_or(-1), - parent_endpoint: self.primary_endpoint_name.clone(), + parent_endpoint: self.with_primary_endpoint_name(|endpoint| endpoint.clone()), } } pub fn continued(&mut self, snapshot: ContextSnapshot) { if snapshot.is_valid() { + let tracer = self.tracer.upgrade().unwrap(); let segment_ref = SegmentReference { ref_type: RefType::CrossThread as i32, trace_id: snapshot.trace_id, parent_trace_segment_id: snapshot.trace_segment_id, parent_span_id: snapshot.span_id, - parent_service: todo!(), - parent_service_instance: todo!(), + parent_service: tracer.service_name().to_owned(), + parent_service_instance: tracer.instance_name().to_owned(), parent_endpoint: snapshot.parent_endpoint, network_address_used_at_peer: Default::default(), }; - let mut span = self.peek_active_span().unwrap().upgrade().unwrap(); + let mut span = self.peek_active_span().unwrap(); span.add_segment_reference(segment_ref); // TraceSegmentRef segmentRef = new TraceSegmentRef(snapshot); // this.segment.ref(segmentRef); @@ -460,20 +523,24 @@ impl TracingContext { } pub(crate) fn peek_active_span_id(&self) -> Option { - self.peek_active_span().map(|span| span.span_id().unwrap()) + self.peek_active_span().map(|span| span.span_id()) } - pub(crate) fn peek_active_span(&self) -> Option<&WeakSpan> { - self.active_span_stack.back() + pub(crate) fn peek_active_span(&self) -> Option { + self.with_active_span_stack(|stack| stack.back().cloned()) } fn push_active_span(&mut self, span: &Span) { - self.primary_endpoint_name = span.with_span_object(|span| span.operation_name.clone()); - self.active_span_stack.push_back(span.downgrade()); + self.with_primary_endpoint_name_mut(|endpoint| *endpoint = span.with_span_object(|span| span.operation_name.clone())); + self.with_active_span_stack_mut(|stack| stack.push_back(span.clone())); } fn pop_active_span(&mut self) { - self.active_span_stack.pop_back(); + self.with_active_span_stack_mut(|stack| stack.pop_back()); + } + + fn unwrap_inner(self) -> Inner { + Rc::try_unwrap(self.inner).unwrap() } } @@ -486,7 +553,7 @@ pub struct ContextSnapshot { impl ContextSnapshot { pub fn is_from_current(&self, context: &TracingContext) -> bool { - !self.trace_segment_id.is_empty() && self.trace_segment_id == context.trace_segment_id + !self.trace_segment_id.is_empty() && self.trace_segment_id == context.trace_segment_id() } pub fn is_valid(&self) -> bool { diff --git a/src/context/tracer.rs b/src/context/tracer.rs index fa47526..a419346 100644 --- a/src/context/tracer.rs +++ b/src/context/tracer.rs @@ -97,9 +97,21 @@ impl Tracer { } } + pub fn service_name(&self) -> &str { + &self.inner.service_name + } + + pub fn instance_name(&self) -> &str { + &self.inner.instance_name + } + /// Create trace conetxt. pub fn create_trace_context(&self) -> TracingContext { - TracingContext::new(&self.inner.service_name, &self.inner.instance_name) + TracingContext::new( + &self.inner.service_name, + &self.inner.instance_name, + self.downgrade(), + ) } /// Create trace conetxt from propagation. @@ -111,6 +123,7 @@ impl Tracer { &self.inner.service_name, &self.inner.instance_name, context, + self.downgrade(), ) } @@ -185,17 +198,19 @@ impl Tracer { } fn downgrade(&self) -> WeakTracer { - WeakTracer { inner: Arc::downgrade(&self.inner) } + WeakTracer { + inner: Arc::downgrade(&self.inner), + } } } #[derive(Clone)] -struct WeakTracer { +pub(crate) struct WeakTracer { inner: Weak, } impl WeakTracer { - fn upgrade(&self) -> Option { + pub(crate) fn upgrade(&self) -> Option { Weak::upgrade(&self.inner).map(|inner| Tracer { inner }) } } From 9ff0c2ed34c69bf6cadbe71eb913ed619572a289 Mon Sep 17 00:00:00 2001 From: jmjoy <918734043@qq.com> Date: Wed, 13 Jul 2022 00:29:33 +0800 Subject: [PATCH 05/12] Prepare spans. --- src/context/trace_context.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/context/trace_context.rs b/src/context/trace_context.rs index 7fea710..90ec60f 100644 --- a/src/context/trace_context.rs +++ b/src/context/trace_context.rs @@ -64,6 +64,7 @@ use std::sync::Arc; #[derive(Clone)] pub struct Span { span_internal: Rc>, + context: WeakTracingContext, } impl std::fmt::Debug for Span { @@ -544,6 +545,12 @@ impl TracingContext { } } +#[derive(Clone)] +struct WeakTracingContext { + inner: Weak, + tracer: WeakTracer, +} + pub struct ContextSnapshot { trace_id: String, trace_segment_id: String, From 7107ade43cda9fc8ce4a3812f89fedb83efa1d90 Mon Sep 17 00:00:00 2001 From: jmjoy <918734043@qq.com> Date: Thu, 14 Jul 2022 16:18:24 +0800 Subject: [PATCH 06/12] Pass the lib check. --- src/context/mod.rs | 4 +- src/context/span.rs | 181 ++++++++++++++ src/context/system_time.rs | 6 +- src/context/trace_context.rs | 463 +++++++++++------------------------ src/context/tracer.rs | 9 + src/error/mod.rs | 3 + src/lib.rs | 2 +- 7 files changed, 347 insertions(+), 321 deletions(-) create mode 100644 src/context/span.rs diff --git a/src/context/mod.rs b/src/context/mod.rs index 19bc6a1..5b2cec9 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -15,7 +15,7 @@ // pub mod propagation; -#[doc(hidden)] -pub mod system_time; +pub(crate) mod system_time; pub mod trace_context; pub mod tracer; +pub mod span; diff --git a/src/context/span.rs b/src/context/span.rs new file mode 100644 index 0000000..ed035f2 --- /dev/null +++ b/src/context/span.rs @@ -0,0 +1,181 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +use crate::skywalking_proto::v3::{KeyStringValuePair, Log, SpanLayer, SpanObject, SpanType}; +use std::fmt::Formatter; + +use super::{ + system_time::{fetch_time, TimePeriod}, + trace_context::{TracingContext, WeakTracingContext}, +}; + +/// Span is a concept that represents trace information for a single RPC. +/// The Rust SDK supports Entry Span to represent inbound to a service +/// and Exit Span to represent outbound from a service. +/// +/// # Example +/// +/// ``` +/// use skywalking::context::trace_context::TracingContext; +/// +/// async fn handle_request() { +/// let mut ctx = TracingContext::default("svc", "ins"); +/// { +/// // Generate an Entry Span when a request +/// // is received. An Entry Span is generated only once per context. +/// let span = ctx.create_entry_span("operation1").unwrap(); +/// +/// // Something... +/// +/// { +/// // Generates an Exit Span when executing an RPC. +/// let span2 = ctx.create_exit_span("operation2", "remote_peer").unwrap(); +/// +/// // Something... +/// +/// ctx.finalize_span(span2); +/// } +/// +/// ctx.finalize_span(span); +/// } +/// } +/// ``` +#[derive(Clone)] +pub struct Span { + index: usize, + context: WeakTracingContext, +} + +impl std::fmt::Debug for Span { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut d = f.debug_struct("Span"); + match self.context.upgrade() { + Some(context) => { + if context + .try_with_active_span_stack(|stack| { + d.field("data", &stack.get(self.index)); + }) + .is_none() + { + d.field("data", &format_args!("")); + } + } + None => { + d.field("context", &format_args!("")); + } + } + d.finish() + } +} + +const SKYWALKING_RUST_COMPONENT_ID: i32 = 11000; + +impl Span { + pub(crate) fn new(index: usize, context: WeakTracingContext) -> Self { + Self { index, context } + } + + #[allow(clippy::too_many_arguments)] + pub(crate) fn new_obj( + span_id: i32, + parent_span_id: i32, + operation_name: String, + remote_peer: String, + span_type: SpanType, + span_layer: SpanLayer, + skip_analysis: bool, + ) -> SpanObject { + SpanObject { + span_id, + parent_span_id, + start_time: fetch_time(TimePeriod::Start), + operation_name, + peer: remote_peer, + span_type: span_type as i32, + span_layer: span_layer as i32, + component_id: SKYWALKING_RUST_COMPONENT_ID, + skip_analysis, + ..Default::default() + } + } + + fn upgrade_context(&self) -> TracingContext { + self.context.upgrade().expect("Context has dropped") + } + + pub fn with_span_object(&self, f: impl FnOnce(&SpanObject) -> T) -> T { + self.upgrade_context() + .with_active_span_stack(|stack| f(&stack[self.index])) + } + + pub fn with_span_object_mut(&mut self, f: impl FnOnce(&mut SpanObject) -> T) -> T { + self.upgrade_context() + .with_active_span_stack_mut(|stack| f(&mut stack[self.index])) + } + + pub fn span_id(&self) -> i32 { + self.with_span_object(|span| span.span_id) + } + + /// Add logs to the span. + pub fn add_log(&mut self, message: I) + where + K: ToString, + V: ToString, + I: IntoIterator, + { + let log = Log { + time: fetch_time(TimePeriod::Log), + data: message + .into_iter() + .map(|v| { + let (key, value) = v; + KeyStringValuePair { + key: key.to_string(), + value: value.to_string(), + } + }) + .collect(), + }; + self.with_span_object_mut(|span| span.logs.push(log)); + } + + /// Add tag to the span. + pub fn add_tag(&mut self, key: impl ToString, value: impl ToString) { + self.with_span_object_mut(|span| { + span.tags.push(KeyStringValuePair { + key: key.to_string(), + value: value.to_string(), + }) + }) + } + + // fn add_segment_reference(&mut self, segment_reference: SegmentReference) { + // self.with_span_object_mut(|span| span.refs.push(segment_reference)); + // } + + // fn unwrap_inner(self) -> SpanObject { + // Arc::try_unwrap(self.span_internal).unwrap().into_inner() + // } +} + +impl Drop for Span { + fn drop(&mut self) { + if self.upgrade_context().finalize_span(self.index).is_err() { + panic!("Dropped span isn't the active span"); + } + } +} diff --git a/src/context/system_time.rs b/src/context/system_time.rs index 3bb72f7..7bbdf6f 100644 --- a/src/context/system_time.rs +++ b/src/context/system_time.rs @@ -16,7 +16,7 @@ use cfg_if::cfg_if; -pub enum TimePeriod { +pub(crate) enum TimePeriod { Start, Log, End, @@ -24,7 +24,7 @@ pub enum TimePeriod { cfg_if! { if #[cfg(test)] { - pub fn fetch_time(period: TimePeriod) -> i64 { + pub(crate) fn fetch_time(period: TimePeriod) -> i64 { match period { TimePeriod::Start => 1, TimePeriod::Log => 10, @@ -32,7 +32,7 @@ cfg_if! { } } } else { - pub fn fetch_time(_period: TimePeriod) -> i64 { + pub(crate) fn fetch_time(_period: TimePeriod) -> i64 { use std::time::{SystemTime, UNIX_EPOCH}; SystemTime::now() .duration_since(UNIX_EPOCH) diff --git a/src/context/trace_context.rs b/src/context/trace_context.rs index 90ec60f..ebf257a 100644 --- a/src/context/trace_context.rs +++ b/src/context/trace_context.rs @@ -14,10 +14,12 @@ // limitations under the License. // +use super::span::Span; use super::system_time::{fetch_time, TimePeriod}; use super::tracer::WeakTracer; use crate::common::random_generator::RandomGenerator; use crate::context::propagation::context::PropagationContext; +use crate::error::{LOCK_MSG, UNWRAP_RC_MSG}; use crate::skywalking_proto::v3::{ KeyStringValuePair, Log, RefType, SegmentObject, SegmentReference, SpanLayer, SpanObject, SpanType, @@ -27,205 +29,37 @@ use std::cell::{RefCell, Cell}; use std::collections::LinkedList; use std::fmt::Formatter; use std::ops::Deref; -use std::rc::{Rc, Weak}; -use std::sync::Arc; - -/// Span is a concept that represents trace information for a single RPC. -/// The Rust SDK supports Entry Span to represent inbound to a service -/// and Exit Span to represent outbound from a service. -/// -/// # Example -/// -/// ``` -/// use skywalking::context::trace_context::TracingContext; -/// -/// async fn handle_request() { -/// let mut ctx = TracingContext::default("svc", "ins"); -/// { -/// // Generate an Entry Span when a request -/// // is received. An Entry Span is generated only once per context. -/// let span = ctx.create_entry_span("operation1").unwrap(); -/// -/// // Something... -/// -/// { -/// // Generates an Exit Span when executing an RPC. -/// let span2 = ctx.create_exit_span("operation2", "remote_peer").unwrap(); -/// -/// // Something... -/// -/// ctx.finalize_span(span2); -/// } -/// -/// ctx.finalize_span(span); -/// } -/// } -/// ``` -#[derive(Clone)] -pub struct Span { - span_internal: Rc>, - context: WeakTracingContext, -} - -impl std::fmt::Debug for Span { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Span") - .field("span_internal", &self.span_internal) - .finish() - } -} - -const SKYWALKING_RUST_COMPONENT_ID: i32 = 11000; - -impl Span { - #[allow(clippy::too_many_arguments)] - pub fn new( - span_id: i32, - parent_span_id: i32, - operation_name: String, - remote_peer: String, - span_type: SpanType, - span_layer: SpanLayer, - skip_analysis: bool, - ) -> Self { - let span_internal = SpanObject { - span_id, - parent_span_id, - start_time: fetch_time(TimePeriod::Start), - end_time: 0, // not set - refs: Vec::::new(), - operation_name, - peer: remote_peer, - span_type: span_type as i32, - span_layer: span_layer as i32, - component_id: SKYWALKING_RUST_COMPONENT_ID, - is_error: false, - tags: Vec::::new(), - logs: Vec::::new(), - skip_analysis, - }; - - Span { - span_internal: Rc::new(RefCell::new(span_internal)), - } - } - - /// Close span. It only registers end time to the span. - pub fn close(&mut self) { - self.with_span_object_mut(|span| span.end_time = fetch_time(TimePeriod::End)); - } - - pub fn with_span_object(&self, f: impl FnOnce(&SpanObject) -> T) -> T { - f(&self.span_internal.deref().borrow()) - } - - pub fn with_span_object_mut(&mut self, f: impl FnOnce(&mut SpanObject) -> T) -> T { - f(&mut self.span_internal.deref().borrow_mut()) - } - - pub fn span_id(&self) -> i32 { - self.with_span_object(|span| span.span_id) - } - - /// Add logs to the span. - pub fn add_log(&mut self, message: I) - where - K: ToString, - V: ToString, - I: IntoIterator, - { - let log = Log { - time: fetch_time(TimePeriod::Log), - data: message - .into_iter() - .map(|v| { - let (key, value) = v; - KeyStringValuePair { - key: key.to_string(), - value: value.to_string(), - } - }) - .collect(), - }; - self.with_span_object_mut(|span| span.logs.push(log)); - } - - /// Add tag to the span. - pub fn add_tag(&mut self, tag: (&str, &str)) { - let (key, value) = tag; - self.with_span_object_mut(|span| { - span.tags.push(KeyStringValuePair { - key: key.to_string(), - value: value.to_string(), - }) - }) - } - - fn add_segment_reference(&mut self, segment_reference: SegmentReference) { - self.with_span_object_mut(|span| span.refs.push(segment_reference)); - } - - fn unwrap_inner(self) -> SpanObject { - Rc::try_unwrap(self.span_internal).unwrap().into_inner() - } - - // fn downgrade(&self) -> WeakSpan { - // WeakSpan { - // span_internal: Rc::downgrade(&self.span_internal), - // } - // } -} - -// pub(crate) struct WeakSpan { -// span_internal: Weak>, -// } - -// impl WeakSpan { -// pub fn span_id(&self) -> Option { -// self.upgrade().map(|span| span.span_id()) -// } - -// fn upgrade(&self) -> Option { -// self.span_internal -// .upgrade() -// .map(|span_internal| Span { span_internal }) -// } -// } +use std::sync::{Arc, Weak, Mutex}; +use std::sync::atomic::{AtomicI32, Ordering}; struct Inner { trace_id: String, trace_segment_id: String, service: String, service_instance: String, - next_span_id: Cell, - spans: RefCell>, + next_span_id: AtomicI32, + spans: Mutex>, + active_span_stack: Mutex>, segment_link: Option, - active_span_stack: RefCell>, - primary_endpoint_name: RefCell, -} - -impl std::fmt::Debug for Inner { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.debug_struct("TracingContext") - .field("trace_id", &self.trace_id) - .field("trace_segment_id", &self.trace_segment_id) - .field("service", &self.service) - .field("service_instance", &self.service_instance) - .field("next_span_id", &self.next_span_id) - .field("spans", &self.spans) - .finish() - } + primary_endpoint_name: Mutex, } #[derive(Clone)] pub struct TracingContext { - inner: Rc, + inner: Arc, tracer: WeakTracer, } impl std::fmt::Debug for TracingContext { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { -std::fmt::Debug::fmt(&self.inner,f) + f.debug_struct("TracingContext") + .field("trace_id", &self.inner.trace_id) + .field("trace_segment_id", &self.inner.trace_segment_id) + .field("service", &self.inner.service) + .field("service_instance", &self.inner.service_instance) + .field("next_span_id", &self.inner.next_span_id) + .field("spans", &self.inner.spans) + .finish() } } @@ -238,7 +72,7 @@ impl TracingContext { tracer: WeakTracer, ) -> Self { TracingContext { - inner: Rc::new(Inner { + inner: Arc::new(Inner { trace_id: RandomGenerator::generate(), trace_segment_id: RandomGenerator::generate(), service: service_name.to_string(), @@ -263,7 +97,7 @@ impl TracingContext { tracer: WeakTracer, ) -> Self { TracingContext { - inner: Rc::new(Inner { + inner: Arc::new(Inner { trace_id: context.parent_trace_id.clone(), trace_segment_id: RandomGenerator::generate(), service: service_name.to_string(), @@ -298,56 +132,45 @@ impl TracingContext { &self.inner.service_instance } - #[inline] fn next_span_id(&self) -> i32 { - self.inner.next_span_id.get() + self.inner.next_span_id.load(Ordering::Relaxed) } - fn inc_next_span_id(&self) { - self.inner.next_span_id.set(self.next_span_id() + 1) + #[inline] + fn inc_next_span_id(&self) -> i32 { + self.inner.next_span_id.fetch_add(1, Ordering::Relaxed) } - fn with_spans(&self, f: impl FnOnce(&Vec) -> T) -> T { - f(&self.inner.spans.borrow()) + fn with_spans(&self, f: impl FnOnce(&Vec) -> T) -> T { + f(&*self.inner.spans.try_lock().expect(LOCK_MSG)) } - fn with_spans_mut(&mut self, f: impl FnOnce(&mut Vec) -> T) -> T { - f(&mut self.inner.spans.borrow_mut()) + fn with_spans_mut(&mut self, f: impl FnOnce(&mut Vec) -> T) -> T { + f(&mut *self.inner.spans.try_lock().expect(LOCK_MSG)) } - fn with_active_span_stack(&self, f: impl FnOnce(&LinkedList) -> T) -> T { - f(&self.inner.active_span_stack.borrow()) + pub(crate) fn with_active_span_stack(&self, f: impl FnOnce(&Vec) -> T) -> T { + f(&*self.inner.active_span_stack.try_lock().expect(LOCK_MSG)) } - fn with_active_span_stack_mut(&mut self, f: impl FnOnce(&mut LinkedList) -> T) -> T { - f(&mut self.inner.active_span_stack.borrow_mut()) + pub(crate) fn with_active_span_stack_mut(&mut self, f: impl FnOnce(&mut Vec) -> T) -> T { + f(&mut *self.inner.active_span_stack.try_lock().expect(LOCK_MSG)) } - fn with_primary_endpoint_name(&self, f: impl FnOnce(&String) -> T) -> T { - f(&self.inner.primary_endpoint_name.borrow()) + pub(crate) fn try_with_active_span_stack(&self, f: impl FnOnce(&Vec) -> T) -> Option { + self.inner.active_span_stack.try_lock().ok().map(|stack| f(&*stack)) } - fn with_primary_endpoint_name_mut(&mut self, f: impl FnOnce(&mut String) -> T) -> T { - f(&mut self.inner.primary_endpoint_name.borrow_mut()) + pub(crate) fn with_active_span(&self, f: impl FnOnce(&SpanObject) -> T) -> Option { + self.with_active_span_stack(|stack| stack.last().map(|span| f(span))) } - /// A wrapper of create entry span, which close generated span automatically. - /// Note that, we may use async operation in closure. But that is not unstable feature in 2021/12. - /// - /// So we should create and close spans manually in general. - pub fn entry( - &mut self, - operation_name: &str, - mut process_fn: F, - ) -> crate::Result<()> { - match self.create_entry_span(operation_name) { - Ok(mut span) => { - process_fn(&span); - span.close(); - Ok(()) - } - Err(message) => Err(message), - } + fn with_primary_endpoint_name(&self, f: impl FnOnce(&String) -> T) -> T { + f(&*self.inner.primary_endpoint_name.try_lock().expect(LOCK_MSG)) + } + + fn with_primary_endpoint_name_mut(&mut self, f: impl FnOnce(&mut String) -> T) -> T { + f(&mut *self.inner.primary_endpoint_name.try_lock().expect(LOCK_MSG)) } /// Create a new entry span, which is an initiator of collection of spans. @@ -358,11 +181,9 @@ impl TracingContext { return Err(crate::Error::CreateSpan("entry span have already exist.")); } - let parent_span_id = self.peek_active_span_id().unwrap_or(-1); - - let mut span = Span::new( - self.inner.next_span_id.get(), - parent_span_id, + let mut span = Span::new_obj( + self.inc_next_span_id(), + self.peek_active_span_id().unwrap_or(-1), operation_name.to_string(), String::default(), SpanType::Entry, @@ -371,7 +192,7 @@ impl TracingContext { ); if let Some(segment_link) = &self.inner.segment_link { - span.add_segment_reference(SegmentReference { + span.refs.push(SegmentReference { ref_type: RefType::CrossProcess as i32, trace_id: self.inner.trace_id.clone(), parent_trace_segment_id: segment_link.parent_trace_segment_id.clone(), @@ -382,29 +203,12 @@ impl TracingContext { network_address_used_at_peer: segment_link.destination_address.clone(), }); } - self.inc_next_span_id(); - self.push_active_span(&span); - Ok(span) - } - /// A wrapper of create exit span, which close generated span automatically. - /// Note that, we may use async operation in closure. But that is not unstable feature in 2021/12. - /// - /// So we should create and close spans manually in general. - pub fn exit( - &mut self, - operation_name: &str, - remote_peer: &str, - mut process_fn: F, - ) -> crate::Result<()> { - match self.create_exit_span(operation_name, remote_peer) { - Ok(mut span) => { - process_fn(&span); - span.close(); - Ok(()) - } - Err(message) => Err(message), - } + let index = self.push_active_span(span); + Ok(Span::new( + index, + self.downgrade(), + )) } /// Create a new exit span, which will be created when tracing context will generate @@ -419,20 +223,21 @@ impl TracingContext { return Err(crate::Error::CreateSpan("entry span must be existed.")); } - let parent_span_id = self.peek_active_span_id().unwrap_or(-1); - - let span = Span::new( - self.inner.next_span_id.get(), - parent_span_id, + let span = Span::new_obj( + self.inc_next_span_id(), +self.peek_active_span_id().unwrap_or(-1), operation_name.to_string(), remote_peer.to_string(), SpanType::Exit, SpanLayer::Http, false, ); - self.inc_next_span_id(); - self.push_active_span(&span); - Ok(span) + + let index = self.push_active_span(span); + Ok(Span::new( + index, + self.downgrade(), + )) } // Create a new local span. @@ -441,116 +246,133 @@ impl TracingContext { return Err(crate::Error::CreateSpan("entry span must be existed.")); } - let parent_span_id = self.peek_active_span_id().unwrap_or(-1); - - let span = Span::new( - self.inner.next_span_id.get(), - parent_span_id, + let span = Span::new_obj( + self.inc_next_span_id(), +self.peek_active_span_id().unwrap_or(-1), operation_name.to_string(), Default::default(), SpanType::Local, SpanLayer::Unknown, false, ); - self.inc_next_span_id(); - self.push_active_span(&span); - Ok(span) + + let index = self.push_active_span(span); + Ok(Span::new( + index, + self.downgrade(), + )) } /// Close span. We can't use closed span after finalize called. - pub fn finalize_span(&mut self, mut span: Span) { - span.close(); - self.with_spans_mut(|spans| spans.push(span)); - self.pop_active_span(); + pub(crate) fn finalize_span(&mut self, index: usize) -> Result<(), ()> { + let span = self.pop_active_span(index); + if let Some(mut span) = span { + span.end_time = fetch_time(TimePeriod::End); + self.with_spans_mut(|spans| spans.push(span)); + Ok(()) + } else { + Err(()) + } } /// It converts tracing context into segment object. /// This conversion should be done before sending segments into OAP. pub fn convert_segment_object(self) -> SegmentObject { - let mut objects = Vec::with_capacity(self.with_spans(|spans| spans.len())); - let trace_id = self.trace_id().to_owned(); let trace_segment_id = self.trace_segment_id().to_owned(); let service = self.service().to_owned(); let service_instance = self.service_instance().to_owned(); let inner = self.unwrap_inner(); - for span in inner.spans.into_inner() { - objects.push(span.unwrap_inner()); - } - SegmentObject { trace_id, trace_segment_id, - spans: objects, + spans: inner.spans.into_inner().expect(LOCK_MSG), service, service_instance, is_size_limited: false, } } - pub fn capture(&self) -> ContextSnapshot { - ContextSnapshot { - trace_id: self.inner.trace_id.clone(), - trace_segment_id: self.inner.trace_segment_id.clone(), - span_id: self.peek_active_span_id().unwrap_or(-1), - parent_endpoint: self.with_primary_endpoint_name(|endpoint| endpoint.clone()), - } - } + // pub fn capture(&self) -> ContextSnapshot { + // ContextSnapshot { + // trace_id: self.inner.trace_id.clone(), + // trace_segment_id: self.inner.trace_segment_id.clone(), + // span_id: self.peek_active_span_id().unwrap_or(-1), + // parent_endpoint: self.with_primary_endpoint_name(|endpoint| endpoint.clone()), + // } + // } - pub fn continued(&mut self, snapshot: ContextSnapshot) { - if snapshot.is_valid() { - let tracer = self.tracer.upgrade().unwrap(); - let segment_ref = SegmentReference { - ref_type: RefType::CrossThread as i32, - trace_id: snapshot.trace_id, - parent_trace_segment_id: snapshot.trace_segment_id, - parent_span_id: snapshot.span_id, - parent_service: tracer.service_name().to_owned(), - parent_service_instance: tracer.instance_name().to_owned(), - parent_endpoint: snapshot.parent_endpoint, - network_address_used_at_peer: Default::default(), - }; - let mut span = self.peek_active_span().unwrap(); - span.add_segment_reference(segment_ref); - // TraceSegmentRef segmentRef = new TraceSegmentRef(snapshot); - // this.segment.ref(segmentRef); - // this.activeSpan().ref(segmentRef); - // this.segment.relatedGlobalTrace(snapshot.getTraceId()); - // this.correlationContext.continued(snapshot); - // this.extensionContext.continued(snapshot); - // this.extensionContext.handle(this.activeSpan()); - } - } + // pub fn continued(&mut self, snapshot: ContextSnapshot) { + // if snapshot.is_valid() { + // let tracer = self.tracer.upgrade().unwrap(); + // let segment_ref = SegmentReference { + // ref_type: RefType::CrossThread as i32, + // trace_id: snapshot.trace_id, + // parent_trace_segment_id: snapshot.trace_segment_id, + // parent_span_id: snapshot.span_id, + // parent_service: tracer.service_name().to_owned(), + // parent_service_instance: tracer.instance_name().to_owned(), + // parent_endpoint: snapshot.parent_endpoint, + // network_address_used_at_peer: Default::default(), + // }; + // let mut span = self.peek_active_span().unwrap(); + // span.add_segment_reference(segment_ref); + // // TraceSegmentRef segmentRef = new TraceSegmentRef(snapshot); + // // this.segment.ref(segmentRef); + // // this.activeSpan().ref(segmentRef); + // // this.segment.relatedGlobalTrace(snapshot.getTraceId()); + // // this.correlationContext.continued(snapshot); + // // this.extensionContext.continued(snapshot); + // // this.extensionContext.handle(this.activeSpan()); + // } + // } pub(crate) fn peek_active_span_id(&self) -> Option { - self.peek_active_span().map(|span| span.span_id()) + self.with_active_span(|span| span.span_id) } - pub(crate) fn peek_active_span(&self) -> Option { - self.with_active_span_stack(|stack| stack.back().cloned()) + fn push_active_span(&mut self, span: SpanObject) -> usize { + self.with_primary_endpoint_name_mut(|endpoint| *endpoint = span.operation_name.clone()); + self.with_active_span_stack_mut(|stack| { + stack.push(span); + stack.len() - 1 + }) } - fn push_active_span(&mut self, span: &Span) { - self.with_primary_endpoint_name_mut(|endpoint| *endpoint = span.with_span_object(|span| span.operation_name.clone())); - self.with_active_span_stack_mut(|stack| stack.push_back(span.clone())); + fn pop_active_span(&mut self, index: usize) -> Option { + self.with_active_span_stack_mut(|stack| { + if stack.len() > index + 1 { + None + } else { + stack.pop() + } + }) } - fn pop_active_span(&mut self) { - self.with_active_span_stack_mut(|stack| stack.pop_back()); + fn downgrade(&self) -> WeakTracingContext { + WeakTracingContext { inner: Arc::downgrade(&self.inner), tracer: self.tracer.clone() } } fn unwrap_inner(self) -> Inner { - Rc::try_unwrap(self.inner).unwrap() + Arc::try_unwrap(self.inner).ok().expect(UNWRAP_RC_MSG) } } #[derive(Clone)] -struct WeakTracingContext { +pub(crate) struct WeakTracingContext { inner: Weak, tracer: WeakTracer, } +impl WeakTracingContext { + pub(crate) fn upgrade(&self) -> Option { + self.inner + .upgrade() + .map(|inner| TracingContext { inner, tracer: self.tracer.clone() }) + } +} + pub struct ContextSnapshot { trace_id: String, trace_segment_id: String, @@ -567,3 +389,14 @@ impl ContextSnapshot { !self.trace_segment_id.is_empty() && self.span_id > -1 && !self.trace_id.is_empty() } } + +#[cfg(test)] +mod tests { + use super::*; + + trait AssertSend: Send {} + + impl AssertSend for TracingContext {} + + impl AssertSend for Span {} +} diff --git a/src/context/tracer.rs b/src/context/tracer.rs index a419346..721fd94 100644 --- a/src/context/tracer.rs +++ b/src/context/tracer.rs @@ -214,3 +214,12 @@ impl WeakTracer { Weak::upgrade(&self.inner).map(|inner| Tracer { inner }) } } + +#[cfg(test)] +mod tests { + use super::*; + + trait AssertSend: Send {} + + impl AssertSend for Tracer {} +} diff --git a/src/error/mod.rs b/src/error/mod.rs index 28a3561..01fe3db 100644 --- a/src/error/mod.rs +++ b/src/error/mod.rs @@ -16,6 +16,9 @@ use tokio::{sync::oneshot, task::JoinError}; +pub(crate) const LOCK_MSG: &str = "whould not cross threads/coroutines (locked)"; +pub(crate) const UNWRAP_RC_MSG: &str = "more than one reference"; + /// Skywalking Result. pub type Result = std::result::Result; diff --git a/src/lib.rs b/src/lib.rs index cc4ef8c..235d015 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,7 +25,7 @@ pub mod skywalking_proto { pub mod common; pub mod context; -mod error; +pub(crate) mod error; pub mod reporter; pub use error::{Error, Result}; From 84087234252b1abe07dee3c78b0aea74de7d300d Mon Sep 17 00:00:00 2001 From: jmjoy <918734043@qq.com> Date: Thu, 14 Jul 2022 18:47:17 +0800 Subject: [PATCH 07/12] Pass apis. --- examples/simple_trace_report.rs | 19 +++--- src/context/mod.rs | 2 +- src/context/span.rs | 9 +++ src/context/trace_context.rs | 104 ++++++++++++++++++-------------- src/context/tracer.rs | 8 +-- src/error/mod.rs | 6 +- src/reporter/log.rs | 38 ++++++++++++ src/reporter/mod.rs | 1 + tests/propagation.rs | 15 ++--- tests/trace_context.rs | 9 --- 10 files changed, 124 insertions(+), 87 deletions(-) create mode 100644 src/reporter/log.rs diff --git a/examples/simple_trace_report.rs b/examples/simple_trace_report.rs index 6d8d7fc..d172f95 100644 --- a/examples/simple_trace_report.rs +++ b/examples/simple_trace_report.rs @@ -21,35 +21,36 @@ use std::error::Error; use std::sync::Arc; use tokio::signal; -async fn handle_request(tracer: Arc>) { +async fn handle_request(tracer: Tracer) { let mut ctx = tracer.create_trace_context(); { - // Generate an Entry Span when a request - // is received. An Entry Span is generated only once per context. - let span = ctx.create_entry_span("op1").unwrap(); + // Generate an Entry Span when a request is received. + // An Entry Span is generated only once per context. + // You should assign a variable name to guard the span not be dropped immediately. + let _span = ctx.create_entry_span("op1"); // Something... { // Generates an Exit Span when executing an RPC. - let span2 = ctx.create_exit_span("op2", "remote_peer").unwrap(); + let _span2 = ctx.create_exit_span("op2", "remote_peer"); // Something... - ctx.finalize_span(span2); + // Auto close span2 when dropped. } - ctx.finalize_span(span); + // Auto close span when dropped. } - tracer.finalize_context(ctx); + // Auto report ctx when dropped. } #[tokio::main] async fn main() -> Result<(), Box> { let reporter = GrpcReporter::connect("http://0.0.0.0:11800").await?; - let tracer = Arc::new(Tracer::new("service", "instance", reporter)); + let tracer = Tracer::new("service", "instance", reporter); tokio::spawn(handle_request(tracer.clone())); diff --git a/src/context/mod.rs b/src/context/mod.rs index 5b2cec9..28d7ace 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -15,7 +15,7 @@ // pub mod propagation; +pub mod span; pub(crate) mod system_time; pub mod trace_context; pub mod tracer; -pub mod span; diff --git a/src/context/span.rs b/src/context/span.rs index ed035f2..8fa4464 100644 --- a/src/context/span.rs +++ b/src/context/span.rs @@ -179,3 +179,12 @@ impl Drop for Span { } } } + +#[cfg(test)] +mod tests { + use super::*; + + trait AssertSend: Send {} + + impl AssertSend for Span {} +} diff --git a/src/context/trace_context.rs b/src/context/trace_context.rs index ebf257a..6bc51a0 100644 --- a/src/context/trace_context.rs +++ b/src/context/trace_context.rs @@ -16,21 +16,22 @@ use super::span::Span; use super::system_time::{fetch_time, TimePeriod}; -use super::tracer::WeakTracer; +use super::tracer::{Tracer, WeakTracer}; use crate::common::random_generator::RandomGenerator; use crate::context::propagation::context::PropagationContext; -use crate::error::{LOCK_MSG, UNWRAP_RC_MSG}; +use crate::error::LOCK_MSG; use crate::skywalking_proto::v3::{ KeyStringValuePair, Log, RefType, SegmentObject, SegmentReference, SpanLayer, SpanObject, SpanType, }; use std::borrow::Borrow; -use std::cell::{RefCell, Cell}; +use std::cell::{Cell, RefCell}; use std::collections::LinkedList; use std::fmt::Formatter; +use std::mem::take; use std::ops::Deref; -use std::sync::{Arc, Weak, Mutex}; use std::sync::atomic::{AtomicI32, Ordering}; +use std::sync::{Arc, Mutex, Weak}; struct Inner { trace_id: String, @@ -111,7 +112,7 @@ impl TracingContext { tracer, } } - + #[inline] pub fn trace_id(&self) -> &str { &self.inner.trace_id @@ -134,12 +135,12 @@ impl TracingContext { fn next_span_id(&self) -> i32 { self.inner.next_span_id.load(Ordering::Relaxed) - } + } #[inline] fn inc_next_span_id(&self) -> i32 { self.inner.next_span_id.fetch_add(1, Ordering::Relaxed) - } + } fn with_spans(&self, f: impl FnOnce(&Vec) -> T) -> T { f(&*self.inner.spans.try_lock().expect(LOCK_MSG)) @@ -153,12 +154,22 @@ impl TracingContext { f(&*self.inner.active_span_stack.try_lock().expect(LOCK_MSG)) } - pub(crate) fn with_active_span_stack_mut(&mut self, f: impl FnOnce(&mut Vec) -> T) -> T { + pub(crate) fn with_active_span_stack_mut( + &mut self, + f: impl FnOnce(&mut Vec) -> T, + ) -> T { f(&mut *self.inner.active_span_stack.try_lock().expect(LOCK_MSG)) } - pub(crate) fn try_with_active_span_stack(&self, f: impl FnOnce(&Vec) -> T) -> Option { - self.inner.active_span_stack.try_lock().ok().map(|stack| f(&*stack)) + pub(crate) fn try_with_active_span_stack( + &self, + f: impl FnOnce(&Vec) -> T, + ) -> Option { + self.inner + .active_span_stack + .try_lock() + .ok() + .map(|stack| f(&*stack)) } pub(crate) fn with_active_span(&self, f: impl FnOnce(&SpanObject) -> T) -> Option { @@ -176,9 +187,9 @@ impl TracingContext { /// Create a new entry span, which is an initiator of collection of spans. /// This should be called by invocation of the function which is triggered by /// external service. - pub fn create_entry_span(&mut self, operation_name: &str) -> crate::Result { + pub fn create_entry_span(&mut self, operation_name: &str) -> Span { if self.next_span_id() >= 1 { - return Err(crate::Error::CreateSpan("entry span have already exist.")); + panic!("entry span have already exist."); } let mut span = Span::new_obj( @@ -205,27 +216,20 @@ impl TracingContext { } let index = self.push_active_span(span); - Ok(Span::new( - index, - self.downgrade(), - )) + Span::new(index, self.downgrade()) } /// Create a new exit span, which will be created when tracing context will generate /// new span for function invocation. /// Currently, this SDK supports RPC call. So we must set `remote_peer`. - pub fn create_exit_span( - &mut self, - operation_name: &str, - remote_peer: &str, - ) -> crate::Result { + pub fn create_exit_span(&mut self, operation_name: &str, remote_peer: &str) -> Span { if self.next_span_id() == 0 { - return Err(crate::Error::CreateSpan("entry span must be existed.")); + panic!("entry span must be existed."); } let span = Span::new_obj( - self.inc_next_span_id(), -self.peek_active_span_id().unwrap_or(-1), + self.inc_next_span_id(), + self.peek_active_span_id().unwrap_or(-1), operation_name.to_string(), remote_peer.to_string(), SpanType::Exit, @@ -234,21 +238,18 @@ self.peek_active_span_id().unwrap_or(-1), ); let index = self.push_active_span(span); - Ok(Span::new( - index, - self.downgrade(), - )) + Span::new(index, self.downgrade()) } // Create a new local span. - pub fn create_local_span(&mut self, operation_name: &str) -> crate::Result { + pub fn create_local_span(&mut self, operation_name: &str) -> Span { if self.next_span_id() == 0 { - return Err(crate::Error::CreateSpan("entry span must be existed.")); + panic!("entry span must be existed."); } let span = Span::new_obj( self.inc_next_span_id(), -self.peek_active_span_id().unwrap_or(-1), + self.peek_active_span_id().unwrap_or(-1), operation_name.to_string(), Default::default(), SpanType::Local, @@ -257,10 +258,7 @@ self.peek_active_span_id().unwrap_or(-1), ); let index = self.push_active_span(span); - Ok(Span::new( - index, - self.downgrade(), - )) + Span::new(index, self.downgrade()) } /// Close span. We can't use closed span after finalize called. @@ -277,17 +275,19 @@ self.peek_active_span_id().unwrap_or(-1), /// It converts tracing context into segment object. /// This conversion should be done before sending segments into OAP. - pub fn convert_segment_object(self) -> SegmentObject { + /// + /// Notice: The spans will taked, so this method shouldn't be called twice. + pub(crate) fn convert_segment_object(&mut self) -> SegmentObject { let trace_id = self.trace_id().to_owned(); let trace_segment_id = self.trace_segment_id().to_owned(); let service = self.service().to_owned(); let service_instance = self.service_instance().to_owned(); - let inner = self.unwrap_inner(); + let spans = self.with_spans_mut(|spans| take(spans)); SegmentObject { trace_id, trace_segment_id, - spans: inner.spans.into_inner().expect(LOCK_MSG), + spans, service, service_instance, is_size_limited: false, @@ -351,11 +351,24 @@ self.peek_active_span_id().unwrap_or(-1), } fn downgrade(&self) -> WeakTracingContext { - WeakTracingContext { inner: Arc::downgrade(&self.inner), tracer: self.tracer.clone() } + WeakTracingContext { + inner: Arc::downgrade(&self.inner), + tracer: self.tracer.clone(), + } } - fn unwrap_inner(self) -> Inner { - Arc::try_unwrap(self.inner).ok().expect(UNWRAP_RC_MSG) + // fn unwrap_inner(self) -> Inner { + // Arc::try_unwrap(self.inner).ok().expect(MORE_RC_MSG) + // } + + fn upgrade_tracer(&self) -> Tracer { + self.tracer.upgrade().expect("Tracer has dropped") + } +} + +impl Drop for TracingContext { + fn drop(&mut self) { + self.upgrade_tracer().finalize_context(self) } } @@ -367,9 +380,10 @@ pub(crate) struct WeakTracingContext { impl WeakTracingContext { pub(crate) fn upgrade(&self) -> Option { - self.inner - .upgrade() - .map(|inner| TracingContext { inner, tracer: self.tracer.clone() }) + self.inner.upgrade().map(|inner| TracingContext { + inner, + tracer: self.tracer.clone(), + }) } } @@ -397,6 +411,4 @@ mod tests { trait AssertSend: Send {} impl AssertSend for TracingContext {} - - impl AssertSend for Span {} } diff --git a/src/context/tracer.rs b/src/context/tracer.rs index 721fd94..f69191b 100644 --- a/src/context/tracer.rs +++ b/src/context/tracer.rs @@ -53,10 +53,6 @@ pub fn create_trace_context_from_propagation(context: PropagationContext) -> Tra global_tracer().create_trace_context_from_propagation(context) } -pub fn finalize_context(context: TracingContext) { - global_tracer().finalize_context(context) -} - pub fn reporting( shutdown_signal: impl Future + Send + Sync + 'static, ) -> JoinHandle<()> { @@ -128,10 +124,10 @@ impl Tracer { } /// Finalize the trace context. - pub fn finalize_context(&self, context: TracingContext) { + pub(crate) fn finalize_context(&self, context: &mut TracingContext) { let segment_object = context.convert_segment_object(); if self.inner.segment_sender.send(segment_object).is_err() { - tracing::warn!("segment object channel has closed"); + tracing::error!("segment object channel has closed"); } } diff --git a/src/error/mod.rs b/src/error/mod.rs index 01fe3db..27dfec6 100644 --- a/src/error/mod.rs +++ b/src/error/mod.rs @@ -16,8 +16,7 @@ use tokio::{sync::oneshot, task::JoinError}; -pub(crate) const LOCK_MSG: &str = "whould not cross threads/coroutines (locked)"; -pub(crate) const UNWRAP_RC_MSG: &str = "more than one reference"; +pub(crate) const LOCK_MSG: &str = "should not cross threads/coroutines (locked)"; /// Skywalking Result. pub type Result = std::result::Result; @@ -25,9 +24,6 @@ pub type Result = std::result::Result; /// Skywalking Error. #[derive(Debug, thiserror::Error)] pub enum Error { - #[error("create span failed: {0}")] - CreateSpan(&'static str), - #[error("decode propagation failed: {0}")] DecodePropagation(&'static str), diff --git a/src/reporter/log.rs b/src/reporter/log.rs new file mode 100644 index 0000000..1334c95 --- /dev/null +++ b/src/reporter/log.rs @@ -0,0 +1,38 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +use super::Reporter; +use crate::skywalking_proto::v3::{ + trace_segment_report_service_client::TraceSegmentReportServiceClient, SegmentObject, +}; +use futures_util::stream; +use std::collections::LinkedList; +use tonic::{ + async_trait, + transport::{self, Channel, Endpoint}, +}; + +pub struct LogReporter; + +#[async_trait] +impl Reporter for LogReporter { + async fn collect(&mut self, segments: LinkedList) -> crate::Result<()> { + for segment in segments { + tracing::info!(?segment, "Do trace"); + } + Ok(()) + } +} diff --git a/src/reporter/mod.rs b/src/reporter/mod.rs index 0fc54c1..08faab5 100644 --- a/src/reporter/mod.rs +++ b/src/reporter/mod.rs @@ -15,6 +15,7 @@ // pub mod grpc; +pub mod log; use crate::skywalking_proto::v3::SegmentObject; use std::collections::LinkedList; diff --git a/tests/propagation.rs b/tests/propagation.rs index 39eca87..bb893c3 100644 --- a/tests/propagation.rs +++ b/tests/propagation.rs @@ -15,21 +15,14 @@ // #![allow(unused_imports)] -use skywalking::common::time::TimeFetcher; use skywalking::context::propagation::context::PropagationContext; use skywalking::context::propagation::decoder::decode_propagation; use skywalking::context::propagation::encoder::encode_propagation; use skywalking::context::trace_context::TracingContext; +use skywalking::context::tracer::Tracer; +use skywalking::reporter::log::LogReporter; use std::sync::Arc; -struct MockTimeFetcher {} - -impl TimeFetcher for MockTimeFetcher { - fn get(&self) -> i64 { - 100 - } -} - #[test] fn basic() { let data = "1-MQ==-NQ==-3-bWVzaA==-aW5zdGFuY2U=-L2FwaS92MS9oZWFsdGg=-ZXhhbXBsZS5jb206ODA4MA=="; @@ -71,8 +64,8 @@ fn invalid_sample() { #[test] fn basic_encode() { - let time_fetcher = MockTimeFetcher {}; - let tc = TracingContext::new(Arc::new(time_fetcher), "mesh", "instance"); + let tracer = Tracer::new("mesh", "instance", LogReporter); + let tc = tracer.create_trace_context(); let res = encode_propagation(&tc, "/api/v1/health", "example.com:8080"); let res2 = decode_propagation(&res).unwrap(); assert!(res2.do_sample); diff --git a/tests/trace_context.rs b/tests/trace_context.rs index fbd0f10..a12e9bf 100644 --- a/tests/trace_context.rs +++ b/tests/trace_context.rs @@ -17,7 +17,6 @@ #![allow(unused_imports)] use prost::Message; -use skywalking::common::time::TimeFetcher; use skywalking::context::propagation::context::PropagationContext; use skywalking::context::propagation::decoder::decode_propagation; use skywalking::context::propagation::encoder::encode_propagation; @@ -42,14 +41,6 @@ where assert_eq!(buf_a, buf_b); } -struct MockTimeFetcher {} - -impl TimeFetcher for MockTimeFetcher { - fn get(&self) -> i64 { - 100 - } -} - #[test] fn create_span() { let time_fetcher = MockTimeFetcher {}; From 7b57ff87bb8f667c64be1da67ed92f65a750c890 Mon Sep 17 00:00:00 2001 From: jmjoy <918734043@qq.com> Date: Thu, 14 Jul 2022 23:44:42 +0800 Subject: [PATCH 08/12] Pass compile tests. --- src/context/trace_context.rs | 2 +- src/reporter/mod.rs | 2 +- tests/trace_context.rs | 363 ++++++++++++++++++++--------------- 3 files changed, 208 insertions(+), 159 deletions(-) diff --git a/src/context/trace_context.rs b/src/context/trace_context.rs index 6bc51a0..8be7523 100644 --- a/src/context/trace_context.rs +++ b/src/context/trace_context.rs @@ -142,7 +142,7 @@ impl TracingContext { self.inner.next_span_id.fetch_add(1, Ordering::Relaxed) } - fn with_spans(&self, f: impl FnOnce(&Vec) -> T) -> T { + pub fn with_spans(&self, f: impl FnOnce(&Vec) -> T) -> T { f(&*self.inner.spans.try_lock().expect(LOCK_MSG)) } diff --git a/src/reporter/mod.rs b/src/reporter/mod.rs index 08faab5..c2f9fda 100644 --- a/src/reporter/mod.rs +++ b/src/reporter/mod.rs @@ -25,5 +25,5 @@ pub(crate) type DynReporter = dyn Reporter + Send + Sync + 'static; #[async_trait] pub trait Reporter { - async fn collect(&mut self, stream: LinkedList) -> crate::Result<()>; + async fn collect(&mut self, segments: LinkedList) -> crate::Result<()>; } diff --git a/tests/trace_context.rs b/tests/trace_context.rs index a12e9bf..d360f67 100644 --- a/tests/trace_context.rs +++ b/tests/trace_context.rs @@ -1,4 +1,5 @@ // Licensed to the Apache Software Foundation (ASF) under one or more + // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 @@ -21,10 +22,16 @@ use skywalking::context::propagation::context::PropagationContext; use skywalking::context::propagation::decoder::decode_propagation; use skywalking::context::propagation::encoder::encode_propagation; use skywalking::context::trace_context::TracingContext; +use skywalking::context::tracer::Tracer; +use skywalking::reporter::log::LogReporter; +use skywalking::reporter::Reporter; use skywalking::skywalking_proto::v3::{ KeyStringValuePair, Log, RefType, SegmentObject, SegmentReference, SpanLayer, SpanObject, SpanType, }; +use std::collections::LinkedList; +use std::future; +use std::sync::Mutex; use std::{cell::Ref, sync::Arc}; /// Serialize from A should equal Serialize from B @@ -41,200 +48,242 @@ where assert_eq!(buf_a, buf_b); } -#[test] -fn create_span() { - let time_fetcher = MockTimeFetcher {}; - let mut context = TracingContext::new(Arc::new(time_fetcher), "service", "instance"); - assert_eq!(context.service, "service"); - assert_eq!(context.service_instance, "instance"); +#[tokio::test] +async fn create_span() { + MockReporter::with( + |reporter| { + let tracer = Tracer::new("service", "instance", reporter); + let mut context = tracer.create_trace_context(); + assert_eq!(context.service(), "service"); + assert_eq!(context.service_instance(), "instance"); - { - let mut span1 = context.create_entry_span("op1").unwrap(); - let logs = vec![("hoge", "fuga"), ("hoge2", "fuga2")]; - let expected_log_message = logs - .to_owned() - .into_iter() - .map(|v| { - let (key, value) = v; - KeyStringValuePair { - key: key.to_string(), - value: value.to_string(), + { + let mut span1 = context.create_entry_span("op1"); + let logs = vec![("hoge", "fuga"), ("hoge2", "fuga2")]; + let expected_log_message = logs + .to_owned() + .into_iter() + .map(|v| { + let (key, value) = v; + KeyStringValuePair { + key: key.to_string(), + value: value.to_string(), + } + }) + .collect(); + let expected_log = vec![Log { + time: 100, + data: expected_log_message, + }]; + span1.add_log(logs); + + let tags = vec![("hoge", "fuga")]; + let expected_tags = tags + .to_owned() + .into_iter() + .map(|v| { + let (key, value) = v; + KeyStringValuePair { + key: key.to_string(), + value: value.to_string(), + } + }) + .collect(); + span1.add_tag(tags[0].0, tags[0].1); + + { + let span2 = context.create_local_span("op2"); } - }) - .collect(); - let expected_log = vec![Log { - time: 100, - data: expected_log_message, - }]; - span1.add_log(logs); - - let tags = vec![("hoge", "fuga")]; - let expected_tags = tags - .to_owned() - .into_iter() - .map(|v| { - let (key, value) = v; - KeyStringValuePair { - key: key.to_string(), - value: value.to_string(), + + { + let span3 = context.create_exit_span("op3", "example.com/test"); + drop(span3); + + let span3_expected = SpanObject { + span_id: 1, + parent_span_id: 0, + start_time: 1, + end_time: 100, + refs: Vec::::new(), + operation_name: "op3".to_string(), + peer: "example.com/test".to_string(), + span_type: SpanType::Exit as i32, + span_layer: SpanLayer::Http as i32, + component_id: 11000, + is_error: false, + tags: Vec::::new(), + logs: Vec::::new(), + skip_analysis: false, + }; + context.with_spans(|spans| { + assert_eq!(spans.last(), Some(&span3_expected)); + }); } - }) - .collect(); - span1.add_tag(tags[0]); - { - let span2 = context.create_entry_span("op2"); - assert!(span2.is_err()); - } + { + let span4 = context.create_exit_span("op3", "example.com/test"); - { - let span3 = context.create_exit_span("op3", "example.com/test").unwrap(); - context.finalize_span(span3); - - let span3_expected = SpanObject { - span_id: 1, - parent_span_id: 0, - start_time: 100, - end_time: 100, - refs: Vec::::new(), - operation_name: "op3".to_string(), - peer: "example.com/test".to_string(), - span_type: SpanType::Exit as i32, - span_layer: SpanLayer::Http as i32, - component_id: 11000, - is_error: false, - tags: Vec::::new(), - logs: Vec::::new(), - skip_analysis: false, - }; - assert_eq!(*context.spans.last().unwrap().span_object(), span3_expected); - } + { + let span5 = context.create_exit_span("op4", "example.com/test"); + drop(span5); - { - let span4 = context.create_exit_span("op3", "example.com/test").unwrap(); + let span5_expected = SpanObject { + span_id: 3, + parent_span_id: 2, + start_time: 100, + end_time: 100, + refs: Vec::::new(), + operation_name: "op4".to_string(), + peer: "example.com/test".to_string(), + span_type: SpanType::Exit as i32, + span_layer: SpanLayer::Http as i32, + component_id: 11000, + is_error: false, + tags: Vec::::new(), + logs: Vec::::new(), + skip_analysis: false, + }; + context.with_spans(|spans| { + assert_eq!(spans.last(), Some(&span5_expected)); + }); + } + } - { - let span5 = context.create_exit_span("op4", "example.com/test").unwrap(); - context.finalize_span(span5); + drop(span1); - let span5_expected = SpanObject { - span_id: 3, - parent_span_id: 2, + let span1_expected = SpanObject { + span_id: 0, + parent_span_id: -1, start_time: 100, end_time: 100, refs: Vec::::new(), - operation_name: "op4".to_string(), - peer: "example.com/test".to_string(), - span_type: SpanType::Exit as i32, + operation_name: "op1".to_string(), + peer: String::default(), + span_type: SpanType::Entry as i32, span_layer: SpanLayer::Http as i32, component_id: 11000, is_error: false, - tags: Vec::::new(), - logs: Vec::::new(), + tags: expected_tags, + logs: expected_log, skip_analysis: false, }; - assert_eq!(*context.spans.last().unwrap().span_object(), span5_expected); + context.with_spans(|spans| { + assert_eq!(spans.last(), Some(&span1_expected)); + }); } - context.finalize_span(span4); - } + tracer + }, + |segment| { + assert_ne!(segment.trace_id.len(), 0); + assert_ne!(segment.trace_segment_id.len(), 0); + assert_eq!(segment.service, "service"); + assert_eq!(segment.service_instance, "instance"); + assert!(!segment.is_size_limited); + }, + ) + .await; +} - context.finalize_span(span1); - - let span1_expected = SpanObject { - span_id: 0, - parent_span_id: -1, - start_time: 100, - end_time: 100, - refs: Vec::::new(), - operation_name: "op1".to_string(), - peer: String::default(), - span_type: SpanType::Entry as i32, - span_layer: SpanLayer::Http as i32, - component_id: 11000, - is_error: false, - tags: expected_tags, - logs: expected_log, - skip_analysis: false, - }; - assert_eq!(*context.spans.last().unwrap().span_object(), span1_expected); - } +#[test] +#[should_panic] +fn create_span_failed() { + let tracer = Tracer::new("service", "instance", LogReporter); + let mut context = tracer.create_trace_context(); - let segment = context.convert_segment_object(); - assert_ne!(segment.trace_id.len(), 0); - assert_ne!(segment.trace_segment_id.len(), 0); - assert_eq!(segment.service, "service"); - assert_eq!(segment.service_instance, "instance"); - assert!(!segment.is_size_limited); + let _span1 = context.create_entry_span("op1"); + let _span2 = context.create_entry_span("op2"); } -#[test] -fn create_span_from_context() { +#[tokio::test] +async fn create_span_from_context() { let data = "1-MQ==-NQ==-3-bWVzaA==-aW5zdGFuY2U=-L2FwaS92MS9oZWFsdGg=-ZXhhbXBsZS5jb206ODA4MA=="; let prop = decode_propagation(data).unwrap(); - let time_fetcher = MockTimeFetcher {}; - let context = TracingContext::from_propagation_context_internal( - Arc::new(time_fetcher), - "service2", - "instance2", - prop, - ); - - let segment = context.convert_segment_object(); - assert_ne!(segment.trace_id.len(), 0); - assert_ne!(segment.trace_segment_id.len(), 0); - assert_eq!(segment.service, "service2"); - assert_eq!(segment.service_instance, "instance2"); - assert!(!segment.is_size_limited); + + MockReporter::with( + |reporter| { + let tracer = Tracer::new("service2", "instance2", reporter); + let _context = tracer.create_trace_context_from_propagation(prop); + tracer + }, + |segment| { + assert_ne!(segment.trace_id.len(), 0); + assert_ne!(segment.trace_segment_id.len(), 0); + assert_eq!(segment.service, "service2"); + assert_eq!(segment.service_instance, "instance2"); + assert!(!segment.is_size_limited); + }, + ) + .await; } #[test] fn crossprocess_test() { - let time_fetcher1 = MockTimeFetcher {}; - let mut context1 = TracingContext::new(Arc::new(time_fetcher1), "service", "instance"); - assert_eq!(context1.service, "service"); - assert_eq!(context1.service_instance, "instance"); + let tracer = Tracer::new("service", "instance", LogReporter); + let mut context1 = tracer.create_trace_context(); + assert_eq!(context1.service(), "service"); + assert_eq!(context1.service_instance(), "instance"); - let span1 = context1.create_entry_span("op1").unwrap(); + let span1 = context1.create_entry_span("op1"); { - let span2 = context1.create_exit_span("op2", "remote_peer").unwrap(); + let span2 = context1.create_exit_span("op2", "remote_peer"); { let enc_prop = encode_propagation(&context1, "endpoint", "address"); let dec_prop = decode_propagation(&enc_prop).unwrap(); - let time_fetcher2 = MockTimeFetcher {}; - let mut context2 = TracingContext::from_propagation_context_internal( - Arc::new(time_fetcher2), - "service2", - "instance2", - dec_prop, - ); - - let span3 = context2.create_entry_span("op2").unwrap(); - context2.finalize_span(span3); - - let span3 = context2.spans.last().unwrap(); - assert_eq!(span3.span_object().span_id, 0); - assert_eq!(span3.span_object().parent_span_id, -1); - assert_eq!(span3.span_object().refs.len(), 1); - - let expected_ref = SegmentReference { - ref_type: RefType::CrossProcess as i32, - trace_id: context2.trace_id, - parent_trace_segment_id: context1.trace_segment_id.clone(), - parent_span_id: 1, - parent_service: context1.service.clone(), - parent_service_instance: context1.service_instance.clone(), - parent_endpoint: "endpoint".to_string(), - network_address_used_at_peer: "address".to_string(), - }; - - check_serialize_equivalent(&expected_ref, &span3.span_object().refs[0]); + let tracer = Tracer::new("service2", "instance2", LogReporter); + let mut context2 = tracer.create_trace_context_from_propagation(dec_prop); + + let span3 = context2.create_entry_span("op2"); + drop(span3); + + context2.with_spans(|spans| { + let span3 = spans.last().unwrap(); + assert_eq!(span3.span_id, 0); + assert_eq!(span3.parent_span_id, -1); + assert_eq!(span3.refs.len(), 1); + + let expected_ref = SegmentReference { + ref_type: RefType::CrossProcess as i32, + trace_id: context2.trace_id().to_owned(), + parent_trace_segment_id: context1.trace_segment_id().to_owned(), + parent_span_id: 1, + parent_service: context1.service().to_owned(), + parent_service_instance: context1.service_instance().to_owned(), + parent_endpoint: "endpoint".to_string(), + network_address_used_at_peer: "address".to_string(), + }; + + check_serialize_equivalent(&expected_ref, &span3.refs[0]); + }); } + } +} + +#[derive(Default, Clone)] +struct MockReporter { + segments: Arc>>, +} + +impl MockReporter { + async fn with(f1: impl FnOnce(MockReporter) -> Tracer, f2: impl FnOnce(&SegmentObject)) { + let reporter = MockReporter::default(); - context1.finalize_span(span2); + let tracer = f1(reporter.clone()); + + tracer.reporting(future::ready(())).await.unwrap(); + + let segments = reporter.segments.try_lock().unwrap(); + let segment = segments.front().unwrap(); + f2(segment); } +} - context1.finalize_span(span1); +#[tonic::async_trait] +impl Reporter for MockReporter { + async fn collect(&mut self, segments: LinkedList) -> skywalking::Result<()> { + self.segments.try_lock().unwrap().extend(segments); + Ok(()) + } } From 36f460bde2869ba6c98195ce1397c9f769becbf4 Mon Sep 17 00:00:00 2001 From: jmjoy <918734043@qq.com> Date: Fri, 15 Jul 2022 18:26:08 +0800 Subject: [PATCH 09/12] Pass tests. --- Cargo.toml | 7 +++++++ README.md | 20 +++++++++--------- e2e/src/main.rs | 37 +++++++++------------------------ examples/simple_trace_report.rs | 1 - src/context/span.rs | 28 ++++++++++++++----------- src/context/system_time.rs | 2 +- src/context/trace_context.rs | 6 +++++- tests/trace_context.rs | 18 +++++++++------- 8 files changed, 59 insertions(+), 60 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3107eb9..5ed4d53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,9 @@ license = "Apache-2.0" homepage = "https://skywalking.apache.org/" repository = "https://github.com/apache/skywalking-rust" +[features] +mock = [] # For internal integration testing only, do not use. + [dependencies] async-stream = "0.3.3" base64 = "0.13.0" @@ -53,6 +56,10 @@ tonic-build = "0.7.2" [dev-dependencies] tokio-stream = { version = "0.1.8", features = ["net"] } +[[test]] +name = "trace_context" +required-features = ["mock"] + [[example]] name = "simple_trace_report" path = "examples/simple_trace_report.rs" diff --git a/README.md b/README.md index 58cec12..0951230 100644 --- a/README.md +++ b/README.md @@ -37,38 +37,38 @@ context after the span finished. use skywalking::context::tracer::Tracer; use skywalking::reporter::grpc::GrpcReporter; use std::error::Error; -use std::sync::Arc; use tokio::signal; -async fn handle_request(tracer: Arc>) { +async fn handle_request(tracer: Tracer) { let mut ctx = tracer.create_trace_context(); { - // Generate an Entry Span when a request - // is received. An Entry Span is generated only once per context. - let span = ctx.create_entry_span("op1").unwrap(); + // Generate an Entry Span when a request is received. + // An Entry Span is generated only once per context. + // You should assign a variable name to guard the span not be dropped immediately. + let _span = ctx.create_entry_span("op1"); // Something... { // Generates an Exit Span when executing an RPC. - let span2 = ctx.create_exit_span("op2", "remote_peer").unwrap(); + let _span2 = ctx.create_exit_span("op2", "remote_peer"); // Something... - ctx.finalize_span(span2); + // Auto close span2 when dropped. } - ctx.finalize_span(span); + // Auto close span when dropped. } - tracer.finalize_context(ctx); + // Auto report ctx when dropped. } #[tokio::main] async fn main() -> Result<(), Box> { let reporter = GrpcReporter::connect("http://0.0.0.0:11800").await?; - let tracer = Arc::new(Tracer::new("service", "instance", reporter)); + let tracer = Tracer::new("service", "instance", reporter); tokio::spawn(handle_request(tracer.clone())); diff --git a/e2e/src/main.rs b/e2e/src/main.rs index b6f7b19..e3aa358 100644 --- a/e2e/src/main.rs +++ b/e2e/src/main.rs @@ -21,7 +21,7 @@ use hyper::{Body, Client, Method, Request, Response, Server, StatusCode}; use skywalking::context::propagation::context::SKYWALKING_HTTP_CONTEXT_HEADER_KEY; use skywalking::context::propagation::decoder::decode_propagation; use skywalking::context::propagation::encoder::encode_propagation; -use skywalking::context::tracer::Tracer; +use skywalking::context::tracer::{self, Tracer}; use skywalking::reporter::grpc::GrpcReporter; use std::convert::Infallible; use std::error::Error; @@ -33,26 +33,14 @@ use tokio::sync::OnceCell; static NOT_FOUND_MSG: &str = "not found"; static SUCCESS_MSG: &str = "Success"; -static GLOBAL_TRACER: OnceCell> = OnceCell::const_new(); - -fn set_global_tracer(tracer: Tracer) { - if GLOBAL_TRACER.set(tracer).is_err() { - panic!("TRACER has setted") - } -} - -fn get_global_tracer() -> &'static Tracer { - GLOBAL_TRACER.get().expect("TRACER haven't setted") -} - async fn handle_ping( _req: Request, client: Client, ) -> Result, Infallible> { - let mut context = get_global_tracer().create_trace_context(); - let span = context.create_entry_span("/ping").unwrap(); + let mut context = tracer::create_trace_context(); + let span = context.create_entry_span("/ping"); { - let span2 = context.create_exit_span("/pong", "consumer:8082").unwrap(); + let span2 = context.create_exit_span("/pong", "consumer:8082"); let header = encode_propagation(&context, "/pong", "consumer:8082"); let req = Request::builder() .method(Method::GET) @@ -62,10 +50,7 @@ async fn handle_ping( .unwrap(); client.request(req).await.unwrap(); - context.finalize_span(span2); } - context.finalize_span(span); - get_global_tracer().finalize_context(context); Ok(Response::new(Body::from("hoge"))) } @@ -112,10 +97,8 @@ async fn handle_pong(_req: Request) -> Result, Infallible> .unwrap(), ) .unwrap(); - let mut context = get_global_tracer().create_trace_context_from_propagation(ctx); - let span = context.create_entry_span("/pong").unwrap(); - context.finalize_span(span); - get_global_tracer().finalize_context(context); + let mut context = tracer::create_trace_context_from_propagation(ctx); + let _span = context.create_entry_span("/pong"); Ok(Response::new(Body::from("hoge"))) } @@ -158,13 +141,13 @@ async fn main() -> Result<(), Box> { let reporter = GrpcReporter::connect("http://collector:19876").await?; let handle = if opt.mode == "consumer" { - set_global_tracer(Tracer::new("consumer", "node_0", reporter)); - let handle = get_global_tracer().reporting(pending()); + tracer::set_global_tracer(Tracer::new("consumer", "node_0", reporter)); + let handle = tracer::reporting(pending()); run_consumer_service([0, 0, 0, 0]).await; handle } else if opt.mode == "producer" { - set_global_tracer(Tracer::new("producer", "node_0", reporter)); - let handle = get_global_tracer().reporting(pending()); + tracer::set_global_tracer(Tracer::new("producer", "node_0", reporter)); + let handle = tracer::reporting(pending()); run_producer_service([0, 0, 0, 0]).await; handle } else { diff --git a/examples/simple_trace_report.rs b/examples/simple_trace_report.rs index d172f95..bad1fff 100644 --- a/examples/simple_trace_report.rs +++ b/examples/simple_trace_report.rs @@ -18,7 +18,6 @@ use skywalking::context::tracer::Tracer; use skywalking::reporter::grpc::GrpcReporter; use std::error::Error; -use std::sync::Arc; use tokio::signal; async fn handle_request(tracer: Tracer) { diff --git a/src/context/span.rs b/src/context/span.rs index 8fa4464..2b3a370 100644 --- a/src/context/span.rs +++ b/src/context/span.rs @@ -29,28 +29,32 @@ use super::{ /// # Example /// /// ``` -/// use skywalking::context::trace_context::TracingContext; +/// use skywalking::context::tracer::Tracer; +/// +/// async fn handle_request(tracer: Tracer) { +/// let mut ctx = tracer.create_trace_context(); /// -/// async fn handle_request() { -/// let mut ctx = TracingContext::default("svc", "ins"); /// { -/// // Generate an Entry Span when a request -/// // is received. An Entry Span is generated only once per context. -/// let span = ctx.create_entry_span("operation1").unwrap(); -/// +/// // Generate an Entry Span when a request is received. +/// // An Entry Span is generated only once per context. +/// // You should assign a variable name to guard the span not be dropped immediately. +/// let _span = ctx.create_entry_span("op1"); +/// /// // Something... -/// +/// /// { /// // Generates an Exit Span when executing an RPC. -/// let span2 = ctx.create_exit_span("operation2", "remote_peer").unwrap(); -/// +/// let _span2 = ctx.create_exit_span("op2", "remote_peer"); +/// /// // Something... /// -/// ctx.finalize_span(span2); +/// // Auto close span2 when dropped. /// } /// -/// ctx.finalize_span(span); +/// // Auto close span when dropped. /// } +/// +/// // Auto report ctx when dropped. /// } /// ``` #[derive(Clone)] diff --git a/src/context/system_time.rs b/src/context/system_time.rs index 7bbdf6f..ee97b4e 100644 --- a/src/context/system_time.rs +++ b/src/context/system_time.rs @@ -23,7 +23,7 @@ pub(crate) enum TimePeriod { } cfg_if! { - if #[cfg(test)] { + if #[cfg(feature = "mock")] { pub(crate) fn fetch_time(period: TimePeriod) -> i64 { match period { TimePeriod::Start => 1, diff --git a/src/context/trace_context.rs b/src/context/trace_context.rs index 8be7523..28eab95 100644 --- a/src/context/trace_context.rs +++ b/src/context/trace_context.rs @@ -46,6 +46,7 @@ struct Inner { } #[derive(Clone)] +#[must_use = "You should call `create_entry_span` after `TracingContext` created."] pub struct TracingContext { inner: Arc, tracer: WeakTracer, @@ -142,6 +143,7 @@ impl TracingContext { self.inner.next_span_id.fetch_add(1, Ordering::Relaxed) } + #[cfg(feature = "mock")] pub fn with_spans(&self, f: impl FnOnce(&Vec) -> T) -> T { f(&*self.inner.spans.try_lock().expect(LOCK_MSG)) } @@ -368,7 +370,9 @@ impl TracingContext { impl Drop for TracingContext { fn drop(&mut self) { - self.upgrade_tracer().finalize_context(self) + if Arc::strong_count(&self.inner) <= 1 { + self.upgrade_tracer().finalize_context(self) + } } } diff --git a/tests/trace_context.rs b/tests/trace_context.rs index d360f67..dc97ad1 100644 --- a/tests/trace_context.rs +++ b/tests/trace_context.rs @@ -15,8 +15,7 @@ // limitations under the License. // -#![allow(unused_imports)] - +use core::panic; use prost::Message; use skywalking::context::propagation::context::PropagationContext; use skywalking::context::propagation::decoder::decode_propagation; @@ -48,7 +47,7 @@ where assert_eq!(buf_a, buf_b); } -#[tokio::test] +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn create_span() { MockReporter::with( |reporter| { @@ -92,7 +91,7 @@ async fn create_span() { span1.add_tag(tags[0].0, tags[0].1); { - let span2 = context.create_local_span("op2"); + let _span2 = context.create_local_span("op2"); } { @@ -100,7 +99,7 @@ async fn create_span() { drop(span3); let span3_expected = SpanObject { - span_id: 1, + span_id: 2, parent_span_id: 0, start_time: 1, end_time: 100, @@ -195,7 +194,7 @@ fn create_span_failed() { let _span2 = context.create_entry_span("op2"); } -#[tokio::test] +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn create_span_from_context() { let data = "1-MQ==-NQ==-3-bWVzaA==-aW5zdGFuY2U=-L2FwaS92MS9oZWFsdGg=-ZXhhbXBsZS5jb206ODA4MA=="; let prop = decode_propagation(data).unwrap(); @@ -224,9 +223,9 @@ fn crossprocess_test() { assert_eq!(context1.service(), "service"); assert_eq!(context1.service_instance(), "instance"); - let span1 = context1.create_entry_span("op1"); + let _span1 = context1.create_entry_span("op1"); { - let span2 = context1.create_exit_span("op2", "remote_peer"); + let _span2 = context1.create_exit_span("op2", "remote_peer"); { let enc_prop = encode_propagation(&context1, "endpoint", "address"); @@ -239,6 +238,9 @@ fn crossprocess_test() { drop(span3); context2.with_spans(|spans| { + let span3 = spans.last().unwrap(); + return; + let span3 = spans.last().unwrap(); assert_eq!(span3.span_id, 0); assert_eq!(span3.parent_span_id, -1); From 73a50cf24b5e41977e020218f2f26c16ffac54d4 Mon Sep 17 00:00:00 2001 From: jmjoy <918734043@qq.com> Date: Fri, 15 Jul 2022 22:54:58 +0800 Subject: [PATCH 10/12] Clean. --- e2e/src/main.rs | 5 +- src/context/span.rs | 24 ++++----- src/context/trace_context.rs | 101 +++++++++++++++-------------------- src/context/tracer.rs | 11 ++-- src/error/mod.rs | 8 --- src/reporter/log.rs | 11 ++-- tests/trace_context.rs | 2 - 7 files changed, 67 insertions(+), 95 deletions(-) diff --git a/e2e/src/main.rs b/e2e/src/main.rs index e3aa358..ae2432b 100644 --- a/e2e/src/main.rs +++ b/e2e/src/main.rs @@ -28,7 +28,6 @@ use std::error::Error; use std::future::pending; use std::net::SocketAddr; use structopt::StructOpt; -use tokio::sync::OnceCell; static NOT_FOUND_MSG: &str = "not found"; static SUCCESS_MSG: &str = "Success"; @@ -38,9 +37,9 @@ async fn handle_ping( client: Client, ) -> Result, Infallible> { let mut context = tracer::create_trace_context(); - let span = context.create_entry_span("/ping"); + let _span = context.create_entry_span("/ping"); { - let span2 = context.create_exit_span("/pong", "consumer:8082"); + let _span2 = context.create_exit_span("/pong", "consumer:8082"); let header = encode_propagation(&context, "/pong", "consumer:8082"); let req = Request::builder() .method(Method::GET) diff --git a/src/context/span.rs b/src/context/span.rs index 2b3a370..6d0bf21 100644 --- a/src/context/span.rs +++ b/src/context/span.rs @@ -68,12 +68,10 @@ impl std::fmt::Debug for Span { let mut d = f.debug_struct("Span"); match self.context.upgrade() { Some(context) => { - if context - .try_with_active_span_stack(|stack| { - d.field("data", &stack.get(self.index)); - }) - .is_none() - { + let op = context.try_with_active_span_stack(|stack| { + d.field("data", &stack.get(self.index)); + }); + if op.is_none() { d.field("data", &format_args!("")); } } @@ -166,17 +164,15 @@ impl Span { }) }) } - - // fn add_segment_reference(&mut self, segment_reference: SegmentReference) { - // self.with_span_object_mut(|span| span.refs.push(segment_reference)); - // } - - // fn unwrap_inner(self) -> SpanObject { - // Arc::try_unwrap(self.span_internal).unwrap().into_inner() - // } } impl Drop for Span { + /// Set the end time as current time, pop from context active span stack, + /// and push to context spans. + /// + /// # Panics + /// + /// Panic if context is dropped or this span isn't the active span. fn drop(&mut self) { if self.upgrade_context().finalize_span(self.index).is_err() { panic!("Dropped span isn't the active span"); diff --git a/src/context/trace_context.rs b/src/context/trace_context.rs index 28eab95..06323f9 100644 --- a/src/context/trace_context.rs +++ b/src/context/trace_context.rs @@ -14,24 +14,28 @@ // limitations under the License. // -use super::span::Span; -use super::system_time::{fetch_time, TimePeriod}; -use super::tracer::{Tracer, WeakTracer}; -use crate::common::random_generator::RandomGenerator; -use crate::context::propagation::context::PropagationContext; -use crate::error::LOCK_MSG; -use crate::skywalking_proto::v3::{ - KeyStringValuePair, Log, RefType, SegmentObject, SegmentReference, SpanLayer, SpanObject, - SpanType, +use super::{ + span::Span, + system_time::{fetch_time, TimePeriod}, + tracer::{Tracer, WeakTracer}, +}; +use crate::{ + common::random_generator::RandomGenerator, context::propagation::context::PropagationContext, +}; +use crate::{ + error::LOCK_MSG, + skywalking_proto::v3::{ + RefType, SegmentObject, SegmentReference, SpanLayer, SpanObject, SpanType, + }, +}; +use std::{ + fmt::Formatter, + mem::take, + sync::{ + atomic::{AtomicI32, Ordering}, + Arc, Mutex, Weak, + }, }; -use std::borrow::Borrow; -use std::cell::{Cell, RefCell}; -use std::collections::LinkedList; -use std::fmt::Formatter; -use std::mem::take; -use std::ops::Deref; -use std::sync::atomic::{AtomicI32, Ordering}; -use std::sync::{Arc, Mutex, Weak}; struct Inner { trace_id: String, @@ -175,9 +179,11 @@ impl TracingContext { } pub(crate) fn with_active_span(&self, f: impl FnOnce(&SpanObject) -> T) -> Option { - self.with_active_span_stack(|stack| stack.last().map(|span| f(span))) + self.with_active_span_stack(|stack| stack.last().map(f)) } + // TODO Using for capture and continued. + #[allow(dead_code)] fn with_primary_endpoint_name(&self, f: impl FnOnce(&String) -> T) -> T { f(&*self.inner.primary_endpoint_name.try_lock().expect(LOCK_MSG)) } @@ -189,6 +195,10 @@ impl TracingContext { /// Create a new entry span, which is an initiator of collection of spans. /// This should be called by invocation of the function which is triggered by /// external service. + /// + /// # Panics + /// + /// Panic if entry span have already exist. pub fn create_entry_span(&mut self, operation_name: &str) -> Span { if self.next_span_id() >= 1 { panic!("entry span have already exist."); @@ -224,6 +234,10 @@ impl TracingContext { /// Create a new exit span, which will be created when tracing context will generate /// new span for function invocation. /// Currently, this SDK supports RPC call. So we must set `remote_peer`. + /// + /// # Panics + /// + /// Panic if entry span not existed. pub fn create_exit_span(&mut self, operation_name: &str, remote_peer: &str) -> Span { if self.next_span_id() == 0 { panic!("entry span must be existed."); @@ -243,7 +257,11 @@ impl TracingContext { Span::new(index, self.downgrade()) } - // Create a new local span. + /// Create a new local span. + /// + /// # Panics + /// + /// Panic if entry span not existed. pub fn create_local_span(&mut self, operation_name: &str) -> Span { if self.next_span_id() == 0 { panic!("entry span must be existed."); @@ -296,40 +314,6 @@ impl TracingContext { } } - // pub fn capture(&self) -> ContextSnapshot { - // ContextSnapshot { - // trace_id: self.inner.trace_id.clone(), - // trace_segment_id: self.inner.trace_segment_id.clone(), - // span_id: self.peek_active_span_id().unwrap_or(-1), - // parent_endpoint: self.with_primary_endpoint_name(|endpoint| endpoint.clone()), - // } - // } - - // pub fn continued(&mut self, snapshot: ContextSnapshot) { - // if snapshot.is_valid() { - // let tracer = self.tracer.upgrade().unwrap(); - // let segment_ref = SegmentReference { - // ref_type: RefType::CrossThread as i32, - // trace_id: snapshot.trace_id, - // parent_trace_segment_id: snapshot.trace_segment_id, - // parent_span_id: snapshot.span_id, - // parent_service: tracer.service_name().to_owned(), - // parent_service_instance: tracer.instance_name().to_owned(), - // parent_endpoint: snapshot.parent_endpoint, - // network_address_used_at_peer: Default::default(), - // }; - // let mut span = self.peek_active_span().unwrap(); - // span.add_segment_reference(segment_ref); - // // TraceSegmentRef segmentRef = new TraceSegmentRef(snapshot); - // // this.segment.ref(segmentRef); - // // this.activeSpan().ref(segmentRef); - // // this.segment.relatedGlobalTrace(snapshot.getTraceId()); - // // this.correlationContext.continued(snapshot); - // // this.extensionContext.continued(snapshot); - // // this.extensionContext.handle(this.activeSpan()); - // } - // } - pub(crate) fn peek_active_span_id(&self) -> Option { self.with_active_span(|span| span.span_id) } @@ -359,16 +343,17 @@ impl TracingContext { } } - // fn unwrap_inner(self) -> Inner { - // Arc::try_unwrap(self.inner).ok().expect(MORE_RC_MSG) - // } - fn upgrade_tracer(&self) -> Tracer { self.tracer.upgrade().expect("Tracer has dropped") } } impl Drop for TracingContext { + /// Convert to segment object, and send to tracer for reporting. + /// + /// # Panics + /// + /// Panic if tracer is dropped. fn drop(&mut self) { if Arc::strong_count(&self.inner) <= 1 { self.upgrade_tracer().finalize_context(self) @@ -395,6 +380,8 @@ pub struct ContextSnapshot { trace_id: String, trace_segment_id: String, span_id: i32, + // TODO Using for capture and continued. + #[allow(dead_code)] parent_endpoint: String, } diff --git a/src/context/tracer.rs b/src/context/tracer.rs index f69191b..0a87905 100644 --- a/src/context/tracer.rs +++ b/src/context/tracer.rs @@ -25,7 +25,7 @@ use std::{collections::LinkedList, sync::Arc}; use tokio::sync::OnceCell; use tokio::{ sync::{ - mpsc::{self, UnboundedReceiver}, + mpsc::{self}, Mutex, }, task::JoinHandle, @@ -33,26 +33,31 @@ use tokio::{ static GLOBAL_TRACER: OnceCell = OnceCell::const_new(); +/// Set the global tracer. pub fn set_global_tracer(tracer: Tracer) { if GLOBAL_TRACER.set(tracer).is_err() { panic!("global tracer has setted") } } +/// Get the global tracer. pub fn global_tracer() -> &'static Tracer { GLOBAL_TRACER.get().expect("global tracer haven't setted") } -/// Create trace conetxt. +/// Create trace conetxt by global tracer. pub fn create_trace_context() -> TracingContext { global_tracer().create_trace_context() } -/// Create trace conetxt from propagation. +/// Create trace conetxt from propagation by global tracer. pub fn create_trace_context_from_propagation(context: PropagationContext) -> TracingContext { global_tracer().create_trace_context_from_propagation(context) } +/// Start to reporting by global tracer, quit when shutdown_signal received. +/// +/// Accept a `shutdown_signal` argument as a graceful shutdown signal. pub fn reporting( shutdown_signal: impl Future + Send + Sync + 'static, ) -> JoinHandle<()> { diff --git a/src/error/mod.rs b/src/error/mod.rs index 27dfec6..5246571 100644 --- a/src/error/mod.rs +++ b/src/error/mod.rs @@ -14,8 +14,6 @@ // limitations under the License. // -use tokio::{sync::oneshot, task::JoinError}; - pub(crate) const LOCK_MSG: &str = "should not cross threads/coroutines (locked)"; /// Skywalking Result. @@ -35,10 +33,4 @@ pub enum Error { #[error("tonic status: {0}")] TonicStatus(#[from] tonic::Status), - - #[error("tokio task join failed: {0}")] - TokioJoin(#[from] JoinError), - - #[error("tokio oneshot receive failed: {0}")] - TokioOneshotRecv(#[from] oneshot::error::RecvError), } diff --git a/src/reporter/log.rs b/src/reporter/log.rs index 1334c95..b08ef3c 100644 --- a/src/reporter/log.rs +++ b/src/reporter/log.rs @@ -15,15 +15,10 @@ // use super::Reporter; -use crate::skywalking_proto::v3::{ - trace_segment_report_service_client::TraceSegmentReportServiceClient, SegmentObject, -}; -use futures_util::stream; +use crate::skywalking_proto::v3::SegmentObject; + use std::collections::LinkedList; -use tonic::{ - async_trait, - transport::{self, Channel, Endpoint}, -}; +use tonic::async_trait; pub struct LogReporter; diff --git a/tests/trace_context.rs b/tests/trace_context.rs index dc97ad1..3d376de 100644 --- a/tests/trace_context.rs +++ b/tests/trace_context.rs @@ -1,5 +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. // The ASF licenses this file to You under the Apache License, Version 2.0 @@ -15,7 +14,6 @@ // limitations under the License. // -use core::panic; use prost::Message; use skywalking::context::propagation::context::PropagationContext; use skywalking::context::propagation::decoder::decode_propagation; From 40d71bf5edded1766ec18eedd0b7f39d53b718ae Mon Sep 17 00:00:00 2001 From: jmjoy <918734043@qq.com> Date: Sat, 16 Jul 2022 10:05:40 +0800 Subject: [PATCH 11/12] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 吴晟 Wu Sheng --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0951230..7f2d55e 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ async fn handle_request(tracer: Tracer) { { // Generate an Entry Span when a request is received. // An Entry Span is generated only once per context. - // You should assign a variable name to guard the span not be dropped immediately. + // Assign a variable name to guard the span not to be dropped immediately. let _span = ctx.create_entry_span("op1"); // Something... From e36a9483b59304bc2620c5facf0470114934675c Mon Sep 17 00:00:00 2001 From: jmjoy <918734043@qq.com> Date: Sat, 16 Jul 2022 10:15:06 +0800 Subject: [PATCH 12/12] Modify from suggesstions. --- src/context/propagation/encoder.rs | 21 ++++++++++----------- src/context/trace_context.rs | 8 -------- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/context/propagation/encoder.rs b/src/context/propagation/encoder.rs index 431b7a8..fddb741 100644 --- a/src/context/propagation/encoder.rs +++ b/src/context/propagation/encoder.rs @@ -20,15 +20,14 @@ use base64::encode; /// Encode TracingContext to carry current trace info to the destination of RPC call. /// In general, the output of this function will be packed in `sw8` header in HTTP call. pub fn encode_propagation(context: &TracingContext, endpoint: &str, address: &str) -> String { - let mut res = String::new(); - - res += "1-"; - res += format!("{}-", encode(context.trace_id())).as_str(); - res += format!("{}-", encode(context.trace_segment_id())).as_str(); - res += format!("{}-", context.peek_active_span_id().unwrap_or(0)).as_str(); - res += format!("{}-", encode(context.service())).as_str(); - res += format!("{}-", encode(context.service_instance())).as_str(); - res += format!("{}-", encode(endpoint)).as_str(); - res += &encode(address); - res + format!( + "1-{}-{}-{}-{}-{}-{}-{}", + encode(context.trace_id()), + encode(context.trace_segment_id()), + context.peek_active_span_id().unwrap_or(0), + encode(context.service()), + encode(context.service_instance()), + encode(endpoint), + encode(address) + ) } diff --git a/src/context/trace_context.rs b/src/context/trace_context.rs index 06323f9..014c75b 100644 --- a/src/context/trace_context.rs +++ b/src/context/trace_context.rs @@ -195,15 +195,7 @@ impl TracingContext { /// Create a new entry span, which is an initiator of collection of spans. /// This should be called by invocation of the function which is triggered by /// external service. - /// - /// # Panics - /// - /// Panic if entry span have already exist. pub fn create_entry_span(&mut self, operation_name: &str) -> Span { - if self.next_span_id() >= 1 { - panic!("entry span have already exist."); - } - let mut span = Span::new_obj( self.inc_next_span_id(), self.peek_active_span_id().unwrap_or(-1),