Skip to content

Commit

Permalink
Fix displaying status message in span details (#7075)
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesNK authored Jan 14, 2025
1 parent 3cf908b commit d7b7807
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 17 deletions.
5 changes: 4 additions & 1 deletion src/Aspire.Dashboard/Otlp/Model/OtlpDisplayField.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;

namespace Aspire.Dashboard.Otlp.Model;

[DebuggerDisplay("Key = {Key}, Value = {Value}")]
public class OtlpDisplayField
{
public required string DisplayName { get; init; }
public required object Key { get; init; }
public required string Value{ get; init; }
public required string Value { get; init; }
}
2 changes: 1 addition & 1 deletion src/Aspire.Dashboard/Otlp/Model/OtlpSpan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public List<OtlpDisplayField> AllProperties()

if (!string.IsNullOrEmpty(StatusMessage))
{
props.Add(new OtlpDisplayField { DisplayName = "StatusMessage", Key = KnownTraceFields.StatusField, Value = Status.ToString() });
props.Add(new OtlpDisplayField { DisplayName = "StatusMessage", Key = KnownTraceFields.StatusMessageField, Value = StatusMessage });
}

foreach (var kv in Attributes.OrderBy(a => a.Key))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ public void Create_HasChildren_ChildrenPopulated()

var trace = new OtlpTrace(new byte[] { 1, 2, 3 });
var scope = new OtlpScope(TelemetryTestHelpers.CreateScope(), context);
trace.AddSpan(TelemetryTestHelpers.CreateSpan(app1, trace, scope, spanId: "1", parentSpanId: null, startDate: new DateTime(2001, 1, 1, 1, 1, 2, DateTimeKind.Utc)));
trace.AddSpan(TelemetryTestHelpers.CreateSpan(app2, trace, scope, spanId: "1-1", parentSpanId: "1", startDate: new DateTime(2001, 1, 1, 1, 1, 3, DateTimeKind.Utc)));
trace.AddSpan(TelemetryTestHelpers.CreateOtlpSpan(app1, trace, scope, spanId: "1", parentSpanId: null, startDate: new DateTime(2001, 1, 1, 1, 1, 2, DateTimeKind.Utc)));
trace.AddSpan(TelemetryTestHelpers.CreateOtlpSpan(app2, trace, scope, spanId: "1-1", parentSpanId: "1", startDate: new DateTime(2001, 1, 1, 1, 1, 3, DateTimeKind.Utc)));

// Act
var vm = SpanWaterfallViewModel.Create(trace, new SpanWaterfallViewModel.TraceDetailState([], []));
Expand Down
18 changes: 9 additions & 9 deletions tests/Aspire.Dashboard.Tests/Model/TraceHelpersTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public void GetOrderedApplications_SingleSpan_GroupedResult()
var app1 = new OtlpApplication("app1", "instance", context);
var trace = new OtlpTrace(new byte[] { 1, 2, 3 });
var scope = new OtlpScope(TelemetryTestHelpers.CreateScope(), context);
trace.AddSpan(TelemetryTestHelpers.CreateSpan(app1, trace, scope, spanId: "1", parentSpanId: null, startDate: new DateTime(2001, 1, 1, 1, 1, 1, DateTimeKind.Utc)));
trace.AddSpan(TelemetryTestHelpers.CreateOtlpSpan(app1, trace, scope, spanId: "1", parentSpanId: null, startDate: new DateTime(2001, 1, 1, 1, 1, 1, DateTimeKind.Utc)));

// Act
var results = TraceHelpers.GetOrderedApplications(trace);
Expand All @@ -41,8 +41,8 @@ public void GetOrderedApplications_MultipleUnparentedSpans_GroupedResult()
var app2 = new OtlpApplication("app2", "instance", context);
var trace = new OtlpTrace(new byte[] { 1, 2, 3 });
var scope = new OtlpScope(TelemetryTestHelpers.CreateScope(), context);
trace.AddSpan(TelemetryTestHelpers.CreateSpan(app2, trace, scope, spanId: "1-2", parentSpanId: "1", startDate: new DateTime(2001, 1, 1, 1, 1, 2, DateTimeKind.Utc)));
trace.AddSpan(TelemetryTestHelpers.CreateSpan(app1, trace, scope, spanId: "1-1", parentSpanId: "1", startDate: new DateTime(2001, 1, 1, 1, 1, 1, DateTimeKind.Utc)));
trace.AddSpan(TelemetryTestHelpers.CreateOtlpSpan(app2, trace, scope, spanId: "1-2", parentSpanId: "1", startDate: new DateTime(2001, 1, 1, 1, 1, 2, DateTimeKind.Utc)));
trace.AddSpan(TelemetryTestHelpers.CreateOtlpSpan(app1, trace, scope, spanId: "1-1", parentSpanId: "1", startDate: new DateTime(2001, 1, 1, 1, 1, 1, DateTimeKind.Utc)));

// Act
var results = TraceHelpers.GetOrderedApplications(trace);
Expand All @@ -68,8 +68,8 @@ public void GetOrderedApplications_ChildSpanAfterParentSpan_GroupedResult()
var app2 = new OtlpApplication("app2", "instance", context);
var trace = new OtlpTrace(new byte[] { 1, 2, 3 });
var scope = new OtlpScope(TelemetryTestHelpers.CreateScope(), context);
trace.AddSpan(TelemetryTestHelpers.CreateSpan(app1, trace, scope, spanId: "1", parentSpanId: null, startDate: new DateTime(2001, 1, 1, 1, 1, 2, DateTimeKind.Utc)));
trace.AddSpan(TelemetryTestHelpers.CreateSpan(app2, trace, scope, spanId: "1-1", parentSpanId: "1", startDate: new DateTime(2001, 1, 1, 1, 1, 1, DateTimeKind.Utc)));
trace.AddSpan(TelemetryTestHelpers.CreateOtlpSpan(app1, trace, scope, spanId: "1", parentSpanId: null, startDate: new DateTime(2001, 1, 1, 1, 1, 2, DateTimeKind.Utc)));
trace.AddSpan(TelemetryTestHelpers.CreateOtlpSpan(app2, trace, scope, spanId: "1-1", parentSpanId: "1", startDate: new DateTime(2001, 1, 1, 1, 1, 1, DateTimeKind.Utc)));

// Act
var results = TraceHelpers.GetOrderedApplications(trace);
Expand All @@ -96,10 +96,10 @@ public void GetOrderedApplications_ChildSpanDifferentStartTime_GroupedResult()
var app3 = new OtlpApplication("app3", "instance", context);
var trace = new OtlpTrace(new byte[] { 1, 2, 3 });
var scope = new OtlpScope(TelemetryTestHelpers.CreateScope(), context);
trace.AddSpan(TelemetryTestHelpers.CreateSpan(app1, trace, scope, spanId: "1", parentSpanId: null, startDate: new DateTime(2001, 1, 1, 1, 1, 2, DateTimeKind.Utc)));
trace.AddSpan(TelemetryTestHelpers.CreateSpan(app2, trace, scope, spanId: "1-1", parentSpanId: "1", startDate: new DateTime(2001, 1, 1, 1, 1, 3, DateTimeKind.Utc)));
trace.AddSpan(TelemetryTestHelpers.CreateSpan(app3, trace, scope, spanId: "1-1-1", parentSpanId: "1-1", startDate: new DateTime(2001, 1, 1, 1, 1, 2, DateTimeKind.Utc)));
trace.AddSpan(TelemetryTestHelpers.CreateSpan(app3, trace, scope, spanId: "1-2", parentSpanId: "1", startDate: new DateTime(2001, 1, 1, 1, 1, 2, DateTimeKind.Utc)));
trace.AddSpan(TelemetryTestHelpers.CreateOtlpSpan(app1, trace, scope, spanId: "1", parentSpanId: null, startDate: new DateTime(2001, 1, 1, 1, 1, 2, DateTimeKind.Utc)));
trace.AddSpan(TelemetryTestHelpers.CreateOtlpSpan(app2, trace, scope, spanId: "1-1", parentSpanId: "1", startDate: new DateTime(2001, 1, 1, 1, 1, 3, DateTimeKind.Utc)));
trace.AddSpan(TelemetryTestHelpers.CreateOtlpSpan(app3, trace, scope, spanId: "1-1-1", parentSpanId: "1-1", startDate: new DateTime(2001, 1, 1, 1, 1, 2, DateTimeKind.Utc)));
trace.AddSpan(TelemetryTestHelpers.CreateOtlpSpan(app3, trace, scope, spanId: "1-2", parentSpanId: "1", startDate: new DateTime(2001, 1, 1, 1, 1, 2, DateTimeKind.Utc)));

// Act
var results = TraceHelpers.GetOrderedApplications(trace);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Aspire.Dashboard.Model.Otlp;
using Aspire.Dashboard.Otlp.Model;
using Aspire.Tests.Shared.Telemetry;
using Microsoft.Extensions.Logging.Abstractions;
using Xunit;

namespace Aspire.Dashboard.Tests.TelemetryRepositoryTests;

public class OtlpSpanTests
{
private static readonly DateTime s_testTime = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

[Fact]
public void AllProperties()
{
// Arrange
var context = new OtlpContext { Logger = NullLogger.Instance, Options = new() };
var app1 = new OtlpApplication("app1", "instance", context);
var trace = new OtlpTrace(new byte[] { 1, 2, 3 });
var scope = new OtlpScope(TelemetryTestHelpers.CreateScope(), context);

var span = TelemetryTestHelpers.CreateOtlpSpan(app1, trace, scope, spanId: "abc", parentSpanId: null, startDate: s_testTime,
statusCode: OtlpSpanStatusCode.Ok, statusMessage: "Status message!", attributes: [new KeyValuePair<string, string>(KnownTraceFields.StatusMessageField, "value")]);

// Act
var properties = span.AllProperties();

// Assert
Assert.Collection(properties,
a =>
{
Assert.Equal("trace.spanid", a.Key);
Assert.Equal("abc", a.Value);
},
a =>
{
Assert.Equal("trace.name", a.Key);
Assert.Equal("Test", a.Value);
},
a =>
{
Assert.Equal("trace.kind", a.Key);
Assert.Equal("Unspecified", a.Value);
},
a =>
{
Assert.Equal("trace.status", a.Key);
Assert.Equal("Ok", a.Value);
},
a =>
{
Assert.Equal("trace.statusmessage", a.Key);
Assert.Equal("Status message!", a.Value);
},
a =>
{
Assert.Equal("unknown-trace.statusmessage", a.Key);
Assert.Equal("value", a.Value);
});
}
}
9 changes: 5 additions & 4 deletions tests/Shared/Telemetry/TelemetryTestHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,11 +287,12 @@ public static OtlpContext CreateContext(TelemetryLimitOptions? options = null, I
};
}

public static OtlpSpan CreateSpan(OtlpApplication app, OtlpTrace trace, OtlpScope scope, string spanId, string? parentSpanId, DateTime startDate)
public static OtlpSpan CreateOtlpSpan(OtlpApplication app, OtlpTrace trace, OtlpScope scope, string spanId, string? parentSpanId, DateTime startDate,
KeyValuePair<string, string>[]? attributes = null, OtlpSpanStatusCode? statusCode = null, string? statusMessage = null)
{
return new OtlpSpan(app.GetView([]), trace, scope)
{
Attributes = [],
Attributes = attributes ?? [],
BackLinks = [],
EndTime = DateTime.MaxValue,
Events = [],
Expand All @@ -302,8 +303,8 @@ public static OtlpSpan CreateSpan(OtlpApplication app, OtlpTrace trace, OtlpScop
SpanId = spanId,
StartTime = startDate,
State = null,
Status = OtlpSpanStatusCode.Unset,
StatusMessage = null
Status = statusCode ?? OtlpSpanStatusCode.Unset,
StatusMessage = statusMessage
};
}
}

0 comments on commit d7b7807

Please sign in to comment.