Skip to content

Log guest app host output to CLI log file and add OutputLineStream/ConsoleLogTypes#15307

Merged
JamesNK merged 4 commits intorelease/13.2from
jamesnk/revert-apphost-output
Mar 17, 2026
Merged

Log guest app host output to CLI log file and add OutputLineStream/ConsoleLogTypes#15307
JamesNK merged 4 commits intorelease/13.2from
jamesnk/revert-apphost-output

Conversation

@JamesNK
Copy link
Member

@JamesNK JamesNK commented Mar 17, 2026

Description

Log guest (non-.NET) app host console output to the CLI log file, matching the behavior already in place for .NET app hosts. Previously, guest process stdout/stderr was only buffered in memory and never written to disk.

Changes

  • File logging for guest app hosts: Pass FileLoggerProvider through GuestAppHostProjectGuestRuntimeProcessGuestLauncherOutputCollector so guest process output is written to the CLI log file
  • OutputLineStream enum: Replace stringly-typed "stdout"/"stderr" stream identifiers with a type-safe enum across OutputCollector, IInteractionService, and all implementations
  • ConsoleLogTypes constants: Replace string literals ("waiting", "running", "exitCode", "failedToStart") with named constants for console log semantic types
  • Stream drain on exit: Add TaskCompletionSource-based stream drain with 5-second timeout in ProcessGuestLauncher to ensure no trailing output lines are lost after process exit
  • Test coverage: Add test verifying guest process output is written to the log file

Log file output after change.

Here is an app host (note, console.log):

// Aspire TypeScript AppHost
// For more information, see: https://aspire.dev

import { createBuilder } from './.modules/aspire.js';

const builder = await createBuilder();

// Add your resources here, for example:
// const redis = await builder.addContainer("cache", "redis:latest");
// const postgres = await builder.addPostgres("db");

console.log('Hello world');

await builder.build().run();

Log file (note hello world in output):

[2026-03-17 05:08:21.768] [INFO] [Program] Version: 13.2.0-dev
[2026-03-17 05:08:21.769] [INFO] [Program] Build ID: 42.42.42.42424
[2026-03-17 05:08:21.769] [INFO] [Program] Working directory: C:\Development\Temp\cli-ts\cli-ts
[2026-03-17 05:08:22.308] [INFO] [Program] Command: aspire run
[2026-03-17 05:08:22.342] [INFO] [ProjectLocator] Found AppHost path 'apphost.ts' from config file in C:\Development\Temp\cli-ts\cli-ts
[2026-03-17 05:08:22.525] [INFO] [ConfigurationService] Found settings file at C:\Development\Temp\cli-ts\cli-ts\aspire.config.json
[2026-03-17 05:08:22.526] [INFO] [GuestAppHostProject] Loaded config from C:\Development\Temp\cli-ts\cli-ts (file exists: True)
[2026-03-17 05:08:51.398] [INFO] [ConfigurationService] Found settings file at C:\Development\Temp\cli-ts\cli-ts\aspire.config.json
[2026-03-17 05:08:51.407] [INFO] [ConfigurationService] Found settings file at C:\Development\Temp\cli-ts\cli-ts\aspire.config.json
[2026-03-17 05:08:54.550] [INFO] [AppHost] 
[2026-03-17 05:08:54.550] [INFO] [AppHost] up to date, audited 38 packages in 1s
[2026-03-17 05:08:54.551] [INFO] [AppHost] 
[2026-03-17 05:08:54.551] [INFO] [AppHost] 7 packages are looking for funding
[2026-03-17 05:08:54.551] [INFO] [AppHost]   run `npm fund` for details
[2026-03-17 05:08:54.551] [INFO] [AppHost] 
[2026-03-17 05:08:54.551] [INFO] [AppHost] found 0 vulnerabilities
[2026-03-17 05:08:54.662] [INFO] [GuestAppHostProject] Generated 3 TypeScript files in C:\Development\Temp\cli-ts\cli-ts\.modules
[2026-03-17 05:08:56.818] [INFO] [AppHost] Hello world
[2026-03-17 05:08:57.118] [INFO] [AppHost/DistributedApplication] Aspire version: 13.2.0-dev
[2026-03-17 05:08:57.119] [INFO] [AppHost/DistributedApplication] Distributed application starting.
[2026-03-17 05:08:57.119] [INFO] [AppHost/DistributedApplication] Application host directory is: C:\Development\Temp\cli-ts\cli-ts
[2026-03-17 05:08:58.934] [INFO] [AppHost/DistributedApplication] Distributed application started. Press Ctrl+C to shut down.
[2026-03-17 05:08:59.113] [INFO] [AppHost/DistributedApplication] Now listening on: https://localhost:53089
[2026-03-17 05:08:59.113] [INFO] [AppHost/DistributedApplication] Login to the dashboard at https://localhost:53089/login?t=09d14758d8059c244ed7eec74e1fc9bf

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
    • No
  • Does the change require an update in our Aspire docs?
    • Yes
    • No

