Skip to content

Commit

Permalink
Add add_link API (open-telemetry#1515)
Browse files Browse the repository at this point in the history
Co-authored-by: Harold Dost <[email protected]>
Co-authored-by: Cijo Thomas <[email protected]>
Co-authored-by: Zhongyang Wu <[email protected]>
  • Loading branch information
4 people authored Mar 19, 2024
1 parent 13c9dc5 commit ab39fd2
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 35 deletions.
6 changes: 6 additions & 0 deletions opentelemetry-sdk/src/trace/links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,9 @@ impl IntoIterator for SpanLinks {
self.links.into_iter()
}
}

impl SpanLinks {
pub(crate) fn add_link(&mut self, link: Link) {
self.links.push(link);
}
}
17 changes: 7 additions & 10 deletions opentelemetry-sdk/src/trace/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,16 +181,13 @@ mod tests {

let mut links = Vec::new();
for _i in 0..(DEFAULT_MAX_LINKS_PER_SPAN * 2) {
links.push(Link::new(
SpanContext::new(
TraceId::from_u128(12),
SpanId::from_u64(12),
TraceFlags::default(),
false,
Default::default(),
),
Vec::new(),
))
links.push(Link::with_context(SpanContext::new(
TraceId::from_u128(12),
SpanId::from_u64(12),
TraceFlags::default(),
false,
Default::default(),
)))
}

let span_builder = SpanBuilder::from_name("span_name").with_links(links);
Expand Down
72 changes: 50 additions & 22 deletions opentelemetry-sdk/src/trace/span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//! These cannot be changed after the `Span`'s end time has been set.
use crate::trace::SpanLimits;
use crate::Resource;
use opentelemetry::trace::{Event, SpanContext, SpanId, SpanKind, Status};
use opentelemetry::trace::{Event, Link, SpanContext, SpanId, SpanKind, Status};
use opentelemetry::KeyValue;
use std::borrow::Cow;
use std::time::SystemTime;
Expand Down Expand Up @@ -170,6 +170,28 @@ impl opentelemetry::trace::Span for Span {
});
}

/// Add `Link` to this `Span`
///
fn add_link(&mut self, span_context: SpanContext, attributes: Vec<KeyValue>) {
let span_links_limit = self.span_limits.max_links_per_span as usize;
let link_attributes_limit = self.span_limits.max_attributes_per_link as usize;
self.with_data(|data| {
if data.links.links.len() < span_links_limit {
let dropped_attributes_count =
attributes.len().saturating_sub(link_attributes_limit);
let mut attributes = attributes;
attributes.truncate(link_attributes_limit);
data.links.add_link(Link::new(
span_context,
attributes,
dropped_attributes_count as u32,
));
} else {
data.links.dropped_count += 1;
}
});
}

/// Finishes the span with given timestamp.
fn end_with_timestamp(&mut self, timestamp: SystemTime) {
self.ensure_ended_and_exported(Some(timestamp));
Expand Down Expand Up @@ -595,16 +617,13 @@ mod tests {
let provider = provider_builder.build();
let tracer = provider.tracer("opentelemetry-test");

let mut link = Link::new(
SpanContext::new(
TraceId::from_u128(12),
SpanId::from_u64(12),
TraceFlags::default(),
false,
Default::default(),
),
Vec::new(),
);
let mut link = Link::with_context(SpanContext::new(
TraceId::from_u128(12),
SpanId::from_u64(12),
TraceFlags::default(),
false,
Default::default(),
));
for i in 0..(DEFAULT_MAX_ATTRIBUTES_PER_LINK * 2) {
link.attributes
.push(KeyValue::new(format!("key {}", i), i.to_string()));
Expand Down Expand Up @@ -632,20 +651,29 @@ mod tests {

let mut links = Vec::new();
for _i in 0..(DEFAULT_MAX_LINKS_PER_SPAN * 2) {
links.push(Link::new(
SpanContext::new(
TraceId::from_u128(12),
SpanId::from_u64(12),
TraceFlags::default(),
false,
Default::default(),
),
Vec::new(),
))
links.push(Link::with_context(SpanContext::new(
TraceId::from_u128(12),
SpanId::from_u64(12),
TraceFlags::default(),
false,
Default::default(),
)))
}

let span_builder = tracer.span_builder("test").with_links(links);
let span = tracer.build(span_builder);
let mut span = tracer.build(span_builder);

// add links using span api after building the span
span.add_link(
SpanContext::new(
TraceId::from_u128(12),
SpanId::from_u64(12),
TraceFlags::default(),
false,
Default::default(),
),
vec![],
);
let link_queue = span
.data
.clone()
Expand Down
14 changes: 14 additions & 0 deletions opentelemetry/src/global/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ pub trait ObjectSafeSpan {
/// filtering decisions made previously depending on the implementation.
fn update_name(&mut self, new_name: Cow<'static, str>);

/// Adds a link to this span
///
fn add_link(&mut self, span_context: SpanContext, attributes: Vec<KeyValue>);

/// Finishes the `Span`.
///
/// Implementations MUST ignore all subsequent calls to `end` (there might be
Expand Down Expand Up @@ -138,6 +142,10 @@ impl<T: trace::Span> ObjectSafeSpan for T {
self.update_name(new_name)
}

fn add_link(&mut self, span_context: SpanContext, attributes: Vec<KeyValue>) {
self.add_link(span_context, attributes)
}

fn end_with_timestamp(&mut self, timestamp: SystemTime) {
self.end_with_timestamp(timestamp)
}
Expand Down Expand Up @@ -216,6 +224,12 @@ impl trace::Span for BoxedSpan {
self.0.update_name(new_name.into())
}

/// Adds a link to this span
///
fn add_link(&mut self, span_context: trace::SpanContext, attributes: Vec<KeyValue>) {
self.0.add_link(span_context, attributes)
}

/// Finishes the span with given timestamp.
fn end_with_timestamp(&mut self, timestamp: SystemTime) {
self.0.end_with_timestamp(timestamp);
Expand Down
2 changes: 2 additions & 0 deletions opentelemetry/src/testing/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ impl Span for TestSpan {
T: Into<Cow<'static, str>>,
{
}

fn add_link(&mut self, _span_context: SpanContext, _attributes: Vec<KeyValue>) {}
fn end_with_timestamp(&mut self, _timestamp: std::time::SystemTime) {}
}

Expand Down
17 changes: 15 additions & 2 deletions opentelemetry/src/trace/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,11 +302,24 @@ pub struct Link {
}

impl Link {
/// Create a new link.
pub fn new(span_context: SpanContext, attributes: Vec<KeyValue>) -> Self {
/// Create new `Link`
pub fn new(
span_context: SpanContext,
attributes: Vec<KeyValue>,
dropped_attributes_count: u32,
) -> Self {
Link {
span_context,
attributes,
dropped_attributes_count,
}
}

/// Create new `Link` with given context
pub fn with_context(span_context: SpanContext) -> Self {
Link {
span_context,
attributes: Vec::new(),
dropped_attributes_count: 0,
}
}
Expand Down
6 changes: 5 additions & 1 deletion opentelemetry/src/trace/noop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl trace::Span for NoopSpan {
where
T: Into<Cow<'static, str>>,
{
// Ignore
// Ignored
}

/// Ignores all events with timestamps
Expand Down Expand Up @@ -94,6 +94,10 @@ impl trace::Span for NoopSpan {
// Ignored
}

fn add_link(&mut self, _span_context: trace::SpanContext, _attributes: Vec<KeyValue>) {
// Ignored
}

/// Ignores `Span` endings
fn end_with_timestamp(&mut self, _timestamp: SystemTime) {
// Ignored
Expand Down
16 changes: 16 additions & 0 deletions opentelemetry/src/trace/span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,22 @@ pub trait Span {
where
T: Into<Cow<'static, str>>;

/// Adds [`Link`] to another [`SpanContext`].
///
/// This method allows linking the current span to another span, identified by its `SpanContext`. Links can be used
/// to connect spans from different traces or within the same trace. Attributes can be attached to the link to
/// provide additional context or metadata.
///
/// # Arguments
///
/// * `span_context` - The `SpanContext` of the span to link to. This represents the target span's unique identifiers
/// and trace information.
/// * `attributes` - A vector of `KeyValue` pairs that describe additional attributes of the link. These attributes
/// can include any contextual information relevant to the link between the spans.
///
/// [`Link`]: crate::trace::Link
fn add_link(&mut self, span_context: SpanContext, attributes: Vec<KeyValue>);

/// Signals that the operation described by this span has now ended.
fn end(&mut self) {
self.end_with_timestamp(crate::time::now());
Expand Down

0 comments on commit ab39fd2

Please sign in to comment.