diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj
index 68082e5a183c94..90126cf85da13e 100644
--- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj
+++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj
@@ -87,6 +87,7 @@ System.Diagnostics.DiagnosticSource
+
@@ -107,7 +108,6 @@ System.Diagnostics.DiagnosticSource
-
diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs
index e7d36273408355..e33938066d9d24 100644
--- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs
+++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs
@@ -58,8 +58,8 @@ public partial class Activity : IDisposable
#pragma warning disable CA1825 // Array.Empty() doesn't exist in all configurations
private static readonly IEnumerable> s_emptyBaggageTags = new KeyValuePair[0];
private static readonly IEnumerable> s_emptyTagObjects = new KeyValuePair[0];
- private static readonly IEnumerable s_emptyLinks = new ActivityLink[0];
- private static readonly IEnumerable s_emptyEvents = new ActivityEvent[0];
+ private static readonly IEnumerable s_emptyLinks = new DiagLinkedList();
+ private static readonly IEnumerable s_emptyEvents = new DiagLinkedList();
#pragma warning restore CA1825
private static readonly ActivitySource s_defaultSource = new ActivitySource(string.Empty);
private static readonly AsyncLocal s_current = new AsyncLocal();
diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySource.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySource.cs
index 8b3cdebadc1ead..8a207ae838ac4c 100644
--- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySource.cs
+++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySource.cs
@@ -59,21 +59,18 @@ private ActivitySource(string name, string? version, IEnumerable 0)
+ s_allListeners.EnumWithAction((listener, source) =>
{
- s_allListeners.EnumWithAction((listener, source) =>
+ Func? shouldListenTo = listener.ShouldListenTo;
+ if (shouldListenTo != null)
{
- Func? shouldListenTo = listener.ShouldListenTo;
- if (shouldListenTo != null)
+ var activitySource = (ActivitySource)source;
+ if (shouldListenTo(activitySource))
{
- var activitySource = (ActivitySource)source;
- if (shouldListenTo(activitySource))
- {
- activitySource.AddListener(listener);
- }
+ activitySource.AddListener(listener);
}
- }, this);
- }
+ }
+ }, this);
GC.KeepAlive(DiagnosticSourceEventSource.Log);
}
diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagLinkedList.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagLinkedList.cs
index 7a0ea5004e0fd4..439be3dc509783 100644
--- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagLinkedList.cs
+++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagLinkedList.cs
@@ -3,6 +3,7 @@
using System.Collections;
using System.Collections.Generic;
+using System.Text;
namespace System.Diagnostics
{
@@ -149,6 +150,121 @@ public void AddFront(T value)
public DiagEnumerator GetEnumerator() => new DiagEnumerator(_first);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+
+ private static void ActivityLinkToString(ref ActivityLink al, ref ValueStringBuilder vsb)
+ {
+ ActivityContext ac = al.Context;
+
+ vsb.Append("(");
+ vsb.Append(ac.TraceId.ToHexString());
+ vsb.Append(",\u200B");
+ vsb.Append(ac.SpanId.ToHexString());
+ vsb.Append(",\u200B");
+ vsb.Append(ac.TraceFlags.ToString());
+ vsb.Append(",\u200B");
+ vsb.Append(ac.TraceState ?? "null");
+ vsb.Append(",\u200B");
+ vsb.Append(ac.IsRemote ? "true" : "false");
+
+ if (al.Tags is not null)
+ {
+ vsb.Append(",\u200B[");
+ string sep = "";
+ foreach (KeyValuePair kvp in al.EnumerateTagObjects())
+ {
+ vsb.Append(sep);
+ vsb.Append(kvp.Key);
+ vsb.Append(":\u200B");
+ vsb.Append(kvp.Value?.ToString() ?? "null");
+ sep = ",\u200B";
+ }
+
+ vsb.Append("]");
+ }
+ vsb.Append(")");
+ }
+
+ private static void ActivityEventToString(ref ActivityEvent ae, ref ValueStringBuilder vsb)
+ {
+ vsb.Append("(");
+ vsb.Append(ae.Name);
+ vsb.Append(",\u200B");
+ vsb.Append(ae.Timestamp.ToString("o"));
+
+ if (ae.Tags is not null)
+ {
+ vsb.Append(",\u200B[");
+ string sep = "";
+ foreach (KeyValuePair kvp in ae.EnumerateTagObjects())
+ {
+ vsb.Append(sep);
+ vsb.Append(kvp.Key);
+ vsb.Append(":\u200B");
+ vsb.Append(kvp.Value?.ToString() ?? "null");
+ sep = ",\u200B";
+ }
+
+ vsb.Append("]");
+ }
+ vsb.Append(")");
+ }
+
+ public override string ToString()
+ {
+ lock (this)
+ {
+ DiagNode? current = _first;
+ if (current is null)
+ {
+ return "[]";
+ }
+
+ var vsb = new ValueStringBuilder(stackalloc char[256]);
+ vsb.Append("[");
+
+ if (typeof(T) == typeof(ActivityLink))
+ {
+ while (current is not null)
+ {
+ ActivityLink al = (ActivityLink)(object)current.Value!;
+ ActivityLinkToString(ref al, ref vsb);
+ current = current.Next;
+ if (current is not null)
+ {
+ vsb.Append(",\u200B");
+ }
+ }
+ }
+ else if (typeof(T) == typeof(ActivityEvent))
+ {
+ while (current is not null)
+ {
+ ActivityEvent ae = (ActivityEvent)(object)current.Value!;
+ ActivityEventToString(ref ae, ref vsb);
+ current = current.Next;
+ if (current is not null)
+ {
+ vsb.Append(",\u200B");
+ }
+ }
+ }
+ else
+ {
+ while (current is not null)
+ {
+ vsb.Append(current.Value?.ToString() ?? "null");
+ current = current.Next;
+ if (current is not null)
+ {
+ vsb.Append(",\u200B");
+ }
+ }
+ }
+
+ vsb.Append("]");
+ return vsb.ToString();
+ }
+ }
}
internal struct DiagEnumerator : IEnumerator
diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs
index 435fde8804035e..ace36d95253df0 100644
--- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs
+++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs
@@ -2422,6 +2422,100 @@ public void EnumerateEventTagsTest()
}
}
+ [Fact]
+ public void TestLinksToString()
+ {
+ Activity activity = new Activity("testLinksActivity");
+
+ Assert.Equal("[]", activity.Links.ToString());
+
+ activity.AddLink(new ActivityLink(new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded), new ActivityTagsCollection { ["alk1"] = "alv1", ["alk2"] = "alv2", ["alk3"] = null }));
+ activity.AddLink(new ActivityLink(new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None)));
+
+ string formattedLinks = "[";
+ string linkSep = "";
+ foreach (ActivityLink link in activity.Links)
+ {
+ ActivityContext ac = link.Context;
+
+ formattedLinks += $"{linkSep}(";
+ formattedLinks += ac.TraceId.ToHexString();
+ formattedLinks += ",\u200B";
+ formattedLinks += ac.SpanId.ToHexString();
+ formattedLinks += ",\u200B";
+ formattedLinks += ac.TraceFlags.ToString();
+ formattedLinks += ",\u200B";
+ formattedLinks += ac.TraceState ?? "null";
+ formattedLinks += ",\u200B";
+ formattedLinks += ac.IsRemote ? "true" : "false";
+
+ if (link.Tags is not null)
+ {
+ formattedLinks += ",\u200B[";
+ string sep = "";
+ foreach (KeyValuePair kvp in link.EnumerateTagObjects())
+ {
+ formattedLinks += sep;
+ formattedLinks += kvp.Key;
+ formattedLinks += ":\u200B";
+ formattedLinks += kvp.Value?.ToString() ?? "null";
+ sep = ",\u200B";
+ }
+
+ formattedLinks += "]";
+ }
+ formattedLinks += ")";
+ linkSep = ",\u200B";
+ }
+ formattedLinks += "]";
+
+ Assert.Equal(formattedLinks, activity.Links.ToString());
+ }
+
+ [Fact]
+ public void TestEventsToString()
+ {
+ Activity activity = new Activity("testLinksActivity");
+
+ Assert.Equal("[]", activity.Events.ToString());
+
+ activity.AddEvent(new ActivityEvent("TestEvent1", DateTime.UtcNow, new ActivityTagsCollection { { "E11", "EV1" }, { "E12", "EV2" } }));
+ activity.AddEvent(new ActivityEvent("TestEvent2", DateTime.UtcNow.AddSeconds(10), new ActivityTagsCollection { { "E21", "EV21" }, { "E22", "EV22" } }));
+
+ string formattedEvents = "[";
+ string linkSep = "";
+
+ foreach (var e in activity.Events)
+ {
+ formattedEvents += $"{linkSep}(";
+ formattedEvents += e.Name;
+ formattedEvents += ",\u200B";
+ formattedEvents += e.Timestamp.ToString("o");
+
+ if (e.Tags is not null)
+ {
+ formattedEvents += ",\u200B[";
+ string sep = "";
+ foreach (KeyValuePair kvp in e.EnumerateTagObjects())
+ {
+ formattedEvents += sep;
+ formattedEvents += kvp.Key;
+ formattedEvents += ":\u200B";
+ formattedEvents += kvp.Value?.ToString() ?? "null";
+ sep = ",\u200B";
+ }
+
+ formattedEvents += "]";
+ }
+
+ formattedEvents += ")";
+ linkSep = ",\u200B";
+ }
+
+ formattedEvents += "]";
+ Assert.Equal(formattedEvents, activity.Events.ToString());
+ }
+
public void Dispose()
{
Activity.Current = null;
diff --git a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs
index 335642fdb1fd15..9963885aad5aa7 100644
--- a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs
@@ -977,7 +977,7 @@ public bool HasSameRules(TimeZoneInfo other)
// "TimeZoneInfo" := TimeZoneInfo Data;[AdjustmentRule Data 1];...;[AdjustmentRule Data N]
//
// "TimeZoneInfo Data" := <_id>;<_baseUtcOffset>;<_displayName>;
- // <_standardDisplayName>;<_daylightDispayName>;
+ // <_standardDisplayName>;<_daylightDisplayName>;
//
// "AdjustmentRule Data" := ;;;
// [TransitionTime Data DST Start]