You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2020/02/29 13:13:23 UTC

[skywalking-rust] branch master updated: Finish the tracing core and report bridge trait.

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

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


The following commit(s) were added to refs/heads/master by this push:
     new f9b7e81  Finish the tracing core and report bridge trait.
f9b7e81 is described below

commit f9b7e815416df70e77a8b01e918d1f8b9ccb456a
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Sat Feb 29 21:13:13 2020 +0800

    Finish the tracing core and report bridge trait.
---
 tracing-core/Cargo.toml           |  2 +-
 tracing-core/src/context.rs       | 85 +++++++++++++++++++++++++++++++++++----
 tracing-core/src/id.rs            |  4 +-
 tracing-core/src/lib.rs           |  2 +
 tracing-core/src/report_bridge.rs | 15 +++++++
 tracing-core/src/span.rs          | 23 ++++++++---
 6 files changed, 114 insertions(+), 17 deletions(-)

diff --git a/tracing-core/Cargo.toml b/tracing-core/Cargo.toml
index 8010bb8..6751303 100644
--- a/tracing-core/Cargo.toml
+++ b/tracing-core/Cargo.toml
@@ -3,7 +3,7 @@ name = "skywalking-core"
 version = "0.1.0"
 authors = ["Apache Software Foundation (ASF)"]
 edition = "2018"
-description = "SkyWalking Rust Agent provides observability capability for Rust App and Library, including tracing, metrics, topology map for distributed system and alert."
+description = "SkyWalking tracing core APIs. Provide the way to build SkyWalking native format traces/spans and propagated context."
 license = "Apache 2.0"
 
 [dependencies]
diff --git a/tracing-core/src/context.rs b/tracing-core/src/context.rs
index 6c112d6..e9f1de5 100644
--- a/tracing-core/src/context.rs
+++ b/tracing-core/src/context.rs
@@ -1,4 +1,7 @@
-use crate::{Span, TracingSpan};
+use std::rc::Rc;
+
+use crate::{ID, Reporter, Span, TracingSpan};
+use crate::id::IDGenerator;
 
 /// Context represents the context of a tracing process.
 /// All new span belonging to this tracing context should be created through this context.
