Skip to content

Commit

Permalink
Add InstrumentationLibrary for instrumentation library information (#207
Browse files Browse the repository at this point in the history
)
  • Loading branch information
TommyCpp authored Sep 3, 2020
1 parent dc6fd88 commit ce469b4
Show file tree
Hide file tree
Showing 13 changed files with 96 additions and 30 deletions.
4 changes: 2 additions & 2 deletions benches/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ fn trace_benchmark_group<F: Fn(&sdk::Tracer)>(c: &mut Criterion, name: &str, f:
..Default::default()
})
.build()
.get_tracer("always-sample");
.get_tracer("always-sample", None);

b.iter(|| f(&always_sample));
});
Expand All @@ -86,7 +86,7 @@ fn trace_benchmark_group<F: Fn(&sdk::Tracer)>(c: &mut Criterion, name: &str, f:
..Default::default()
})
.build()
.get_tracer("never-sample");
.get_tracer("never-sample", None);
b.iter(|| f(&never_sample));
});

Expand Down
2 changes: 1 addition & 1 deletion examples/stdout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ fn main() {
global::set_provider(provider);

global::trace_provider()
.get_tracer("component-main")
.get_tracer("component-main", None)
.in_span("operation", |_cx| {});
}
2 changes: 1 addition & 1 deletion opentelemetry-jaeger/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ impl PipelineBuilder {
/// Install a Jaeger pipeline with the recommended defaults.
pub fn install(self) -> Result<sdk::Tracer, Box<dyn Error>> {
let trace_provider = self.build()?;
let tracer = trace_provider.get_tracer("opentelemetry-jaeger");
let tracer = trace_provider.get_tracer("opentelemetry-jaeger", None);

global::set_provider(trace_provider);

Expand Down
2 changes: 1 addition & 1 deletion src/api/context/propagation/composite_propagator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use std::fmt::Debug;
/// let mut injector = HashMap::new();
///
/// // And a given span
/// let example_span = sdk::TracerProvider::default().get_tracer("example-component").start("span-name");
/// let example_span = sdk::TracerProvider::default().get_tracer("example-component", None).start("span-name");
///
/// // with the current context, call inject to add the headers
/// composite_propagator.inject_context(&Context::current_with_span(example_span)
Expand Down
2 changes: 1 addition & 1 deletion src/api/trace/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub trait TraceContextExt {
/// // returns a reference to an empty span by default
/// assert_eq!(Context::current().span().span_context(), api::SpanContext::empty_context());
///
/// sdk::TracerProvider::default().get_tracer("my-component").in_span("my-span", |cx| {
/// sdk::TracerProvider::default().get_tracer("my-component", None).in_span("my-span", |cx| {
/// // Returns a reference to the current span if set
/// assert_ne!(cx.span().span_context(), api::SpanContext::empty_context());
/// });
Expand Down
2 changes: 1 addition & 1 deletion src/api/trace/noop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl api::TracerProvider for NoopProvider {
type Tracer = NoopTracer;

/// Returns a new `NoopTracer` instance.
fn get_tracer(&self, _name: &'static str) -> Self::Tracer {
fn get_tracer(&self, _name: &'static str, _version: Option<&'static str>) -> Self::Tracer {
NoopTracer {}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/api/trace/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
//! the SDK to suppress telemetry produced by this library.
//!
//! Implementations might require the user to specify configuration properties at
//! `TracerProvider` creation time, or rely on external configuration.
//! `TracerProvider` creation time, or rely on external configurations.
use crate::api;
use std::fmt;

Expand All @@ -29,5 +29,5 @@ pub trait TracerProvider: fmt::Debug + 'static {

/// Creates a named tracer instance of `Self::Tracer`.
/// If the name is an empty string then provider uses default name.
fn get_tracer(&self, name: &'static str) -> Self::Tracer;
fn get_tracer(&self, name: &'static str, version: Option<&'static str>) -> Self::Tracer;
}
9 changes: 6 additions & 3 deletions src/global/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@
//! // Then you can use the global provider to create a tracer via `tracer`.
//! let _span = global::tracer("my-component").start("span-name");
//!
//! // You can also get the tracer via name and version.
//! let _tracer = global::tracer_with_version("another-component", "1.1.1");
//!
//! // Or access the configured provider via `trace_provider`.
//! let provider = global::trace_provider();
//! let _tracer_a = provider.get_tracer("my-component-a");
//! let _tracer_b = provider.get_tracer("my-component-b");
//! let _tracer_a = provider.get_tracer("my-component-a", None);
//! let _tracer_b = provider.get_tracer("my-component-b", None);
//! }
//!
//! // in main or other app start
Expand Down Expand Up @@ -84,4 +87,4 @@ pub use metrics::{meter, meter_provider, set_meter_provider};
#[cfg(feature = "trace")]
pub use propagation::{get_text_map_propagator, set_text_map_propagator};
#[cfg(feature = "trace")]
pub use trace::{set_provider, trace_provider, tracer, GenericProvider};
pub use trace::{set_provider, trace_provider, tracer, tracer_with_version, GenericProvider};
34 changes: 27 additions & 7 deletions src/global/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::time::SystemTime;
/// [`Span`]: ../api/trace/span/trait.Span.html
#[derive(Debug)]
pub struct BoxedSpan(Box<DynSpan>);

type DynSpan = dyn api::Span + Send + Sync;

impl api::Span for BoxedSpan {
Expand Down Expand Up @@ -163,7 +164,11 @@ where
/// [`GlobalProvider`]: struct.GlobalProvider.html
pub trait GenericProvider: fmt::Debug + 'static {
/// Creates a named tracer instance that is a trait object through the underlying `TracerProvider`.
fn get_tracer_boxed(&self, name: &'static str) -> Box<dyn GenericTracer + Send + Sync>;
fn get_tracer_boxed(
&self,
name: &'static str,
version: Option<&'static str>,
) -> Box<dyn GenericTracer + Send + Sync>;
}

impl<S, T, P> GenericProvider for P
Expand All @@ -173,8 +178,12 @@ where
P: api::TracerProvider<Tracer = T>,
{
/// Return a boxed generic tracer
fn get_tracer_boxed(&self, name: &'static str) -> Box<dyn GenericTracer + Send + Sync> {
Box::new(self.get_tracer(name))
fn get_tracer_boxed(
&self,
name: &'static str,
version: Option<&'static str>,
) -> Box<dyn GenericTracer + Send + Sync> {
Box::new(self.get_tracer(name, version))
}
}

Expand Down Expand Up @@ -207,8 +216,8 @@ impl api::TracerProvider for GlobalProvider {
type Tracer = BoxedTracer;

/// Find or create a named tracer using the global provider.
fn get_tracer(&self, name: &'static str) -> Self::Tracer {
BoxedTracer(self.provider.get_tracer_boxed(name))
fn get_tracer(&self, name: &'static str, version: Option<&'static str>) -> Self::Tracer {
BoxedTracer(self.provider.get_tracer_boxed(name, version))
}
}

Expand All @@ -233,12 +242,23 @@ pub fn trace_provider() -> GlobalProvider {
///
/// If the name is an empty string, the provider will use a default name.
///
/// This is a more convenient way of expressing `global::trace_provider().get_tracer(name)`.
/// This is a more convenient way of expressing `global::trace_provider().get_tracer(name, None)`.
///
/// [`Tracer`]: ../api/trace/tracer/trait.Tracer.html
/// [`GlobalProvider`]: struct.GlobalProvider.html
pub fn tracer(name: &'static str) -> BoxedTracer {
trace_provider().get_tracer(name)
trace_provider().get_tracer(name, None)
}

/// Creates a named instance of [`Tracer`] with version info via the configured [`GlobalProvider`]
///
/// If the name is an empty string, the provider will use a default name.
/// If the version is an empty string, it will be used as part of instrumentation library information.
///
/// [`Tracer`]: ../api/trace/tracer/trait.Tracer.html
/// [`GlobalProvider`]: struct.GlobalProvider.html
pub fn tracer_with_version(name: &'static str, version: &'static str) -> BoxedTracer {
trace_provider().get_tracer(name, Some(version))
}

/// Sets the given [`TracerProvider`] instance as the current global provider.
Expand Down
25 changes: 25 additions & 0 deletions src/sdk/instrumentation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//! Provides instrumentation information for both tracing and metric.
//! See `OTEPS-0083` for details.
//!
//! [OTEPS-0083](https://github.com/open-telemetry/oteps/blob/master/text/0083-component.md)
/// InstrumentationLibrary contains information about instrumentation library.
///
/// See `Instrumentation Libraries` for more information.
///
/// [`Instrumentation Libraries`](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/overview.md#instrumentation-libraries)
#[derive(Debug, Default, Hash, Copy, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct InstrumentationLibrary {
/// instrumentation library name, cannot be empty
pub name: &'static str,
/// instrumentation library version, can be empty
pub version: Option<&'static str>,
}

impl InstrumentationLibrary {
/// Create an InstrumentationLibrary from name and version.
pub fn new(name: &'static str, version: Option<&'static str>) -> InstrumentationLibrary {
InstrumentationLibrary { name, version }
}
}
2 changes: 2 additions & 0 deletions src/sdk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
//! `Meter` creation.
pub mod env;
pub mod export;
pub mod instrumentation;
#[cfg(feature = "metrics")]
pub mod metrics;
pub mod resource;
#[cfg(feature = "trace")]
pub mod trace;

pub use env::EnvResourceDetector;
pub use instrumentation::InstrumentationLibrary;
pub use resource::Resource;
#[cfg(feature = "trace")]
pub use trace::{
Expand Down
12 changes: 7 additions & 5 deletions src/sdk/trace/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const DEFAULT_COMPONENT_NAME: &str = "rust.opentelemetry.io/sdk/tracer";
/// TracerProvider inner type
#[derive(Debug)]
struct ProviderInner {
named_tracers: RwLock<HashMap<&'static str, sdk::Tracer>>,
named_tracers: RwLock<HashMap<sdk::InstrumentationLibrary, sdk::Tracer>>,
processors: Vec<Box<dyn api::SpanProcessor>>,
config: sdk::Config,
}
Expand Down Expand Up @@ -66,29 +66,31 @@ impl api::TracerProvider for TracerProvider {
type Tracer = sdk::Tracer;

/// Find or create `Tracer` instance by name.
fn get_tracer(&self, name: &'static str) -> Self::Tracer {
fn get_tracer(&self, name: &'static str, version: Option<&'static str>) -> Self::Tracer {
// Use default value if name is invalid empty string
let component_name = if name.is_empty() {
DEFAULT_COMPONENT_NAME
} else {
name
};

let instrumentation_lib = sdk::InstrumentationLibrary::new(component_name, version);

// Return named tracer if already initialized
if let Some(tracer) = self
.inner
.named_tracers
.read()
.expect("RwLock poisoned")
.get(&component_name)
.get(&instrumentation_lib)
{
return tracer.clone();
};

// Else construct new named tracer
let mut tracers = self.inner.named_tracers.write().expect("RwLock poisoned");
let new_tracer = sdk::Tracer::new(name, self.clone());
tracers.insert(component_name, new_tracer.clone());
let new_tracer = sdk::Tracer::new(instrumentation_lib, self.clone());
tracers.insert(instrumentation_lib, new_tracer.clone());

new_tracer
}
Expand Down
26 changes: 20 additions & 6 deletions src/sdk/trace/tracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,43 @@ use std::time::SystemTime;
/// `Tracer` implementation to create and manage spans
#[derive(Clone)]
pub struct Tracer {
name: &'static str,
instrumentation_lib: sdk::InstrumentationLibrary,
provider: sdk::TracerProvider,
}

impl fmt::Debug for Tracer {
/// Formats the `Tracer` using the given formatter.
/// Omitting `provider` here is necessary to avoid cycles.
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Tracer").field("name", &self.name).finish()
f.debug_struct("Tracer")
.field("name", &self.instrumentation_lib.name)
.field("version", &self.instrumentation_lib.version)
.finish()
}
}

impl Tracer {
/// Create a new tracer (used internally by `TracerProvider`s.
pub(crate) fn new(name: &'static str, provider: sdk::TracerProvider) -> Self {
Tracer { name, provider }
/// Create a new tracer (used internally by `TracerProvider`s).
pub(crate) fn new(
instrumentation_lib: sdk::InstrumentationLibrary,
provider: sdk::TracerProvider,
) -> Self {
Tracer {
instrumentation_lib,
provider,
}
}

/// TracerProvider associated with this tracer
/// TracerProvider associated with this tracer.
pub fn provider(&self) -> &sdk::TracerProvider {
&self.provider
}

/// instrumentation library information of this tracer.
pub fn instrumentation_library(&self) -> &sdk::InstrumentationLibrary {
&self.instrumentation_lib
}

/// Make a sampling decision using the provided sampler for the span and context.
#[allow(clippy::too_many_arguments)]
fn make_sampling_decision(
Expand Down

0 comments on commit ce469b4

Please sign in to comment.