-
Notifications
You must be signed in to change notification settings - Fork 599
feat(tracer): add more convenience methods for enterings spans #3251
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -207,11 +207,126 @@ pub trait Tracer { | |
| N: Into<Cow<'static, str>>, | ||
| Self::Span: Send + Sync + 'static, | ||
| { | ||
| let span = self.start(name); | ||
| self.in_span_with_builder(self.span_builder(name), f) | ||
| } | ||
|
|
||
| /// Start a new span with a given parent context and execute the given closure with | ||
| /// reference to the context in which the span is active. | ||
| /// | ||
| /// This method starts a new span as a child of the provided parent context and sets | ||
| /// it as the active span for the given function. It then executes the body. It ends | ||
| /// the span before returning the execution result. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ``` | ||
| /// use opentelemetry::{global, trace::{Span, Tracer, TraceContextExt}, Context, KeyValue}; | ||
| /// | ||
| /// fn my_function() { | ||
| /// let tracer = global::tracer("my-component"); | ||
| /// | ||
| /// // Create a parent context | ||
| /// let parent = tracer.start("parent-span"); | ||
| /// let parent_cx = Context::current_with_span(parent); | ||
| /// | ||
| /// // start an active span with explicit parent context | ||
| /// tracer.in_span_with_context("child-span", &parent_cx, |_cx| { | ||
| /// // child span is active here | ||
| /// }) | ||
| /// } | ||
| /// ``` | ||
| fn in_span_with_context<T, F, N>(&self, name: N, parent_cx: &Context, f: F) -> T | ||
| where | ||
| F: FnOnce(Context) -> T, | ||
| N: Into<Cow<'static, str>>, | ||
| Self::Span: Send + Sync + 'static, | ||
| { | ||
| self.in_span_with_builder_and_context(self.span_builder(name), parent_cx, f) | ||
| } | ||
|
|
||
| /// Start a new span from a [`SpanBuilder`] and execute the given closure with | ||
| /// reference to the context in which the span is active. | ||
| /// | ||
| /// This method builds and starts a new span from a [`SpanBuilder`] using the current | ||
| /// context and sets it as the active span for the given function. It then executes | ||
| /// the body. It ends the span before returning the execution result. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ``` | ||
| /// use opentelemetry::{global, trace::{Span, SpanKind, Tracer}, KeyValue}; | ||
| /// | ||
| /// fn my_function() { | ||
| /// let tracer = global::tracer("my-component"); | ||
| /// | ||
| /// // start an active span with span configuration | ||
| /// tracer.in_span_with_builder( | ||
| /// tracer.span_builder("span-name") | ||
| /// .with_kind(SpanKind::Client) | ||
| /// .with_attributes(vec![KeyValue::new("key", "value")]), | ||
| /// |_cx| { | ||
| /// // span is active here with configured attributes | ||
| /// } | ||
| /// ) | ||
| /// } | ||
| /// ``` | ||
| fn in_span_with_builder<T, F>(&self, builder: SpanBuilder, f: F) -> T | ||
| where | ||
| F: FnOnce(Context) -> T, | ||
| Self::Span: Send + Sync + 'static, | ||
| { | ||
| let span = self.build(builder); | ||
| let cx = Context::current_with_span(span); | ||
| let _guard = cx.clone().attach(); | ||
| f(cx) | ||
| } | ||
|
|
||
| /// Start a new span from a [`SpanBuilder`] with a given parent context and execute the | ||
| /// given closure with reference to the context in which the span is active. | ||
| /// | ||
| /// This method builds and starts a new span from a [`SpanBuilder`] as a child of the | ||
| /// provided parent context and sets it as the active span for the given function. It | ||
| /// then executes the body. It ends the span before returning the execution result. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ``` | ||
| /// use opentelemetry::{global, trace::{Span, SpanKind, Tracer, TraceContextExt}, Context, KeyValue}; | ||
| /// | ||
| /// fn my_function() { | ||
| /// let tracer = global::tracer("my-component"); | ||
| /// | ||
| /// // Create a parent context | ||
| /// let parent = tracer.start("parent-span"); | ||
| /// let parent_cx = Context::current_with_span(parent); | ||
| /// | ||
| /// // start an active span with explicit parent context and span configuration | ||
| /// tracer.in_span_with_builder_and_context( | ||
| /// tracer.span_builder("child-span") | ||
| /// .with_kind(SpanKind::Client) | ||
| /// .with_attributes(vec![KeyValue::new("key", "value")]), | ||
| /// &parent_cx, | ||
| /// |_cx| { | ||
| /// // child span is active here with configured attributes | ||
| /// } | ||
| /// ) | ||
| /// } | ||
| /// ``` | ||
| fn in_span_with_builder_and_context<T, F>( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. based on our benchmarks (https://github.com/open-telemetry/opentelemetry-rust/blob/main/opentelemetry-sdk/benches/span.rs#L71) the Not opposed to this change, just noting the perf implications. Maybe we can improve the implementation to make it better, and/or warn users about perf implication in the doc in follow ups.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll take a look at the benchmarks and extend them with versions for these variants.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So the benchmarks are really comparing apples and oranges. Do we want comparable numbers or what are we trying to measure in the benchmarks? Yes, if you don't attach a The bigger question is what type of API do we want to have here. Should we have a method that maybe attaches the |
||
| &self, | ||
| builder: SpanBuilder, | ||
| parent_cx: &Context, | ||
| f: F, | ||
| ) -> T | ||
| where | ||
| F: FnOnce(Context) -> T, | ||
| Self::Span: Send + Sync + 'static, | ||
| { | ||
| let span = self.build_with_context(builder, parent_cx); | ||
| let cx = parent_cx.with_span(span); | ||
| let _guard = cx.clone().attach(); | ||
| f(cx) | ||
| } | ||
| } | ||
|
|
||
| /// `SpanBuilder` allows span attributes to be configured before the span | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.