Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ internal ActivityChangedEventArgs(Activity? previous, Activity? current)
/// but the exception is suppressed, and the operation does something reasonable (typically
/// doing nothing).
/// </summary>
[DebuggerDisplay("{DebuggerDisplayString,nq}")]
[DebuggerTypeProxy(typeof(ActivityDebuggerProxy))]
public partial class Activity : IDisposable
{
#pragma warning disable CA1825 // Array.Empty<T>() doesn't exist in all configurations
Expand Down Expand Up @@ -1839,6 +1841,15 @@ public override string ToString()
}
}

private string DebuggerDisplayString
{
get
{
string? id = Id;
return $"OperationName = {OperationName}, Id = {(id is not null ? id : "(null)")}";
}
}

[Flags]
private enum State : byte
{
Expand Down Expand Up @@ -2168,4 +2179,30 @@ public void CopyTo(Span<byte> destination)
ActivityTraceId.SetSpanFromHexChars(ToHexString().AsSpan(), destination);
}
}

internal sealed class ActivityDebuggerProxy(Activity activity)
{
public ActivityTraceFlags ActivityTraceFlags => activity.ActivityTraceFlags;
public List<KeyValuePair<string, string?>> Baggage => new List<KeyValuePair<string, string?>>(activity.Baggage);
public ActivityContext Context => activity.Context;
public string DisplayName => activity.DisplayName;
public TimeSpan Duration => activity.Duration;
public List<ActivityEvent> Events => new List<ActivityEvent>(activity.Events);
public bool HasRemoteParent => activity.HasRemoteParent;
public string? Id => activity.Id;
public ActivityKind Kind => activity.Kind;
public List<ActivityLink> Links => new List<ActivityLink>(activity.Links);
public string OperationName => activity.OperationName;
public Activity? Parent => activity.Parent;
public string? ParentId => activity.ParentId;
public ActivitySpanId ParentSpanId => activity.ParentSpanId;
public ActivitySource Source => activity.Source;
public ActivitySpanId SpanId => activity.SpanId;
public DateTime StartTimeUtc => activity.StartTimeUtc;
public ActivityStatusCode Status => activity.Status;
public string? StatusDescription => activity.StatusDescription;
public List<KeyValuePair<string, object?>> TagObjects => new List<KeyValuePair<string, object?>>(activity.TagObjects);
public ActivityTraceId TraceId => activity.TraceId;
public string? TraceStateString => activity.TraceStateString;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace System.Diagnostics
/// ActivityContext representation conforms to the w3c TraceContext specification. It contains two identifiers
/// a TraceId and a SpanId - along with a set of common TraceFlags and system-specific TraceState values.
/// </summary>
[DebuggerDisplay("TraceId = {TraceId}, SpanId = {SpanId}, TraceFlags = {TraceFlags}")]
public readonly partial struct ActivityContext : IEquatable<ActivityContext>
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace System.Diagnostics
/// <summary>
/// A text annotation associated with a collection of tags.
/// </summary>
[DebuggerDisplay("Name = {Name}, Timestamp = {Timestamp}")]
public readonly struct ActivityEvent
{
private static readonly IEnumerable<KeyValuePair<string, object?>> s_emptyTags = Array.Empty<KeyValuePair<string, object?>>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace System.Diagnostics
/// Links can be used to represent batched operations where a Activity was initiated by multiple initiating Activities,
/// each representing a single incoming item being processed in the batch.
/// </summary>
[DebuggerDisplay("{DebuggerDisplayString,nq}")]
public readonly partial struct ActivityLink : IEquatable<ActivityLink>
{
private readonly Activity.TagsLinkedList? _tags;
Expand All @@ -38,6 +39,8 @@ public ActivityLink(ActivityContext context, ActivityTagsCollection? tags = null
/// </summary>
public IEnumerable<KeyValuePair<string, object?>>? Tags => _tags;

private string DebuggerDisplayString => $"TraceId = {Context.TraceId}, SpanId = {Context.SpanId}";

public override bool Equals([NotNullWhen(true)] object? obj) => (obj is ActivityLink link) && this.Equals(link);

public bool Equals(ActivityLink value) => Context == value.Context && value.Tags == Tags;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

namespace System.Diagnostics
{
[DebuggerDisplay("Name = {Name}")]
public sealed class ActivitySource : IDisposable
{
private static readonly SynchronizedList<ActivitySource> s_activeSources = new SynchronizedList<ActivitySource>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2548,5 +2548,65 @@ public void OnError(Exception error) { }
}

private const int MaxClockErrorMSec = 20;

[Fact]
public void TestActivityDebuggerDisplay()
{
Activity activity = new Activity("TestOperation");
activity.Start();

string debuggerDisplay = DebuggerAttributes.ValidateDebuggerDisplayReferences(activity);
Assert.Contains("OperationName = TestOperation", debuggerDisplay);
Assert.Contains("Id =", debuggerDisplay);

activity.Stop();
}

[Fact]
public void TestActivityDebuggerProxy()
{
Activity activity = new Activity("TestOperation");
activity.SetTag("key1", "value1");
activity.SetTag("key2", 42);
activity.SetBaggage("baggage1", "baggageValue1");
activity.AddEvent(new ActivityEvent("TestEvent"));
activity.Start();

DebuggerAttributes.ValidateDebuggerTypeProxyProperties(activity);

activity.Stop();
}

[Fact]
public void TestActivityContextDebuggerDisplay()
{
ActivityTraceId traceId = ActivityTraceId.CreateRandom();
ActivitySpanId spanId = ActivitySpanId.CreateRandom();
ActivityContext context = new ActivityContext(traceId, spanId, ActivityTraceFlags.Recorded);

string debuggerDisplay = DebuggerAttributes.ValidateDebuggerDisplayReferences(context);
Assert.NotNull(debuggerDisplay);
}

[Fact]
public void TestActivityLinkDebuggerDisplay()
{
ActivityTraceId traceId = ActivityTraceId.CreateRandom();
ActivitySpanId spanId = ActivitySpanId.CreateRandom();
ActivityContext context = new ActivityContext(traceId, spanId, ActivityTraceFlags.Recorded);
ActivityLink link = new ActivityLink(context);

DebuggerAttributes.ValidateDebuggerDisplayReferences(link);
}

[Fact]
public void TestActivityEventDebuggerDisplay()
{
ActivityEvent activityEvent = new ActivityEvent("TestEvent");

string debuggerDisplay = DebuggerAttributes.ValidateDebuggerDisplayReferences(activityEvent);
Assert.Contains("Name = \"TestEvent\"", debuggerDisplay);
Assert.Contains("Timestamp =", debuggerDisplay);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
</ItemGroup>

<ItemGroup>
<Compile Include="$(CommonTestPath)System\Diagnostics\DebuggerAttributes.cs" Link="Common\System\Diagnostics\DebuggerAttributes.cs" />
<Compile Include="..\src\System\Diagnostics\DsesSamplerBuilder.cs" Link="DsesSamplerBuilder.cs" />
<Compile Include="..\src\System\Diagnostics\RateLimiter.cs" Link="RateLimiter.cs" />
<Compile Include="..\src\System\Diagnostics\Helpers.cs" Link="Helpers.cs" />
Expand Down
Loading