Skip to content

Commit ab39fd2

Browse files
lalitbhdostcijothomasTommyCpp
authored
Add add_link API (#1515)
Co-authored-by: Harold Dost <github@hdost.com> Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com> Co-authored-by: Zhongyang Wu <zhongyang.wu@outlook.com>
1 parent 13c9dc5 commit ab39fd2

File tree

8 files changed

+115
-35
lines changed

8 files changed

+115
-35
lines changed

opentelemetry-sdk/src/trace/links.rs

+6
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,9 @@ impl IntoIterator for SpanLinks {
2929
self.links.into_iter()
3030
}
3131
}
32+
33+
impl SpanLinks {
34+
pub(crate) fn add_link(&mut self, link: Link) {
35+
self.links.push(link);
36+
}
37+
}

opentelemetry-sdk/src/trace/mod.rs

+7-10
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,13 @@ mod tests {
181181

182182
let mut links = Vec::new();
183183
for _i in 0..(DEFAULT_MAX_LINKS_PER_SPAN * 2) {
184-
links.push(Link::new(
185-
SpanContext::new(
186-
TraceId::from_u128(12),
187-
SpanId::from_u64(12),
188-
TraceFlags::default(),
189-
false,
190-
Default::default(),
191-
),
192-
Vec::new(),
193-
))
184+
links.push(Link::with_context(SpanContext::new(
185+
TraceId::from_u128(12),
186+
SpanId::from_u64(12),
187+
TraceFlags::default(),
188+
false,
189+
Default::default(),
190+
)))
194191
}
195192

196193
let span_builder = SpanBuilder::from_name("span_name").with_links(links);

opentelemetry-sdk/src/trace/span.rs

+50-22
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//! These cannot be changed after the `Span`'s end time has been set.
1111
use crate::trace::SpanLimits;
1212
use crate::Resource;
13-
use opentelemetry::trace::{Event, SpanContext, SpanId, SpanKind, Status};
13+
use opentelemetry::trace::{Event, Link, SpanContext, SpanId, SpanKind, Status};
1414
use opentelemetry::KeyValue;
1515
use std::borrow::Cow;
1616
use std::time::SystemTime;
@@ -170,6 +170,28 @@ impl opentelemetry::trace::Span for Span {
170170
});
171171
}
172172

