Improve aspire start readiness diagnostics#17141
Conversation
Wait for detached AppHost startup readiness before reporting success, surface curated startup output on failure, and replay child AppHost diagnostics into the parent start log under detached categories. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 17141Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 17141" |
Avoid killing detached child AppHost processes immediately after they report startup failure so they can finish flushing their logs. Use the shared process signaling helper for timeout and cancellation cleanup, matching the graceful-then-force shutdown shape used by stop. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolve conflicts in guest process launch logging and detached child environment tests while preserving main's profiling telemetry changes and this branch's startup readiness diagnostics. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Stop rewriting detached guest command log lines to shell-style output. Display the original Executing: prefix while keeping the same relevance filtering for startup diagnostics. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Mirror the detached AppHost replay header in the footer so both boundaries identify the child process and child log file that produced the excerpt. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep the detached AppHost replay header concise and report the full child log path only on the footer boundary. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
PR testing resultsTested this PR with the dogfood CLI from PR artifacts. CLI version verification
Scenarios
Observed output shape Terminal failure output included: Parent log replay included: Caveat The default repo container runner on this machine is Linux arm64, but the selected workflow run did not yet have |
There was a problem hiding this comment.
Pull request overview
Makes aspire start wait for the detached child aspire run process to report readiness (or failure) via a JSON status file before returning, so early startup failures (e.g. TypeScript syntax errors in a polyglot AppHost) surface in the parent terminal and parent log instead of being lost. A new CliLogFormat utility centralizes the file/console log token format so the parent can parse the child's log file and replay relevant lines under DetachedAppHost/... categories.
Changes:
- New cross-process readiness handshake via
ASPIRE_CLI_START_READY_FILE(atomic-rename JSON file) used byRunCommand(child) andAppHostLauncher(parent); child waits a 2 s stability window before declaring success. - New
Aspire.Cli.Diagnostics.CliLogFormatconsolidates level/category tokens and aTryParseFileLogLineparser; callers across CLI now use the shared constants instead of literals. - On detached-start failure the parent renders a bounded, filtered tail of the child log to the terminal and replays a richer tail into the parent's file log;
ProcessSignalergains a graceful-then-force-kill helper used on timeout / cancellation.
Reviewed changes
Copilot reviewed 29 out of 30 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Aspire.Cli/Commands/AppHostLauncher.cs | Major rewrite of detached launch wait loop: reads child status file, replays/displays child log tail, force-kills on timeout/cancel; new helpers for status file IO and log-tail parsing. |
| src/Aspire.Cli/Commands/RunCommand.cs | Child side: writes DetachedStartupStatus (ready/failure/exit code), observes early exits within a 2 s window, new JSON-serializable record. |
| src/Aspire.Cli/Commands/DashboardRunCommand.cs | Uses CliLogFormat.Categories.Dashboard constant. |
| src/Aspire.Cli/Commands/TelemetryCommandHelpers.cs | Uses shared FileLevelTokens constants instead of literal strings. |
| src/Aspire.Cli/Diagnostics/CliLogFormat.cs | New shared log format helpers (tokens, categories, parser, detached-category prefix). |
| src/Aspire.Cli/Diagnostics/FileLoggerProvider.cs | Delegates level/category formatting to CliLogFormat. |
| src/Aspire.Cli/Interaction/SpectreConsoleLoggerProvider.cs | Delegates to CliLogFormat helpers. |
| src/Aspire.Cli/Interaction/ConsoleInteractionService.cs | Uses CliLogFormat.Categories.Stdout/Stderr. |
| src/Aspire.Cli/Projects/DotNetAppHostProject.cs | Replaces literal collector categories with CliLogFormat.Categories. |
| src/Aspire.Cli/Projects/ProcessGuestLauncher.cs | Uses shared Executing: prefix constant + Categories.AppHost. |
| src/Aspire.Cli/Utils/OutputCollector.cs | Default category sourced from CliLogFormat.Categories.AppHost. |
| src/Aspire.Cli/Resources/RunCommandStrings.resx + Designer + xlf×14 | Adds RecentAppHostStartupOutput localized string. |
| src/Shared/KnownConfigNames.cs | Adds ASPIRE_CLI_START_READY_FILE. |
| src/Shared/ProcessSignaler.cs | Adds RequestGracefulShutdownThenForceKillAsync with 10 s window. |
| tests/Aspire.Cli.Tests/Diagnostics/CliLogFormatTests.cs | Unit tests for the new log format parser/token mappings. |
| tests/Aspire.Cli.Tests/Commands/RunCommandTests.cs | Adds tests for status-file round-trip, child log tail/replay, and env var propagation. |
Files not reviewed (1)
- src/Aspire.Cli/Resources/RunCommandStrings.Designer.cs: Language not supported
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Add a CLI E2E test that verifies this. I think it would good to have 4 tests:
Should be able to have two core test methods. One for .NET and one for TS. Then have parameters for whether it is run vs start. Verify the experience is the same. |
|
What happens on an older apphost? |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
If the apphost backchannel supports the V2 contracts it'll poll for a command that will only succeed after the apphost has started successfully. For even older apphosts there's a short stabilization delay to make sure the child stays alive after the backchannel starts. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Re-running the failed jobs in the CI workflow for this pull request because 1 job was identified as retry-safe transient failures in the CI run attempt.
Matched test failure patterns (1 test)
|
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
❓ CLI E2E Tests unknown — 90 passed, 0 failed, 1 unknown (commit View all recordings
📹 Recordings uploaded automatically from CI run #26049821187 |
|
Verified on Mac, Windows, and Linux (via the CLI E2E tests). |
Documents the new startup readiness behavior introduced in microsoft/aspire#17141: - aspire start now waits for AppHost to reach a stable running state before detaching - Early startup failures (TypeScript/C# compile errors) are surfaced in the terminal - Curated startup excerpts filter noise and highlight relevant error messages - Ctrl+C cancels startup while waiting for readiness Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Pull request created: #1002
|
|
📝 Documentation has been drafted in microsoft/aspire.dev#1002 targeting Updated Note This draft PR needs human review before merging. |
Description
aspire startcould detach from the background AppHost process before the AppHost had actually reached a stable startup state. That made early startup failures, such as TypeScript syntax errors in a polyglot AppHost or C# compile errors in a .NET AppHost, hard to diagnose because the parent command could exit before surfacing the child output.This change makes detached startup wait for AppHost startup readiness when the AppHost supports the new auxiliary backchannel readiness RPC. The child
aspire runprocess notifies readiness only after it has passed the same early startup gate used by foregroundaspire run. On failure, the parent shows a curated, bounded startup excerpt in the terminal and replays relevant child AppHost diagnostics into the parent log underDetachedAppHost/...categories so the linked parent log is self-contained without confusing child CLI status noise.For older AppHosts that do not support the readiness RPC,
aspire startuses the V2 resource snapshot RPC as a short compatibility probe before detaching. If the snapshot probe succeeds, the parent detaches immediately; if the child exits before that probe succeeds, the parent reports the failure and shows the collected child output. AppHosts that do not support the V2 probe still use the short stability wait to preserve compatibility.Sending Ctrl+C while
aspire startis waiting for the child AppHost to start will terminate startup.User-facing output
For a TypeScript guest AppHost syntax error, foreground
aspire runremains concise:Detached
aspire startnow stays attached long enough to report the same relevant compiler output without replaying successful setup noise such asnpm install, audit/funding output, orExecuting:debug lines:For a .NET AppHost compile error, detached
aspire startincludes the recent build output, including compiler diagnostics:The parent log also includes the replayed child excerpt with explicit source separation:
Testing
dotnet test --project tests/Aspire.Cli.Tests/Aspire.Cli.Tests.csproj --no-launch-profile -- --filter-class "*.AppHostLauncherTests" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"dotnet build tests/Aspire.Cli.EndToEnd.Tests/Aspire.Cli.EndToEnd.Tests.csproj --no-restoregit diff --checkaspire runandaspire startwith TypeScript guest and .NET AppHosts containing syntax errors.Fixes #16918
Checklist
<remarks />and<code />elements on your triple slash comments?