From ac6b0f432a7b6ca4208947f6e0896e64e3b3776c Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Thu, 28 May 2026 19:36:08 +0800 Subject: [PATCH 1/2] Improve dashboard summary log formatting - Indent URL lines with 6 spaces and '- ' prefix so they align with the standard log output indentation - Move container warning to a separate log message with clearer text - Update tests to match new format --- src/Shared/LoggingHelpers.cs | 20 ++++++----- .../LoggingHelpersTests.cs | 34 +++++++++---------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/Shared/LoggingHelpers.cs b/src/Shared/LoggingHelpers.cs index d5c2f0b5f3e..c6e593e7ddc 100644 --- a/src/Shared/LoggingHelpers.cs +++ b/src/Shared/LoggingHelpers.cs @@ -44,37 +44,41 @@ public static void WriteDashboardSummary(ILogger logger, string? dashboardUrl, s .Append("Aspire Dashboard").Append('\n') .Append('\n'); + // The default .NET console logger indents the first line 6 characters because of the level. + // This prefix aligns the URLs under the dashboard title and makes them easier to read. + // In other logging layouts the prefix is just extra spaces, but it doesn't cause any real issues. + var prefix = " "; + if (dashboardAuthority is not null) { - templateBuilder.Append("Dashboard: {DashboardUrl}").Append('\n'); + templateBuilder.Append(prefix).Append("- Dashboard: {DashboardUrl}").Append('\n'); parameters.Add(dashboardAuthority); } if (loginUrl is not null) { - templateBuilder.Append("Login URL: {LoginUrl}").Append('\n'); + templateBuilder.Append(prefix).Append("- Login URL: {LoginUrl}").Append('\n'); parameters.Add(loginUrl); } if (otlpGrpcAuthority is not null) { - templateBuilder.Append("OTLP/gRPC: {OtlpGrpcUrl}").Append('\n'); + templateBuilder.Append(prefix).Append("- OTLP/gRPC: {OtlpGrpcUrl}").Append('\n'); parameters.Add(otlpGrpcAuthority); } if (otlpHttpAuthority is not null) { - templateBuilder.Append("OTLP/HTTP: {OtlpHttpUrl}").Append('\n'); + templateBuilder.Append(prefix).Append("- OTLP/HTTP: {OtlpHttpUrl}").Append('\n'); parameters.Add(otlpHttpAuthority); } + logger.LogInformation(templateBuilder.ToString(), parameters.ToArray()); + if (isContainer) { - templateBuilder.Append('\n'); - templateBuilder.Append("URLs may need changes depending on how network access to the container is configured.").Append('\n'); + logger.LogInformation("Dashboard is running in a container. Access the dashboard from the host using port forwarding."); } - - logger.LogInformation(templateBuilder.ToString(), parameters.ToArray()); } [Conditional("DEBUG")] diff --git a/tests/Aspire.Dashboard.Tests/LoggingHelpersTests.cs b/tests/Aspire.Dashboard.Tests/LoggingHelpersTests.cs index f26d9fcbd47..9efc2c4bbd0 100644 --- a/tests/Aspire.Dashboard.Tests/LoggingHelpersTests.cs +++ b/tests/Aspire.Dashboard.Tests/LoggingHelpersTests.cs @@ -31,10 +31,10 @@ public void WriteDashboardSummary_WithTokenAndOtlpEndpoints_LogsSummaryAndStruct Assert.Collection(lines, line => Assert.Equal("Aspire Dashboard", line), line => Assert.Equal(string.Empty, line), - line => Assert.Equal("Dashboard: http://localhost:18888", line), - line => Assert.Equal("Login URL: http://localhost:18888/login?t=abc123", line), - line => Assert.Equal("OTLP/gRPC: http://localhost:18889", line), - line => Assert.Equal("OTLP/HTTP: http://localhost:18890", line), + line => Assert.Equal(" - Dashboard: http://localhost:18888", line), + line => Assert.Equal(" - Login URL: http://localhost:18888/login?t=abc123", line), + line => Assert.Equal(" - OTLP/gRPC: http://localhost:18889", line), + line => Assert.Equal(" - OTLP/HTTP: http://localhost:18890", line), line => Assert.Equal(string.Empty, line)); Assert.Equal("http://localhost:18888", LogTestHelpers.GetValue(write, "DashboardUrl")); @@ -64,9 +64,9 @@ public void WriteDashboardSummary_WithoutToken_DoesNotIncludeLoginUrl() Assert.Collection(lines, line => Assert.Equal("Aspire Dashboard", line), line => Assert.Equal(string.Empty, line), - line => Assert.Equal("Dashboard: http://localhost:18888", line), - line => Assert.Equal("OTLP/gRPC: http://localhost:18889", line), - line => Assert.Equal("OTLP/HTTP: http://localhost:18890", line), + line => Assert.Equal(" - Dashboard: http://localhost:18888", line), + line => Assert.Equal(" - OTLP/gRPC: http://localhost:18889", line), + line => Assert.Equal(" - OTLP/HTTP: http://localhost:18890", line), line => Assert.Equal(string.Empty, line)); Assert.Null(LogTestHelpers.GetValue(write, "LoginUrl")); @@ -88,8 +88,8 @@ public void WriteDashboardSummary_InvalidDashboardUrl_LogsOtlpEndpoints() Assert.Collection(lines, line => Assert.Equal("Aspire Dashboard", line), line => Assert.Equal(string.Empty, line), - line => Assert.Equal("OTLP/gRPC: http://localhost:18889", line), - line => Assert.Equal("OTLP/HTTP: http://localhost:18890", line), + line => Assert.Equal(" - OTLP/gRPC: http://localhost:18889", line), + line => Assert.Equal(" - OTLP/HTTP: http://localhost:18890", line), line => Assert.Equal(string.Empty, line)); } @@ -114,8 +114,8 @@ public void WriteDashboardSummary_NullDashboardUrl_LogsOtlpEndpoints() Assert.Collection(lines, line => Assert.Equal("Aspire Dashboard", line), line => Assert.Equal(string.Empty, line), - line => Assert.Equal("OTLP/gRPC: http://localhost:18889", line), - line => Assert.Equal("OTLP/HTTP: http://localhost:18890", line), + line => Assert.Equal(" - OTLP/gRPC: http://localhost:18889", line), + line => Assert.Equal(" - OTLP/HTTP: http://localhost:18890", line), line => Assert.Equal(string.Empty, line)); Assert.Null(LogTestHelpers.GetValue(write, "DashboardUrl")); @@ -176,8 +176,8 @@ public void WriteDashboardSummary_WithoutOtlpEndpoints_DoesNotIncludeOtlpLines() Assert.Collection(lines, line => Assert.Equal("Aspire Dashboard", line), line => Assert.Equal(string.Empty, line), - line => Assert.Equal("Dashboard: http://localhost:18888", line), - line => Assert.Equal("Login URL: http://localhost:18888/login?t=abc123", line), + line => Assert.Equal(" - Dashboard: http://localhost:18888", line), + line => Assert.Equal(" - Login URL: http://localhost:18888/login?t=abc123", line), line => Assert.Equal(string.Empty, line)); Assert.Null(LogTestHelpers.GetValue(write, "OtlpGrpcUrl")); @@ -198,11 +198,9 @@ public void WriteDashboardSummary_IsContainer_IncludesContainerMessage() token: "abc123", isContainer: true); - var write = Assert.Single(sink.Writes); - Assert.NotNull(write.Message); - var containerMessage = "URLs may need changes depending on how network access to the container is configured."; - - Assert.Contains(containerMessage, write.Message); + Assert.Equal(2, sink.Writes.Count); + var containerWrite = sink.Writes.Skip(1).First(); + Assert.Equal("Dashboard is running in a container. Access the dashboard from the host using port forwarding.", containerWrite.Message); } private static string[] GetMessageLines(string message) From efa23894777088db0fb35671d2aff19db3cbf106 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 28 May 2026 12:23:37 +0000 Subject: [PATCH 2/2] Update FrontendBrowserTokenAuthTests to assert new standalone container log message Co-authored-by: JamesNK <303201+JamesNK@users.noreply.github.com> --- .../Integration/FrontendBrowserTokenAuthTests.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/Aspire.Dashboard.Tests/Integration/FrontendBrowserTokenAuthTests.cs b/tests/Aspire.Dashboard.Tests/Integration/FrontendBrowserTokenAuthTests.cs index 89a9a7b2697..140c74c467f 100644 --- a/tests/Aspire.Dashboard.Tests/Integration/FrontendBrowserTokenAuthTests.cs +++ b/tests/Aspire.Dashboard.Tests/Integration/FrontendBrowserTokenAuthTests.cs @@ -464,9 +464,8 @@ public async Task LogOutput_InContainer_LoginLinkContainerMessage() // Assert var l = testSink.Writes.Where(w => w.LoggerName == typeof(DashboardWebApplication).FullName).ToList(); - // The container message is now part of the summary log message. - var summaryLog = l.Single(w => ((string?)LogTestHelpers.GetValue(w, "{OriginalFormat}"))?.StartsWith("Aspire Dashboard") == true); - var containerMessage = "URLs may need changes depending on how network access to the container is configured."; - Assert.Contains(containerMessage, summaryLog.Message); + // The container message is a separate log entry from the summary. + var containerLog = l.Single(w => w.Message == "Dashboard is running in a container. Access the dashboard from the host using port forwarding."); + Assert.NotNull(containerLog); } }