Skip to content
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

Add add_link API #1515

Merged
merged 15 commits into from
Mar 19, 2024
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,
lalitb marked this conversation as resolved.
Show resolved Hide resolved
) -> 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
15 changes: 15 additions & 0 deletions opentelemetry/src/trace/span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,21 @@ pub trait Span {
where
T: Into<Cow<'static, str>>;

/// Adds a 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.
///
hdost marked this conversation as resolved.
Show resolved Hide resolved
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
Loading