Skip to content

Prevent duplicate logs with aspire --watch#14601

Closed
sebastienros wants to merge 2 commits intorelease/13.2from
sebros/watchspam
Closed

Prevent duplicate logs with aspire --watch#14601
sebastienros wants to merge 2 commits intorelease/13.2from
sebros/watchspam

Conversation

@sebastienros
Copy link
Copy Markdown
Contributor

Fixes #14405

New output:

[pg] Running (Healthy) - tcp://localhost:49728
[nodeservice] FailedToStart
[db1] Running (Healthy)
[pythonservice-installer] Finished
[db1-mcp] Running (Healthy) - http://localhost:49725
[pythonservice] Running (Healthy) - https://localhost:49729
[nodeservice-installer] Finished
[javaservice] Running (Healthy) - http://localhost:49727
[dotnet] Running (Healthy) - http://localhost:5180
[mvn-clean] Finished
[pg] Stopping - tcp://localhost:49728
[db1] Stopping
[pg] Stopping
[pg] Exited
[db1] Exited

Copilot AI review requested due to automatic review settings February 20, 2026 22:51
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 20, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 14601

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 14601"

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes issue #14405 where aspire resources --watch was spamming duplicate output when resource states remained unchanged. The fix introduces deduplication logic that compares the formatted output string for each resource and suppresses consecutive identical outputs.

Changes:

  • Adds a lastDisplayedOutput dictionary to track the last output string displayed for each resource
  • Refactors DisplayResourceUpdate from an instance method to a static FormatResourceUpdate method that returns a string instead of directly outputting it
  • Implements string comparison-based deduplication logic that works for both JSON and human-readable output formats

@davidfowl
Copy link
Copy Markdown
Contributor

Is this output usable you think or should we improve it as well? Maybe docker events is a reasonable thing to compare against

var allResources = new Dictionary<string, ResourceSnapshot>(StringComparer.OrdinalIgnoreCase);

// Track last displayed output per resource to suppress duplicates
var lastDisplayedOutput = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, why OrdinalIgnoreCase? If the whole point is to de-dupe identical strings, shouldn't this just be Ordinal? Same goes for the actual deduping happening below in line 219

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more minor thing ( no need to address here but worth thinking about), but looks like both this dictionary and the one above currently grow unbounded. I know you can only have a limited number of resources in an aspire app, but curious if you think it would be relevant to handle this case to avoid potential memory pressure.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially compared with == but was I preferred to be explicit about the comparison, and then also decided to use OrdinalIgnoreCase because this is the default comparer used for resource names. Actually, if the file is available I should use the existing constant.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should care about memory pressure. It would only be the case if new dynamic resources kept being created, which would probably be an issue in another component.

@JamesNK
Copy link
Copy Markdown
Member

JamesNK commented Feb 23, 2026

Why does the backchannel API send duplicates? Wouldn't it be better to filter them at the source rather than all consumers of the API haven't to track and filter duplicates.

@davidfowl
Copy link
Copy Markdown
Contributor

I don't know that they are dupes, I think there are properties changing that are not displayed and as a result, we end up displaying what looks like a dupe.

@github-actions
Copy link
Copy Markdown
Contributor

🎬 CLI E2E Test Recordings

The following terminal recordings are available for commit 4e5416c:

Test Recording
AddPackageInteractiveWhileAppHostRunningDetached ▶️ View Recording
AddPackageWhileAppHostRunningDetached ▶️ View Recording
AgentCommands_AllHelpOutputs_AreCorrect ▶️ View Recording
AgentInitCommand_MigratesDeprecatedConfig ▶️ View Recording
AspireUpdateRemovesAppHostPackageVersionFromDirectoryPackagesProps ▶️ View Recording
Banner_DisplayedOnFirstRun ▶️ View Recording
Banner_DisplayedWithExplicitFlag ▶️ View Recording
CreateAndDeployToDockerCompose ▶️ View Recording
CreateAndDeployToDockerComposeInteractive ▶️ View Recording
CreateAndPublishToKubernetes ▶️ View Recording
CreateAndRunAspireStarterProject ▶️ View Recording
CreateAndRunAspireStarterProjectWithBundle ▶️ View Recording
CreateAndRunJsReactProject ▶️ View Recording
CreateAndRunPythonReactProject ▶️ View Recording
CreateEmptyAppHostProject ▶️ View Recording
CreateStartAndStopAspireProject ▶️ View Recording
CreateStartWaitAndStopAspireProject ▶️ View Recording
CreateTypeScriptAppHostWithViteApp ▶️ View Recording
DoctorCommand_DetectsDeprecatedAgentConfig ▶️ View Recording
DoctorCommand_WithSslCertDir_ShowsTrusted ▶️ View Recording
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted ▶️ View Recording
LogsCommandShowsResourceLogs ▶️ View Recording
PsCommandListsRunningAppHost ▶️ View Recording
ResourcesCommandShowsRunningResources ▶️ View Recording
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels ▶️ View Recording
StopAllAppHostsFromAppHostDirectory ❌ Upload failed
StopAllAppHostsFromUnrelatedDirectory ▶️ View Recording
StopNonInteractiveMultipleAppHostsShowsError ▶️ View Recording
StopNonInteractiveSingleAppHost ▶️ View Recording
StopWithNoRunningAppHostExitsSuccessfully ❌ Upload failed

📹 Recordings uploaded automatically from CI run #22318614147

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants