From bf4359a72f51044a3c6673580c9ea3647638144f Mon Sep 17 00:00:00 2001 From: Michael Nitschinger Date: Tue, 13 Mar 2018 14:09:23 +0100 Subject: [PATCH] WIP: Span --- opentracing-api/src/lib.rs | 4 ++- opentracing-api/src/span.rs | 61 +++++++++++++++++++++++++++++++++++++ opentracing-api/src/tag.rs | 6 ++++ opentracing-noop/src/lib.rs | 52 ++++++++++++++++++++++++++++++- 4 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 opentracing-api/src/span.rs diff --git a/opentracing-api/src/lib.rs b/opentracing-api/src/lib.rs index ac6ec50..a8500a3 100644 --- a/opentracing-api/src/lib.rs +++ b/opentracing-api/src/lib.rs @@ -3,7 +3,9 @@ mod context; mod tag; mod field; +mod span; pub use context::SpanContext; -pub use tag::{ParseTagsError, Tags}; +pub use tag::{ParseTagsError, TagValue, Tags}; pub use field::{Fields, ParseFieldsError}; +pub use span::{FinishedSpan, Span}; diff --git a/opentracing-api/src/span.rs b/opentracing-api/src/span.rs new file mode 100644 index 0000000..0e75c8c --- /dev/null +++ b/opentracing-api/src/span.rs @@ -0,0 +1,61 @@ +use SpanContext; +use TagValue; + +/// The `Span` represents the OpenTracing specification's Span contract. +pub trait Span<'a> { + /// The associated `SpanContext`. + type Context: SpanContext<'a>; + + /// Retrieve the associated `SpanContext`. + /// + /// This may be called any time, including after `finish`. + fn context(&self) -> &Self::Context; + + /// Sets a key:value tag on the `Span`. + fn set_tag(&mut self, key: &str, value: TagValue); + + /// Returns a tag value if set, none otherwise + fn tag(&self, key: &str) -> Option<&'a TagValue>; + + /// Record an event at the current walltime timestamp. + fn log(&mut self, event: String); + + /// Record an event at the given walltime timestamp. + fn log_at(&mut self, timestamp: u64, event: String); + + /// Sets a baggage item in the Span (and its SpanContext) as a key/value pair. + fn set_baggage_item(&mut self, key: &str, value: String); + + /// the value of the baggage item identified by the given key, or None if no such item + /// could be found. + fn baggage_item(&self, key: &str) -> Option<&'a String>; + + /// Sets the string name for the logical operation this span represents. + fn set_operation_name(&mut self, name: &str); + + /// Returns the operation name if set, None otherwise. + fn operation_name(&self) -> Option<&'a str>; + + /// Sets the end timestamp to now and finishes (records) the span. + fn finish(self) -> FinishedSpan; + + /// Sets an explicit end timestamp and finishes (records) the span. + fn finish_at(self, timestamp: u64) -> FinishedSpan; +} + +pub struct FinishedSpan { + context: C, +} + +impl<'a, C> FinishedSpan +where + C: SpanContext<'a>, +{ + pub fn new(context: C) -> Self { + FinishedSpan { context } + } + + pub fn context(&self) -> &C { + &self.context + } +} diff --git a/opentracing-api/src/tag.rs b/opentracing-api/src/tag.rs index 9f3123d..faaee88 100644 --- a/opentracing-api/src/tag.rs +++ b/opentracing-api/src/tag.rs @@ -171,6 +171,12 @@ impl fmt::Display for ParseTagsError { } } +pub enum TagValue { + String(String), + Boolean(bool), + Number(f64), +} + #[cfg(test)] mod tests { diff --git a/opentracing-noop/src/lib.rs b/opentracing-noop/src/lib.rs index abf365c..bbe5877 100644 --- a/opentracing-noop/src/lib.rs +++ b/opentracing-noop/src/lib.rs @@ -4,7 +4,7 @@ extern crate opentracing_api; -use opentracing_api::SpanContext; +use opentracing_api::{FinishedSpan, Span, SpanContext, TagValue}; use std::iter::{empty, Empty}; /// The `NoopSpanContext` just returns an empty iterator on @@ -25,6 +25,56 @@ impl<'a> SpanContext<'a> for NoopSpanContext { } } +pub struct NoopSpan { + ctx: NoopSpanContext, +} + +impl NoopSpan { + pub fn new() -> Self { + NoopSpan { + ctx: NoopSpanContext::default(), + } + } +} + +impl<'a> Span<'a> for NoopSpan { + type Context = NoopSpanContext; + + fn context(&self) -> &Self::Context { + &self.ctx + } + + fn set_tag(&mut self, _key: &str, _value: TagValue) {} + + fn tag(&self, _key: &str) -> Option<&'a TagValue> { + None + } + + fn log(&mut self, _event: String) {} + + fn log_at(&mut self, _timestamp: u64, _event: String) {} + + fn set_baggage_item(&mut self, _key: &str, _value: String) {} + + fn baggage_item(&self, _key: &str) -> Option<&'a String> { + None + } + + fn set_operation_name(&mut self, _name: &str) {} + + fn operation_name(&self) -> Option<&'a str> { + None + } + + fn finish(self) -> FinishedSpan { + FinishedSpan::new(self.ctx) + } + + fn finish_at(self, _timestamp: u64) -> FinishedSpan { + FinishedSpan::new(self.ctx) + } +} + #[cfg(test)] mod tests {