Skip to content

Commit

Permalink
Implement Activity.AddLink (#101381)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
antonfirsov authored Apr 26, 2024
1 parent c5ca516 commit c29b591
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public string? Id
public string? TraceStateString { get { throw null; } set { } }
public System.Diagnostics.Activity AddBaggage(string key, string? value) { throw null; }
public System.Diagnostics.Activity AddEvent(System.Diagnostics.ActivityEvent e) { throw null; }
public System.Diagnostics.Activity AddLink(System.Diagnostics.ActivityLink link) { throw null; }
public System.Diagnostics.Activity AddTag(string key, string? value) { throw null; }
public System.Diagnostics.Activity AddTag(string key, object? value) { throw null; }
public System.Diagnostics.Activity SetTag(string key, object? value) { throw null; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,25 @@ public Activity AddEvent(ActivityEvent e)
return this;
}

/// <summary>
/// Add an <see cref="ActivityLink"/> to the <see cref="Links"/> list.
/// </summary>
/// <param name="link">The <see cref="ActivityLink"/> to add.</param>
/// <returns><see langword="this" /> for convenient chaining.</returns>
/// <remarks>
/// For contexts that are available during span creation, adding links at span creation is preferred to calling <see cref="AddLink(ActivityLink)" /> later,
/// because head sampling decisions can only consider information present during span creation.
/// </remarks>
public Activity AddLink(ActivityLink link)
{
if (_links != null || Interlocked.CompareExchange(ref _links, new DiagLinkedList<ActivityLink>(link), null) != null)
{
_links.Add(link);
}

return this;
}

/// <summary>
/// Update the Activity to have baggage with an additional 'key' and value 'value'.
/// This shows up in the <see cref="Baggage"/> enumeration as well as the <see cref="GetBaggageItem(string)"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1597,6 +1597,35 @@ public void TestEvent()
Assert.Equal(0, activity.Events.ElementAt(1).Tags.Count());
}

[Fact]
public void AddLinkTest()
{
ActivityContext c1 = new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None);
ActivityContext c2 = new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None);

ActivityLink l1 = new ActivityLink(c1);
ActivityLink l2 = new ActivityLink(c2, new ActivityTagsCollection()
{
new KeyValuePair<string, object?>("foo", 99)
});

Activity activity = new Activity("LinkTest");
Assert.True(ReferenceEquals(activity, activity.AddLink(l1)));
Assert.True(ReferenceEquals(activity, activity.AddLink(l2)));

// Add a duplicate of l1. The implementation doesn't check for duplicates.
Assert.True(ReferenceEquals(activity, activity.AddLink(l1)));

ActivityLink[] links = activity.Links.ToArray();
Assert.Equal(3, links.Length);
Assert.Equal(c1, links[0].Context);
Assert.Equal(c2, links[1].Context);
Assert.Equal(c1, links[2].Context);
KeyValuePair<string, object> tag = links[1].Tags.Single();
Assert.Equal("foo", tag.Key);
Assert.Equal(99, tag.Value);
}

[Fact]
public void TestIsAllDataRequested()
{
Expand Down Expand Up @@ -2163,12 +2192,14 @@ public void EnumerateLinksTest()

var context1 = new ActivityContext(ActivityTraceId.CreateRandom(), default, ActivityTraceFlags.None);
var context2 = new ActivityContext(ActivityTraceId.CreateRandom(), default, ActivityTraceFlags.None);
var context3 = new ActivityContext(ActivityTraceId.CreateRandom(), default, ActivityTraceFlags.None);

a = source.CreateActivity(
name: "Root",
kind: ActivityKind.Internal,
parentContext: default,
links: new[] { new ActivityLink(context1), new ActivityLink(context2) });
a.AddLink(new ActivityLink(context3));

Assert.NotNull(a);

Expand All @@ -2182,6 +2213,9 @@ public void EnumerateLinksTest()
Assert.True(enumerator.MoveNext());
Assert.Equal(context2.TraceId, enumerator.Current.Context.TraceId);
values.Add(enumerator.Current);
Assert.True(enumerator.MoveNext());
Assert.Equal(context3.TraceId, enumerator.Current.Context.TraceId);
values.Add(enumerator.Current);
Assert.False(enumerator.MoveNext());

Assert.Equal(a.Links, values);
Expand Down

0 comments on commit c29b591

Please sign in to comment.