173+
/// Add `Link` to this `Span`
174+
///
175+
fn add_link(&mut self, span_context: SpanContext, attributes: Vec<KeyValue>) {
176+
let span_links_limit = self.span_limits.max_links_per_span as usize;
177+
let link_attributes_limit = self.span_limits.max_attributes_per_link as usize;
178+
self.with_data(|data| {
179+
if data.links.links.len() < span_links_limit {
180+
let dropped_attributes_count =
181+
attributes.len().saturating_sub(link_attributes_limit);
182+
let mut attributes = attributes;
183+
attributes.truncate(link_attributes_limit);
184+
data.links.add_link(Link::new(
185+
span_context,
186+
attributes,
187+
dropped_attributes_count as u32,
188+
));
189+
} else {
190+
data.links.dropped_count += 1;
191+
}
192+
});
193+
}
194+
173195
/// Finishes the span with given timestamp.
174196
fn end_with_timestamp(&mut self, timestamp: SystemTime) {
175197
self.ensure_ended_and_exported(Some(timestamp));
@@ -595,16 +617,13 @@ mod tests {
595617
let provider = provider_builder.build();
596618
let tracer = provider.tracer("opentelemetry-test");
597619

598-
let mut link = Link::new(
599-
SpanContext::new(
600-
TraceId::from_u128(12),
601-
SpanId::from_u64(12),
602-
TraceFlags::default(),
603-
false,
604-
Default::default(),
605-
),
606-
Vec::new(),
607-
);
620+
let mut link = Link::with_context(SpanContext::new(
621+
TraceId::from_u128(12),
622+
SpanId::from_u64(12),
623+
TraceFlags::default(),
624+
false,
625+
Default::default(),
626+
));
608627
for i in 0..(DEFAULT_MAX_ATTRIBUTES_PER_LINK * 2) {
609628
link.attributes
610629
.push(KeyValue::new(format!("key {}", i), i.to_string()));
@@ -632,20 +651,29 @@ mod tests {
632651

633652
let mut links = Vec::new();
634653
for _i in 0..(DEFAULT_MAX_LINKS_PER_SPAN * 2) {
635-
links.push(Link::new(
636-
SpanContext::new(
637-
TraceId::from_u128(12),
638-
SpanId::from_u64(12),
639-
TraceFlags::default(),
640-
false,
641-
Default::default(),
642-
),
643-
Vec::new(),
644-
))
654+
links.push(Link::with_context(SpanContext::new(
655+
TraceId::from_u128(12),
656+
SpanId::from_u64(12),
657+
TraceFlags::default(),
658+
false,
659+
Default::default(),
660+
)))
645661
}
646662

647663
let span_builder = tracer.span_builder("test").with_links(links);
648-
let span = tracer.build(span_builder);
664+
let mut span = tracer.build(span_builder);
665+
666+
// add links using span api after building the span
667+
span.add_link(
668+
SpanContext::new(
669+
TraceId::from_u128(12),
670+
SpanId::from_u64(12),
671+
TraceFlags::default(),
672+
false,
673+
Default::default(),
674+
),
675+
vec![],
676+
);
649677
let link_queue = span
650678
.data
651679
.clone()

opentelemetry/src/global/trace.rs

+14
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ pub trait ObjectSafeSpan {
8686
/// filtering decisions made previously depending on the implementation.
8787
fn update_name(&mut self, new_name: Cow<'static, str>);
8888

89+
/// Adds a link to this span
90+
///
91+
fn add_link(&mut self, span_context: SpanContext, attributes: Vec<KeyValue>);
92+
8993
/// Finishes the `Span`.
9094
///
9195
/// Implementations MUST ignore all subsequent calls to `end` (there might be
@@ -138,6 +142,10 @@ impl<T: trace::Span> ObjectSafeSpan for T {
138142
self.update_name(new_name)
139143
}
140144

145+
fn add_link(&mut self, span_context: SpanContext, attributes: Vec<KeyValue>) {
146+
self.add_link(span_context, attributes)
147+
}
148+
141149
fn end_with_timestamp(&mut self, timestamp: SystemTime) {
142150
self.end_with_timestamp(timestamp)
143151
}
@@ -216,6 +224,12 @@ impl trace::Span for BoxedSpan {
216224
self.0.update_name(new_name.into())
217225
}
218226

227+
/// Adds a link to this span
228+
///
229+
fn add_link(&mut self, span_context: trace::SpanContext, attributes: Vec<KeyValue>) {
230+
self.0.add_link(span_context, attributes)
231+
}
232+
219233
/// Finishes the span with given timestamp.
220234
fn end_with_timestamp(&mut self, timestamp: SystemTime) {
221235
self.0.end_with_timestamp(timestamp);

opentelemetry/src/testing/trace.rs

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ impl Span for TestSpan {
3030
T: Into<Cow<'static, str>>,
3131
{
3232
}
33+
34+
fn add_link(&mut self, _span_context: SpanContext, _attributes: Vec<KeyValue>) {}
3335
fn end_with_timestamp(&mut self, _timestamp: std::time::SystemTime) {}
3436
}
3537

opentelemetry/src/trace/mod.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -302,11 +302,24 @@ pub struct Link {
302302
}
303303

304304
impl Link {
305-
/// Create a new link.
306-
pub fn new(span_context: SpanContext, attributes: Vec<KeyValue>) -> Self {
305+
/// Create new `Link`
306+
pub fn new(
307+
span_context: SpanContext,
308+
attributes: Vec<KeyValue>,
309+
dropped_attributes_count: u32,
310+
) -> Self {
307311
Link {
308312
span_context,
309313
attributes,
314+
dropped_attributes_count,
315+
}
316+
}
317+
318+
/// Create new `Link` with given context
319+
pub fn with_context(span_context: SpanContext) -> Self {
320+
Link {
321+
span_context,
322+
attributes: Vec::new(),
310323
dropped_attributes_count: 0,
311324
}
312325
}

opentelemetry/src/trace/noop.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ impl trace::Span for NoopSpan {
5151
where
5252
T: Into<Cow<'static, str>>,
5353
{
54-
// Ignore
54+
// Ignored
5555
}
5656

5757
/// Ignores all events with timestamps
@@ -94,6 +94,10 @@ impl trace::Span for NoopSpan {
9494
// Ignored
9595
}
9696

97+
fn add_link(&mut self, _span_context: trace::SpanContext, _attributes: Vec<KeyValue>) {
98+
// Ignored
99+
}
100+
97101
/// Ignores `Span` endings
98102
fn end_with_timestamp(&mut self, _timestamp: SystemTime) {
99103
// Ignored

opentelemetry/src/trace/span.rs

+16
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,22 @@ pub trait Span {
154154
where
155155
T: Into<Cow<'static, str>>;
156156

157+
/// Adds [`Link`] to another [`SpanContext`].
158+
///
159+
/// This method allows linking the current span to another span, identified by its `SpanContext`. Links can be used
160+
/// to connect spans from different traces or within the same trace. Attributes can be attached to the link to
161+
/// provide additional context or metadata.
162+
///
163+
/// # Arguments
164+
///
165+
/// * `span_context` - The `SpanContext` of the span to link to. This represents the target span's unique identifiers
166+
/// and trace information.
167+
/// * `attributes` - A vector of `KeyValue` pairs that describe additional attributes of the link. These attributes
168+
/// can include any contextual information relevant to the link between the spans.
169+
///
170+
/// [`Link`]: crate::trace::Link
171+
fn add_link(&mut self, span_context: SpanContext, attributes: Vec<KeyValue>);
172+
157173
/// Signals that the operation described by this span has now ended.
158174
fn end(&mut self) {
159175
self.end_with_timestamp(crate::time::now());

0 commit comments

Comments
 (0)