@@ -12,16 +15,28 @@ pub trait Context {
 pub struct TracingContext {
     /// Span id sequence. Indicate the number of created spans.
     next_seq: i32,
+
+    primary_trace_id: ID,
+    self_generated_id: bool,
     finished_spans: Vec<Box<dyn Span>>,
 }
 
 impl TracingContext {
     /// Create a new instance
-    pub fn new() -> Box<dyn Context> {
-        Box::new(TracingContext {
-            next_seq: -1,
-            finished_spans: Vec::new(),
-        })
+    pub fn new(reporter: &dyn Reporter) -> Option<TracingContext> {
+        let instance_id = reporter.service_instance_id();
+        match instance_id {
+            None => { None }
+            Some(id) => {
+                Some(TracingContext {
+                    next_seq: -1,
+                    primary_trace_id: IDGenerator::new_id(id),
+                    self_generated_id: true,
+                    finished_spans: Vec::new(),
+                }
+                )
+            }
+        }
     }
 
     /// Fetch the next id for new span
@@ -64,11 +79,16 @@ impl Context for TracingContext {
 
 #[cfg(test)]
 mod context_tests {
-    use crate::TracingContext;
+    use std::rc::Rc;
+    use std::sync::mpsc;
+    use std::sync::mpsc::{Receiver, Sender};
+
+    use crate::{Context, Reporter, TracingContext};
 
     #[test]
     fn test_context_stack() {
-        let mut context = TracingContext::new();
+        let reporter = MockReporter::new();
+        let mut context = TracingContext::new(&reporter).unwrap();
         let span1 = context.create_entry_span(String::from("op1"), None);
         {
             assert_eq!(span1.span_id(), 0);
@@ -83,5 +103,54 @@ mod context_tests {
             context.finish_span(span2);
         }
         context.finish_span(span1);
+
+        reporter.report_trace(context);
+        // context has moved into reporter. Can't be used again.
+
+        let received_context = reporter.recv.recv().unwrap();
+        assert_eq!(received_context.finished_spans.len(), 3);
+    }
+
+    #[test]
+    fn test_no_context() {
+        let context = TracingContext::new(&MockRegisterPending {});
+        assert_eq!(context.is_none(), true);
+    }
+
+    struct MockReporter {
+        sender: Box<Sender<TracingContext>>,
+        recv: Box<Receiver<TracingContext>>,
+    }
+
+    impl MockReporter {
+        fn new() -> Self {
+            let (tx, rx) = mpsc::channel();
+            MockReporter {
+                sender: Box::new(tx),
+                recv: Box::new(rx),
+            }
+        }
+    }
+
+    impl Reporter for MockReporter {
+        fn service_instance_id(&self) -> Option<i32> {
+            Some(1)
+        }
+
+        fn report_trace(&self, finished_context: TracingContext) {
+            self.sender.send(finished_context);
+        }
+    }
+
+    struct MockRegisterPending {}
+
+    impl Reporter for MockRegisterPending {
+        fn service_instance_id(&self) -> Option<i32> {
+            None
+        }
+
+        fn report_trace(&self, finished_context: TracingContext) {
+            unimplemented!()
+        }
     }
 }
\ No newline at end of file
diff --git a/tracing-core/src/id.rs b/tracing-core/src/id.rs
index b7b81a2..afc5c40 100644
--- a/tracing-core/src/id.rs
+++ b/tracing-core/src/id.rs
@@ -1,8 +1,6 @@
 use std::hash::Hash;
-use std::thread;
 use std::time::SystemTime;
-
-use rand::{Rng, RngCore};
+use rand::RngCore;
 
 pub struct IDGenerator {}
 
diff --git a/tracing-core/src/lib.rs b/tracing-core/src/lib.rs
index be6a9ef..46fecbd 100644
--- a/tracing-core/src/lib.rs
+++ b/tracing-core/src/lib.rs
@@ -1,6 +1,7 @@
 pub use context::Context;
 pub use context::TracingContext;
 pub use id::ID;
+pub use report_bridge::Reporter;
 pub use span::Span;
 pub use span::TracingSpan;
 pub use tag::Tag;
@@ -9,4 +10,5 @@ pub mod span;
 pub mod context;
 pub mod tag;
 pub mod id;
+pub mod report_bridge;
 
diff --git a/tracing-core/src/report_bridge.rs b/tracing-core/src/report_bridge.rs
new file mode 100644
index 0000000..d07e9bc
--- /dev/null
+++ b/tracing-core/src/report_bridge.rs
@@ -0,0 +1,15 @@
+use crate::TracingContext;
+
+///Report bridge defines the traits for the skywalking-report
+
+/// Register implementation communicate with the SkyWalking OAP backend.
+/// It does metadata register, traces report, and runtime status report or interaction.
+pub trait Reporter {
+    /// Return the registered service id
+    /// If haven't registered successfully, return None.
+    fn service_instance_id(&self) -> Option<i32>;
+
+    /// Move the finished and inactive context to the reporter.
+    /// The reporter should use async way to transport the data to the backend through HTTP, gRPC or SkyWalking forwarder.
+    fn report_trace(&self, finished_context: TracingContext);
+}
diff --git a/tracing-core/src/span.rs b/tracing-core/src/span.rs
index 623783e..b42f3ad 100644
--- a/tracing-core/src/span.rs
+++ b/tracing-core/src/span.rs
@@ -142,14 +142,15 @@ impl Span for TracingSpan {
 
 #[cfg(test)]
 mod span_tests {
+    use std::rc::Rc;
     use std::time::SystemTime;
 
-    use crate::{Tag, TracingContext};
+    use crate::{Context, Reporter, Tag, TracingContext};
     use crate::span::*;
 
     #[test]
     fn test_span_new() {
-        let mut context = TracingContext::new();
+        let mut context = TracingContext::new(&MockRegister {}).unwrap();
         let mut span = TracingSpan::_new(String::from("op1"), 0, -1);
         assert_eq!(span.parent_span_id, -1);
         assert_eq!(span.span_id, 0);
@@ -167,14 +168,14 @@ mod span_tests {
 
     #[test]
     fn test_new_entry_span() {
-        let mut context = TracingContext::new();
-        let mut span = TracingSpan::new_entry_span(String::from("op1"), 0, 1);
+        let context = TracingContext::new(&MockRegister {}).unwrap();
+        let span = TracingSpan::new_entry_span(String::from("op1"), 0, 1);
         assert_eq!(span.is_entry(), true)
     }
 
     #[test]
     fn test_span_with_tags() {
-        let context = TracingContext::new();
+        let context = TracingContext::new(&MockRegister {}).unwrap();
         let mut span = TracingSpan::new_entry_span(String::from("op1"), 0, 1);
         span.tag(Tag::new(String::from("tag1"), String::from("value1")));
         span.tag(Tag::new(String::from("tag2"), String::from("value2")));
@@ -183,6 +184,18 @@ mod span_tests {
         assert_eq!(tags.len(), 2);
         assert_eq!(tags.get(0).unwrap().key(), "tag1")
     }
+
+    struct MockRegister {}
+
+    impl Reporter for MockRegister {
+        fn service_instance_id(&self) -> Option<i32> {
+            Some(1)
+        }
+
+        fn report_trace(&self, finished_context: TracingContext) {
+            unimplemented!()
+        }
+    }
 }