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