Skip to content

Commit 06c5775

Browse files
antonfirsovmichaelgsharp
authored andcommitted
Implement Activity.AddLink (dotnet#101381)
* implement Activity.AddLink * extend tests * Add remarks to docs required by https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#link
1 parent 85f3ea0 commit 06c5775

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSourceActivity.cs

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public string? Id
5050
public string? TraceStateString { get { throw null; } set { } }
5151
public System.Diagnostics.Activity AddBaggage(string key, string? value) { throw null; }
5252
public System.Diagnostics.Activity AddEvent(System.Diagnostics.ActivityEvent e) { throw null; }
53+
public System.Diagnostics.Activity AddLink(System.Diagnostics.ActivityLink link) { throw null; }
5354
public System.Diagnostics.Activity AddTag(string key, string? value) { throw null; }
5455
public System.Diagnostics.Activity AddTag(string key, object? value) { throw null; }
5556
public System.Diagnostics.Activity SetTag(string key, object? value) { throw null; }

src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs

+19
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,25 @@ public Activity AddEvent(ActivityEvent e)
517517
return this;
518518
}
519519

520+
/// <summary>
521+
/// Add an <see cref="ActivityLink"/> to the <see cref="Links"/> list.
522+
/// </summary>
523+
/// <param name="link">The <see cref="ActivityLink"/> to add.</param>
524+
/// <returns><see langword="this" /> for convenient chaining.</returns>
525+
/// <remarks>
526+
/// For contexts that are available during span creation, adding links at span creation is preferred to calling <see cref="AddLink(ActivityLink)" /> later,
527+
/// because head sampling decisions can only consider information present during span creation.
528+
/// </remarks>
529+
public Activity AddLink(ActivityLink link)
530+
{
531+
if (_links != null || Interlocked.CompareExchange(ref _links, new DiagLinkedList<ActivityLink>(link), null) != null)
532+
{
533+
_links.Add(link);
534+
}
535+
536+
return this;
537+
}
538+
520539
/// <summary>
521540
/// Update the Activity to have baggage with an additional 'key' and value 'value'.
522541
/// This shows up in the <see cref="Baggage"/> enumeration as well as the <see cref="GetBaggageItem(string)"/>

src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs

+34
Original file line numberDiff line numberDiff line change
@@ -1597,6 +1597,35 @@ public void TestEvent()
15971597
Assert.Equal(0, activity.Events.ElementAt(1).Tags.Count());
15981598
}
15991599

1600+
[Fact]
1601+
public void AddLinkTest()
1602+
{
1603+
ActivityContext c1 = new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None);
1604+
ActivityContext c2 = new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None);
1605+
1606+
ActivityLink l1 = new ActivityLink(c1);
1607+
ActivityLink l2 = new ActivityLink(c2, new ActivityTagsCollection()
1608+
{
1609+
new KeyValuePair<string, object?>("foo", 99)
1610+
});
1611+
1612+
Activity activity = new Activity("LinkTest");
1613+
Assert.True(ReferenceEquals(activity, activity.AddLink(l1)));
1614+
Assert.True(ReferenceEquals(activity, activity.AddLink(l2)));
1615+
1616+
// Add a duplicate of l1. The implementation doesn't check for duplicates.
1617+
Assert.True(ReferenceEquals(activity, activity.AddLink(l1)));
1618+
1619+
ActivityLink[] links = activity.Links.ToArray();
1620+
Assert.Equal(3, links.Length);
1621+
Assert.Equal(c1, links[0].Context);
1622+
Assert.Equal(c2, links[1].Context);
1623+
Assert.Equal(c1, links[2].Context);
1624+
KeyValuePair<string, object> tag = links[1].Tags.Single();
1625+
Assert.Equal("foo", tag.Key);
1626+
Assert.Equal(99, tag.Value);
1627+
}
1628+
16001629
[Fact]
16011630
public void TestIsAllDataRequested()
16021631
{
@@ -2163,12 +2192,14 @@ public void EnumerateLinksTest()
21632192

21642193
var context1 = new ActivityContext(ActivityTraceId.CreateRandom(), default, ActivityTraceFlags.None);
21652194
var context2 = new ActivityContext(ActivityTraceId.CreateRandom(), default, ActivityTraceFlags.None);
2195+
var context3 = new ActivityContext(ActivityTraceId.CreateRandom(), default, ActivityTraceFlags.None);
21662196

21672197
a = source.CreateActivity(
21682198
name: "Root",
21692199
kind: ActivityKind.Internal,
21702200
parentContext: default,
21712201
links: new[] { new ActivityLink(context1), new ActivityLink(context2) });
2202+
a.AddLink(new ActivityLink(context3));
21722203

21732204
Assert.NotNull(a);
21742205

@@ -2182,6 +2213,9 @@ public void EnumerateLinksTest()
21822213
Assert.True(enumerator.MoveNext());
21832214
Assert.Equal(context2.TraceId, enumerator.Current.Context.TraceId);
21842215
values.Add(enumerator.Current);
2216+
Assert.True(enumerator.MoveNext());
2217+
Assert.Equal(context3.TraceId, enumerator.Current.Context.TraceId);
2218+
values.Add(enumerator.Current);
21852219
Assert.False(enumerator.MoveNext());
21862220

21872221
Assert.Equal(a.Links, values);

0 commit comments

Comments
 (0)