diff --git a/src/api/distributed_context/mod.rs b/src/api/distributed_context/mod.rs deleted file mode 100644 index 7346ff433c..0000000000 --- a/src/api/distributed_context/mod.rs +++ /dev/null @@ -1,12 +0,0 @@ -//! # OpenTelemetry Distributed Context API -//! -//! OpenTelemetry uses `Propagators` to serialize and deserialize `SpanContext` -//! into a binary or text format. Currently there are two types of propagators: -//! -//! - `BinaryFormat` which is used to serialize and deserialize a value into -//! a binary representation. -//! - `HTTPTextFormat` which is used to inject and extract a value as text into -//! `Carrier`s that travel in-band across process boundaries. -pub mod b3_propagator; -pub mod binary_propagator; -pub mod trace_context_propagator; diff --git a/src/api/mod.rs b/src/api/mod.rs index ff3c1fb88a..b8e6660f62 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -14,12 +14,11 @@ //! which implements the delivery of the telemetry. The application must also configure exporters //! so that the SDK knows where and how to deliver the telemetry. pub mod core; -pub mod distributed_context; pub mod metrics; +pub mod propagation; pub mod trace; pub use self::core::{Key, KeyValue, Unit, Value}; -pub use distributed_context::b3_propagator::B3Propagator; pub use metrics::{ counter::{Counter, CounterHandle}, gauge::{Gauge, GaugeHandle}, @@ -28,15 +27,17 @@ pub use metrics::{ value::MeasurementValue, Instrument, InstrumentHandle, LabelSet, Measurement, Meter, MetricOptions, }; +pub use propagation::{binary_propagator::BinaryFormat, text_propagator::HttpTextFormat, Carrier}; pub use trace::{ + b3_propagator::B3Propagator, event::Event, link::Link, noop::{NoopProvider, NoopSpan, NoopTracer}, - propagator::{BinaryFormat, Carrier, HttpTextFormat}, provider::Provider, sampler::{Sampler, SamplingDecision, SamplingResult}, span::{Span, SpanKind, SpanStatus}, span_context::{SpanContext, TRACE_FLAGS_UNUSED, TRACE_FLAG_SAMPLED}, span_processor::SpanProcessor, + trace_context_propagator::TraceContextPropagator, tracer::{Tracer, TracerGenerics}, }; diff --git a/src/api/distributed_context/binary_propagator.rs b/src/api/propagation/binary_propagator.rs similarity index 93% rename from src/api/distributed_context/binary_propagator.rs rename to src/api/propagation/binary_propagator.rs index a5207125a1..7b827a8ad3 100644 --- a/src/api/distributed_context/binary_propagator.rs +++ b/src/api/propagation/binary_propagator.rs @@ -8,6 +8,16 @@ use crate::api; use std::convert::TryInto; +/// Used to serialize and deserialize `SpanContext`s to and from a binary +/// representation. +pub trait BinaryFormat { + /// Serializes span context into a byte array and returns the array. + fn to_bytes(&self, context: &api::SpanContext) -> [u8; 29]; + + /// Deserializes a span context from a byte array. + fn from_bytes(&self, bytes: Vec) -> api::SpanContext; +} + /// Extracts and injects `SpanContext`s from byte arrays. #[derive(Debug, Default)] pub struct BinaryPropagator {} @@ -19,7 +29,7 @@ impl BinaryPropagator { } } -impl api::BinaryFormat for BinaryPropagator { +impl BinaryFormat for BinaryPropagator { /// Serializes span context into a byte array and returns the array. fn to_bytes(&self, context: &api::SpanContext) -> [u8; 29] { let mut res = [0u8; 29]; diff --git a/src/api/trace/propagator.rs b/src/api/propagation/mod.rs similarity index 80% rename from src/api/trace/propagator.rs rename to src/api/propagation/mod.rs index a44e654b50..8017e7c38b 100644 --- a/src/api/trace/propagator.rs +++ b/src/api/propagation/mod.rs @@ -109,6 +109,10 @@ //! - the key of the field. //! - the value of the field. //! +//! The implementation SHOULD preserve casing (e.g. it should not transform +//! `Content-Type` to `content-type`) if the used protocol is case insensitive, +//! otherwise it MUST preserve casing. +//! //! ### Extract //! //! Extracts the value from upstream. For example, as http headers. @@ -138,42 +142,27 @@ //! //! ##### Get //! -//! Returns the first value of the given propagation key or returns `None` -//! if the key doesn't exist. +//! The Get function MUST return the first value of the given propagation +//! key or return `None` if the key doesn't exist. //! //! Required arguments: //! -//! - the carrier of propagation fields, such as an http request. +//! - the carrier of propagation fields, such as an HTTP request. //! - the key of the field. //! -//! Returns the first value of the given propagation key or returns `None` -//! if the key doesn't exist. +//! The `get` function is responsible for handling case sensitivity. If +//! the getter is intended to work with an HTTP request object, the getter +//! MUST be case insensitive. To improve compatibility with other text-based +//! protocols, text format implementations MUST ensure to always use the +//! canonical casing for their attributes. NOTE: Canonical casing for HTTP +//! headers is usually title case (e.g. `Content-Type` instead of `content-type`). +//! use crate::api; use std::collections::HashMap; -/// Used to serialize and deserialize `SpanContext`s to and from a binary -/// representation. -pub trait BinaryFormat { - /// Serializes span context into a byte array and returns the array. - fn to_bytes(&self, context: &api::SpanContext) -> [u8; 29]; - - /// Deserializes a span context from a byte array. - fn from_bytes(&self, bytes: Vec) -> api::SpanContext; -} - -///is used to inject and extract a value as text into carriers that travel -/// in-band across process boundaries. -pub trait HttpTextFormat { - /// Properly encodes the values of the `SpanContext` and injects them - /// into the `Carrier`. - fn inject(&self, context: api::SpanContext, carrier: &mut dyn Carrier); - - /// Retrieves encoded `SpanContext`s using the `Carrier`. It decodes - /// the `SpanContext` and returns it. If no `SpanContext` was retrieved - /// OR if the retrieved SpanContext is invalid then an empty `SpanContext` - /// is returned. - fn extract(&self, carrier: &dyn Carrier) -> api::SpanContext; -} +pub mod binary_propagator; +pub mod noop; +pub mod text_propagator; /// Carriers provide an interface for adding and removing fields from an /// underlying struct like `HashMap`. diff --git a/src/api/propagation/noop.rs b/src/api/propagation/noop.rs new file mode 100644 index 0000000000..80d9058639 --- /dev/null +++ b/src/api/propagation/noop.rs @@ -0,0 +1,36 @@ +//! # No-op OpenTelemetry Propagation Implementation +//! +//! This implementation is useful for testing purposes as it is intended +//! to have minimal resource utilization and runtime impact. +use crate::api; + +/// A no-op instance of a `HttpTextFormat`. +#[derive(Debug)] +pub struct NoopTextFormat {} + +impl api::HttpTextFormat for NoopTextFormat { + /// Ignores calls to `inject` + fn inject(&self, _context: api::SpanContext, _carrier: &mut dyn api::Carrier) { + // Ignored + } + + /// Always returns invalid span contexts + fn extract(&self, _carrier: &dyn api::Carrier) -> api::SpanContext { + api::SpanContext::new(0, 0, 0, false) + } +} + +/// A no-op instance of `BinaryFormat` +#[derive(Debug)] +pub struct NoopBinaryFormat {} + +impl api::BinaryFormat for NoopBinaryFormat { + fn to_bytes(&self, _context: &api::SpanContext) -> [u8; 29] { + [0; 29] + } + + /// Always returns invalid span contexts + fn from_bytes(&self, _bytes: Vec) -> api::SpanContext { + api::SpanContext::new(0, 0, 0, false) + } +} diff --git a/src/api/propagation/text_propagator.rs b/src/api/propagation/text_propagator.rs new file mode 100644 index 0000000000..8d8227719b --- /dev/null +++ b/src/api/propagation/text_propagator.rs @@ -0,0 +1,19 @@ +//! # Text Propagator +//! +//! `HttpTextFormat` is a formatter to serialize and deserialize a +//! value into a text format. +use crate::api; + +///is used to inject and extract a value as text into carriers that travel +/// in-band across process boundaries. +pub trait HttpTextFormat { + /// Properly encodes the values of the `SpanContext` and injects them + /// into the `Carrier`. + fn inject(&self, context: api::SpanContext, carrier: &mut dyn api::Carrier); + + /// Retrieves encoded `SpanContext`s using the `Carrier`. It decodes + /// the `SpanContext` and returns it. If no `SpanContext` was retrieved + /// OR if the retrieved SpanContext is invalid then an empty `SpanContext` + /// is returned. + fn extract(&self, carrier: &dyn api::Carrier) -> api::SpanContext; +} diff --git a/src/api/distributed_context/b3_propagator.rs b/src/api/trace/b3_propagator.rs similarity index 100% rename from src/api/distributed_context/b3_propagator.rs rename to src/api/trace/b3_propagator.rs diff --git a/src/api/trace/mod.rs b/src/api/trace/mod.rs index 6d4c9e36f7..c54a635ba5 100644 --- a/src/api/trace/mod.rs +++ b/src/api/trace/mod.rs @@ -34,7 +34,7 @@ //! //! `Span`s encapsulate: //! -//! - The operation name +//! - The span name //! - An immutable `SpanContext` that uniquely identifies the `Span` //! - A parent span in the form of a `SpanContext`, or None //! - A start timestamp @@ -44,6 +44,24 @@ //! - A list of timestamped `Event`s //! - A `Status`. //! +//! The _span name_ is a human-readable string which concisely identifies the work +//! represented by the `Span`, for example, an RPC method name, a function name, +//! or the name of a subtask or stage within a larger computation. The span name +//! should be the most general string that identifies a (statistically) interesting +//! _class of Spans_, rather than individual Span instances. That is, "get_user" is +//! a reasonable name, while "get_user/314159", where "314159" is a user ID, is not +//! a good name due to its high cardinality. +//! +//! For example, here are potential span names for an endpoint that gets a +//! hypothetical account information: +//! +//! | Span Name | Guidance | +//! | ------------------------- | ------------ | +//! | `get` | Too general | +//! | `get_account/42` | Too specific | +//! | `get_account` | Good, and account_id=42 would make a nice Span attribute | +//! | `get_account/{accountId}` | Also good (using the "HTTP route") | +//! //! The `Span`'s start and end timestamps reflect the elapsed real time of the //! operation. A `Span`'s start time SHOULD be set to the current time on span //! creation. After the `Span` is created, it SHOULD be possible to @@ -91,14 +109,15 @@ //! Please review the W3C specification for details on the [Tracestate //! field](https://www.w3.org/TR/trace-context/#tracestate-field). //! +pub mod b3_propagator; pub mod event; pub mod futures; pub mod link; pub mod noop; -pub mod propagator; pub mod provider; pub mod sampler; pub mod span; pub mod span_context; pub mod span_processor; +pub mod trace_context_propagator; pub mod tracer; diff --git a/src/api/distributed_context/trace_context_propagator.rs b/src/api/trace/trace_context_propagator.rs similarity index 100% rename from src/api/distributed_context/trace_context_propagator.rs rename to src/api/trace/trace_context_propagator.rs diff --git a/src/exporter/trace/mod.rs b/src/exporter/trace/mod.rs index 6a1c54a1e2..39dfc2c89f 100644 --- a/src/exporter/trace/mod.rs +++ b/src/exporter/trace/mod.rs @@ -68,7 +68,7 @@ pub struct SpanData { pub parent_span_id: u64, /// Span kind pub span_kind: api::SpanKind, - /// Span operation name + /// Span name pub name: String, /// Span start time pub start_time: SystemTime,