@JamesNK JamesNK requested a review from radical as a code owner March 17, 2026 04:27
@JamesNK JamesNK requested a review from eerhardt as a code owner March 17, 2026 04:27
Copilot AI review requested due to automatic review settings March 17, 2026 04:27
@github-actions
Copy link
Contributor

github-actions bot commented Mar 17, 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 -- 15307

Or

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

Copy link
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

Reverts the prior change that forwarded AppHost stdout/stderr to the aspire run console in non-detached runs, removing the associated “live output” plumbing and the tests that validated that behavior.

Changes:

  • Removed OutputCollector live-callback support and stopped wiring AppHost/guest process output to console logs during runs.
  • Simplified guest process launching by removing live forwarding and related completion tracking.
  • Removed/updated unit and E2E tests that asserted AppHost console-output forwarding.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/Shared/Hex1bAutomatorTestHelpers.cs Reverts interactive “Empty AppHost” selection flow in Hex1b automations.
tests/Aspire.Cli.Tests/Utils/OutputCollectorTests.cs Removes test validating live output callback forwarding.
tests/Aspire.Cli.Tests/Projects/ProcessGuestLauncherTests.cs Deletes tests asserting guest launcher forwards stdout live.
tests/Aspire.Cli.Tests/Commands/RunCommandTests.cs Removes test asserting aspire run forwards AppHost stdout to console.
tests/Aspire.Cli.EndToEnd.Tests/AppHostConsoleLogTests.cs Deletes E2E coverage for visible AppHost console output during non-detached runs.
src/Aspire.Cli/Utils/OutputCollector.cs Removes live callback API; collector becomes buffered + optional file logger only.
src/Aspire.Cli/Projects/ProcessGuestLauncher.cs Stops accepting live callback and removes post-exit stream completion waiting.
src/Aspire.Cli/Projects/GuestRuntime.cs Removes live-callback parameter from default launcher creation.
src/Aspire.Cli/Projects/GuestAppHostProject.cs Stops wiring guest output to console live; always displays buffered output on failure.
src/Aspire.Cli/Projects/DotNetAppHostProject.cs Stops wiring AppHost run output to console live; keeps file logging/buffering only.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 17, 2026

🎬 CLI E2E Test Recordings

The following terminal recordings are available for commit 725c7d4:

Test Recording
AddPackageInteractiveWhileAppHostRunningDetached ▶️ View Recording
AddPackageWhileAppHostRunningDetached ▶️ View Recording
AgentCommands_AllHelpOutputs_AreCorrect ▶️ View Recording
AgentInitCommand_DefaultSelection_InstallsSkillOnly ▶️ View Recording
AgentInitCommand_MigratesDeprecatedConfig ▶️ View Recording
AspireAddPackageVersionToDirectoryPackagesProps ▶️ View Recording
AspireUpdateRemovesAppHostPackageVersionFromDirectoryPackagesProps ▶️ View Recording
Banner_DisplayedOnFirstRun ▶️ View Recording
Banner_DisplayedWithExplicitFlag ▶️ View Recording
CertificatesClean_RemovesCertificates ▶️ View Recording
CertificatesTrust_WithNoCert_CreatesAndTrustsCertificate ▶️ View Recording
CertificatesTrust_WithUntrustedCert_TrustsCertificate ▶️ View Recording
ConfigSetGet_CreatesNestedJsonFormat ▶️ View Recording
CreateAndDeployToDockerCompose ▶️ View Recording
CreateAndDeployToDockerComposeInteractive ▶️ View Recording
CreateAndPublishToKubernetes ▶️ View Recording
CreateAndRunAspireStarterProject ▶️ View Recording
CreateAndRunAspireStarterProjectWithBundle ▶️ View Recording
CreateAndRunJsReactProject ▶️ View Recording
CreateAndRunPythonReactProject ▶️ View Recording
CreateAndRunTypeScriptStarterProject ▶️ View Recording
CreateEmptyAppHostProject ▶️ View Recording
CreateStartAndStopAspireProject ▶️ View Recording
CreateTypeScriptAppHostWithViteApp ▶️ View Recording
DescribeCommandResolvesReplicaNames ▶️ View Recording
DescribeCommandShowsRunningResources ▶️ View Recording
DetachFormatJsonProducesValidJson ▶️ View Recording
DoctorCommand_DetectsDeprecatedAgentConfig ▶️ View Recording
DoctorCommand_WithSslCertDir_ShowsTrusted ▶️ View Recording
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted ▶️ View Recording
GlobalMigration_HandlesCommentsAndTrailingCommas ▶️ View Recording
GlobalMigration_HandlesMalformedLegacyJson ▶️ View Recording
GlobalMigration_PreservesAllValueTypes ▶️ View Recording
GlobalMigration_SkipsWhenNewConfigExists ▶️ View Recording
GlobalSettings_MigratedFromLegacyFormat ▶️ View Recording
InvalidAppHostPathWithComments_IsHealedOnRun ▶️ View Recording
LogsCommandShowsResourceLogs ▶️ View Recording
PsCommandListsRunningAppHost ▶️ View Recording
PsFormatJsonOutputsOnlyJsonToStdout ▶️ View Recording
PublishWithDockerComposeServiceCallbackSucceeds ❌ Upload failed
RestoreGeneratesSdkFiles ❌ Upload failed
RunWithMissingAwaitShowsHelpfulError ❌ Upload failed
SecretCrudOnDotNetAppHost ❌ Upload failed
SecretCrudOnTypeScriptAppHost ▶️ View Recording
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels ▶️ View Recording
StopAllAppHostsFromAppHostDirectory ▶️ View Recording
StopAllAppHostsFromUnrelatedDirectory ❌ Upload failed
StopNonInteractiveMultipleAppHostsShowsError ▶️ View Recording
StopNonInteractiveSingleAppHost ▶️ View Recording
StopWithNoRunningAppHostExitsSuccessfully ❌ Upload failed
TypeScriptAppHostWithProjectReferenceIntegration ▶️ View Recording

