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 07:36:03 UTC

[skywalking-rust] branch master updated: Add more behaviors to span, including tag.

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 8d77352  Add more behaviors to span, including tag.
8d77352 is described below

commit 8d77352448c22f28f185ca0891582e59e7ddebca
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Sat Feb 29 15:35:50 2020 +0800

    Add more behaviors to span, including tag.
---
 tracing-core/src/context.rs |  63 ++++++++++++++++++---------
 tracing-core/src/lib.rs     |   6 ++-
 tracing-core/src/span.rs    | 102 ++++++++++++++++++++++++++++++++++----------
 tracing-core/src/tag.rs     |  37 ++++++++++++++++
 4 files changed, 163 insertions(+), 45 deletions(-)

diff --git a/tracing-core/src/context.rs b/tracing-core/src/context.rs
index eccce19..6c112d6 100644
--- a/tracing-core/src/context.rs
+++ b/tracing-core/src/context.rs
@@ -3,51 +3,68 @@ use crate::{Span, TracingSpan};
 /// Context represents the context of a tracing process.
 /// All new span belonging to this tracing context should be created through this context.
 pub trait Context {
-    /// Fetch the next id for new span
-    fn next_span_id(&mut self) -> i32;
-    fn create_entry_span(&mut self, operation_name: String, parent: Option<Box<dyn Span>>) -> Box<dyn Span>;
-    fn create_exit_span(&mut self, operation_name: String, parent: Option<Box<dyn Span>>) -> Box<dyn Span>;
-    fn create_local_span(&mut self, operation_name: String, parent: Option<Box<dyn Span>>) -> Box<dyn Span>;
+    fn create_entry_span(&mut self, operation_name: String, parent: Option<&Box<dyn Span>>) -> Box<dyn Span>;
+    fn create_exit_span(&mut self, operation_name: String, parent: Option<&Box<dyn Span>>) -> Box<dyn Span>;
+    fn create_local_span(&mut self, operation_name: String, parent: Option<&Box<dyn Span>>) -> Box<dyn Span>;
+    fn finish_span(&mut self, span: Box<dyn Span>);
 }
 
 pub struct TracingContext {
     /// Span id sequence. Indicate the number of created spans.
     next_seq: i32,
+    finished_spans: Vec<Box<dyn Span>>,
 }
 
 impl TracingContext {
     /// Create a new instance
-    pub fn new() -> Self {
-        TracingContext {
-            next_seq: -1
-        }
+    pub fn new() -> Box<dyn Context> {
+        Box::new(TracingContext {
+            next_seq: -1,
+            finished_spans: Vec::new(),
+        })
     }
-}
 
-/// Default implementation of Context
-impl Context for TracingContext {
     /// Fetch the next id for new span
     fn next_span_id(&mut self) -> i32 {
         self.next_seq = self.next_seq + 1;
         self.next_seq
     }
+}
+
+/// Default implementation of Context
+impl Context for TracingContext {
+    fn create_entry_span(&mut self, operation_name: String, parent: Option<&Box<dyn Span>>) -> Box<dyn Span> {
+        TracingSpan::new_entry_span(operation_name, self.next_span_id(), match parent {
+            None => { -1 }
+            Some(s) => { s.span_id() }
+        })
+    }
 
-    fn create_entry_span(&mut self, operation_name: String, parent: Option<Box<dyn Span>>) -> Box<dyn Span> {
-        TracingSpan::new_entry_span(operation_name, self, parent)
+    fn create_exit_span(&mut self, operation_name: String, parent: Option<&Box<dyn Span>>) -> Box<dyn Span> {
+        TracingSpan::new_exit_span(operation_name, self.next_span_id(), match parent {
+            None => { -1 }
+            Some(s) => { s.span_id() }
+        })
     }
 
-    fn create_exit_span(&mut self, operation_name: String, parent: Option<Box<dyn Span>>) -> Box<dyn Span> {
-        TracingSpan::new_exit_span(operation_name, self, parent)
+    fn create_local_span(&mut self, operation_name: String, parent: Option<&Box<dyn Span>>) -> Box<dyn Span> {
+        TracingSpan::new_local_span(operation_name, self.next_span_id(), match parent {
+            None => { -1 }
+            Some(s) => { s.span_id() }
+        })
     }
 
-    fn create_local_span(&mut self, operation_name: String, parent: Option<Box<dyn Span>>) -> Box<dyn Span> {
-        TracingSpan::new_local_span(operation_name, self, parent)
+    fn finish_span(&mut self, mut span: Box<dyn Span>) {
+        if !span.is_ended() {
+            span.end();
+        }
+        self.finished_spans.push(span);
     }
 }
 
 #[cfg(test)]
 mod context_tests {
-    use crate::{TracingContext, Context};
+    use crate::TracingContext;
 
     #[test]
     fn test_context_stack() {
@@ -55,12 +72,16 @@ mod context_tests {
         let span1 = context.create_entry_span(String::from("op1"), None);
         {
             assert_eq!(span1.span_id(), 0);
-            let span2 = context.create_entry_span(String::from("op2"), Some(span1));
+            let span2 = context.create_entry_span(String::from("op2"), Some(&span1));
             {
                 assert_eq!(span2.span_id(), 1);
-                let span3 = context.create_entry_span(String::from("op3"), Some(span2));
+                let mut span3 = context.create_entry_span(String::from("op3"), Some(&span2));
                 assert_eq!(span3.span_id(), 2);
+
+                context.finish_span(span3);
             }
+            context.finish_span(span2);
         }
+        context.finish_span(span1);
     }
 }
\ No newline at end of file
diff --git a/tracing-core/src/lib.rs b/tracing-core/src/lib.rs
index 4be7dcb..71be014 100644
--- a/tracing-core/src/lib.rs
+++ b/tracing-core/src/lib.rs
@@ -1,7 +1,9 @@
 pub mod span;
 pub mod context;
+pub mod tag;
 
+pub use context::TracingContext;
+pub use context::Context;
 pub use span::TracingSpan;
 pub use span::Span;
-pub use context::TracingContext;
-pub use context::Context;
\ No newline at end of file
+pub use tag::Tag;
\ No newline at end of file
diff --git a/tracing-core/src/span.rs b/tracing-core/src/span.rs
index d65473c..a69135c 100644
--- a/tracing-core/src/span.rs
+++ b/tracing-core/src/span.rs
@@ -1,6 +1,6 @@
 use std::time::SystemTime;
 
-use crate::Context;
+use crate::Tag;
 
 /// Span is one of the tracing concept, representing a time duration.
 /// Typically, it represent a method invocation or a RPC.
@@ -10,13 +10,21 @@ pub trait Span {
     fn is_entry(&self) -> bool;
     fn is_exit(&self) -> bool;
     fn span_id(&self) -> i32;
+    fn tag(&mut self, tag: Tag);
+    /// End means sealing the end time.
+    /// Still need to call Context::archive
+    fn end(&mut self);
+    fn end_with_timestamp(&mut self, timestamp: SystemTime);
+    fn is_ended(&mut self) -> bool;
+    /// Return the replicated existing tags.
+    fn tags(&self) -> Vec<Tag>;
 }
 
 pub struct TracingSpan {
     /// The operation name represents the logic process of this span
     operation_name: String,
     span_id: i32,
-    paren_span_id: i32,
+    parent_span_id: i32,
     /// The timestamp of the span start time
     start_time: u64,
     /// The timestamp of the span end time
@@ -25,43 +33,51 @@ pub struct TracingSpan {
     is_entry: bool,
     /// As an exit span
     is_exit: bool,
+    /// The peer network address when as an RPC related span.
+    /// Typically used in exit span, representing the target server address.
+    peer: Option<String>,
+    /// Tag this span in error status.
+    error_occurred: bool,
+    /// Component id is defined in the main repo to represent the library kind.
+    component_id: Option<i32>,
+    tags: Vec<Tag>,
 }
 
 impl TracingSpan {
     /// Create a new entry span
-    pub fn new_entry_span(operation_name: String, context: &mut dyn Context, parent: Option<Box<dyn Span>>) -> Box<dyn Span> {
-        let mut span = TracingSpan::_new(operation_name, context, parent);
+    pub fn new_entry_span(operation_name: String, span_id: i32, parent_span_id: i32) -> Box<dyn Span> {
+        let mut span = TracingSpan::_new(operation_name, span_id, parent_span_id);
         span.is_entry = true;
         Box::new(span)
     }
 
     /// Create a new exit span
-    pub fn new_exit_span(operation_name: String, context: &mut dyn Context, parent: Option<Box<dyn Span>>) -> Box<dyn Span> {
-        let mut span = TracingSpan::_new(operation_name, context, parent);
+    pub fn new_exit_span(operation_name: String, span_id: i32, parent_span_id: i32) -> Box<dyn Span> {
+        let mut span = TracingSpan::_new(operation_name, span_id, parent_span_id);
         span.is_exit = true;
         Box::new(span)
     }
 
     /// Create a new local span
-    pub fn new_local_span(operation_name: String, context: &mut dyn Context, parent: Option<Box<dyn Span>>) -> Box<dyn Span> {
-        let span = TracingSpan::_new(operation_name, context, parent);
+    pub fn new_local_span(operation_name: String, span_id: i32, parent_span_id: i32) -> Box<dyn Span> {
+        let span = TracingSpan::_new(operation_name, span_id, parent_span_id);
         Box::new(span)
     }
 
     /// Create a span and set the limited internal values
-    fn _new(operation_name: String, context: &mut dyn Context, parent: Option<Box<dyn Span>>) -> Self {
+    fn _new(operation_name: String, span_id: i32, parent_span_id: i32) -> Self {
         TracingSpan {
-            operation_name: operation_name.clone(),
-            span_id: context.next_span_id(),
-            paren_span_id: match parent {
-                // -1 means no parent span
-                None => { -1 }
-                Some(parent) => { parent.span_id() }
-            },
+            operation_name,
+            span_id,
+            parent_span_id,
             start_time: 0,
             end_time: 0,
             is_entry: false,
             is_exit: false,
+            peer: None,
+            error_occurred: false,
+            component_id: None,
+            tags: Vec::new(),
         }
     }
 }
@@ -92,28 +108,58 @@ impl Span for TracingSpan {
     fn span_id(&self) -> i32 {
         self.span_id
     }
+
+    fn tag(&mut self, tag: Tag) {
+        self.tags.push(tag);
+    }
+
+    fn end(&mut self) {
+        self.end_time = match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
+            Ok(n) => { n.as_millis() }
+            Err(_) => self.start_time as u128,
+        } as u64;
+    }
+
+    fn end_with_timestamp(&mut self, timestamp: SystemTime) {
+        self.end_time = match timestamp.duration_since(SystemTime::UNIX_EPOCH) {
+            Ok(n) => { n.as_millis() }
+            Err(_) => self.start_time as u128,
+        } as u64;
+    }
+
+    fn is_ended(&mut self) -> bool {
+        self.end_time != 0
+    }
+
+    fn tags(&self) -> Vec<Tag> {
+        let mut tags = Vec::new();
+        for t in &self.tags {
+            tags.push(t.clone());
+        };
+        tags
+    }
 }
 
 #[cfg(test)]
 mod span_tests {
     use std::time::SystemTime;
 
+    use crate::{Tag, TracingContext};
     use crate::span::*;
-    use crate::TracingContext;
 
     #[test]
     fn test_span_new() {
         let mut context = TracingContext::new();
-        let mut span = TracingSpan::_new(String::from("op1"), &mut context, None);
-        assert_eq!(span.paren_span_id, -1);
+        let mut span = TracingSpan::_new(String::from("op1"), 0, -1);
+        assert_eq!(span.parent_span_id, -1);
         assert_eq!(span.span_id, 0);
         assert_eq!(span.start_time, 0);
         span.start();
         assert_ne!(span.start_time, 0);
 
-        let mut span2 = TracingSpan::_new(String::from("op2"), &mut context, Some(Box::new(span)));
+        let mut span2 = TracingSpan::_new(String::from("op2"), 1, 0);
         assert_eq!("op2", span2.operation_name);
-        assert_eq!(span2.paren_span_id, 0);
+        assert_eq!(span2.parent_span_id, 0);
         assert_eq!(span2.span_id, 1);
         span2.start_with_timestamp(SystemTime::now());
         assert_ne!(span2.start_time, 0);
@@ -122,9 +168,21 @@ mod span_tests {
     #[test]
     fn test_new_entry_span() {
         let mut context = TracingContext::new();
-        let mut span = TracingSpan::new_entry_span(String::from("op1"), &mut context, None);
+        let mut 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 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")));
+
+        let tags = span.tags();
+        assert_eq!(tags.len(), 2);
+        assert_eq!(tags.get(0).unwrap().key(), "tag1")
+    }
 }
 
 
diff --git a/tracing-core/src/tag.rs b/tracing-core/src/tag.rs
new file mode 100644
index 0000000..d51c96b
--- /dev/null
+++ b/tracing-core/src/tag.rs
@@ -0,0 +1,37 @@
+#[derive(Clone)]
+pub struct Tag {
+    key: String,
+    value: String,
+}
+
+impl Tag {
+    pub fn New(key: String, value: String) -> Self {
+        Tag {
+            key,
+            value,
+        }
+    }
+
+    pub fn key(&self) -> String {
+        self.key.clone()
+    }
+
+    pub fn value(&self) -> String {
+        self.value.clone()
+    }
+}
+
+#[cfg(test)]
+mod tag_tests {
+    use crate::Tag;
+
+    #[test]
+    fn test_tag_new() {
+        let tag = Tag::New(String::from("tag_key"), String::from("tag_value"));
+        assert_eq!(tag.key, "tag_key");
+        assert_eq!(tag.value, "tag_value");
+        let tag_clone = tag.clone();
+        assert_eq!(tag_clone.key, "tag_key");
+        assert_eq!(tag_clone.value, "tag_value");
+    }
+}
\ No newline at end of file