📹 Recordings uploaded automatically from CI run #23180590987

- Pass FileLoggerProvider through GuestAppHostProject -> GuestRuntime -> ProcessGuestLauncher -> OutputCollector so guest process stdout/stderr is written to the CLI log file (matching .NET app host behavior)
- Add OutputLineStream enum to replace stringly-typed stdout/stderr stream identifiers
- Add ConsoleLogTypes constants for console log semantic types
- Add TaskCompletionSource-based stream drain with 5s timeout in ProcessGuestLauncher to ensure no trailing output lines are lost
- Add test verifying guest process output is written to log file
@JamesNK JamesNK changed the title Revert "Show apphost stdout in non-detached runs (#15225)" Log guest app host output to CLI log file and add OutputLineStream/ConsoleLogTypes Mar 17, 2026
@JamesNK JamesNK requested a review from mitchdenny March 17, 2026 05:07
@JamesNK
Copy link
Member Author

JamesNK commented Mar 17, 2026

Merged improvements in #15298 into this PR.

@mitchdenny
Copy link
Member

/deployment-test

@github-actions
Copy link
Contributor

🚀 Deployment tests starting on PR #15307...

This will deploy to real Azure infrastructure. Results will be posted here when complete.

View workflow run

Copy link
Member

@mitchdenny mitchdenny left a comment

Choose a reason for hiding this comment

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

Approved. Looks good but just triggering a deployment test as well.

@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot had a problem deploying to deployment-testing March 17, 2026 06:17 Failure
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot had a problem deploying to deployment-testing March 17, 2026 06:17 Failure
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing March 17, 2026 06:17 Inactive
@JamesNK JamesNK merged commit 57240b2 into release/13.2 Mar 17, 2026
285 of 287 checks passed
@JamesNK JamesNK deleted the jamesnk/revert-apphost-output branch March 17, 2026 06:51
@github-actions
Copy link
Contributor

Deployment E2E Tests failed — 25 passed, 2 failed, 0 cancelled

View test results and recordings

View workflow run

Test Result Recording
Deployment.EndToEnd-AcaCompactNamingDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-VnetSqlServerInfraDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-VnetSqlServerConnectivityDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-AzureEventHubsDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-VnetKeyVaultConnectivityDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-AppServicePythonDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-AzureServiceBusDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-AzureLogAnalyticsDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-AzureStorageDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-AuthenticationTests ✅ Passed
Deployment.EndToEnd-VnetKeyVaultInfraDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-AksStarterWithRedisDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-AzureAppConfigDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-AcaExistingRegistryDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-AzureKeyVaultDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-PythonFastApiDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-AcaCustomRegistryDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-AppServiceReactDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-AcaStarterDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-AcaDeploymentErrorOutputTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-VnetStorageBlobConnectivityDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-AcrPurgeTaskDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-AzureContainerRegistryDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-VnetStorageBlobInfraDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-AksStarterDeploymentTests ✅ Passed ▶️ View Recording
Deployment.EndToEnd-TypeScriptExpressDeploymentTests ❌ Failed ▶️ View Recording
Deployment.EndToEnd-AcaCompactNamingUpgradeDeploymentTests ❌ Failed ▶️ View Recording

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants