Skip to content

Log ConsoleInteractionService output to CLI log file#15521

Merged
JamesNK merged 7 commits intomainfrom
jamesnk/cli-interaction-logging
Mar 25, 2026
Merged

Log ConsoleInteractionService output to CLI log file#15521
JamesNK merged 7 commits intomainfrom
jamesnk/cli-interaction-logging

Conversation

@JamesNK
Copy link
Member

@JamesNK JamesNK commented Mar 24, 2026

Description

Log ConsoleInteractionService output to the CLI log file so that console interactions (status messages, text output, prompts, selections, errors, etc.) are captured in the diagnostic log at ~/.aspire/logs/.

Two ILogger categories are used to distinguish stdout vs stderr output:

  • Aspire.Cli.Console.Stdout - messages routed to stdout
  • Aspire.Cli.Console.Stderr - messages routed to stderr

All messages are logged at Information level. Since the FileLoggerProvider is always active, these appear automatically in CLI log files.

Changes

  • ConsoleInteractionService: Accept ILoggerFactory in constructor, create two loggers with stdout/stderr categories, log key interactions (status, prompts, selections, confirmations, errors, display messages, console logs, output lines)
  • Program.cs: Resolve ILoggerFactory from DI and pass to ConsoleInteractionService in both extension and non-extension code paths
  • Tests: Updated CliTestHelper.cs and ConsoleInteractionServiceTests.cs to pass NullLoggerFactory.Instance

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

Copilot AI review requested due to automatic review settings March 24, 2026 08:03
@github-actions
Copy link
Contributor

github-actions bot commented Mar 24, 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/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 15521

Or

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

@JamesNK
Copy link
Member Author

JamesNK commented Mar 24, 2026

Here is example CLI usage:

image

Logs before:

[2026-03-24 08:05:43.070] [INFO] [Program] Version: 13.2.0+1b339b0aab41b049e8e0d21ed1a79596cf8b8509
[2026-03-24 08:05:43.070] [INFO] [Program] Build ID: 13.200.26.17003
[2026-03-24 08:05:43.070] [INFO] [Program] Working directory: C:\Development\Temp\cli-ts
[2026-03-24 08:05:43.201] [INFO] [Program] Command: aspire new
[2026-03-24 08:06:13.703] [INFO] [Program] Exit code: 0

Logs after:

[2026-03-24 07:56:29.939] [INFO] [Program] Version: 13.3.0-dev
[2026-03-24 07:56:29.940] [INFO] [Program] Build ID: 42.42.42.42424
[2026-03-24 07:56:29.940] [INFO] [Program] Working directory: C:\Development\Temp\cli-ts
[2026-03-24 07:56:30.513] [INFO] [Program] Command: aspire new
[2026-03-24 07:56:30.718] [INFO] [Stdout] Selection prompt: Select a template:
[2026-03-24 07:56:38.742] [INFO] [Stdout] Selection result: Starter App (ASP.NET Core/Blazor)
[2026-03-24 07:56:38.743] [INFO] [Stdout] Select a template: Starter App (ASP.NET Core/Blazor)
[2026-03-24 07:56:38.789] [INFO] [Stdout] Prompt: Enter the project name (default: cli-ts, secret: False)
[2026-03-24 07:56:39.522] [INFO] [Stdout] Prompt result: cli-ts
[2026-03-24 07:56:39.523] [INFO] [Stdout] Prompt: Enter the output path (default: ./cli-ts, secret: False)
[2026-03-24 07:56:39.952] [INFO] [Stdout] Prompt result: ./cli-ts
[2026-03-24 07:56:39.958] [INFO] [Stdout] Status: Searching for available project template versions...
[2026-03-24 07:56:39.990] [INFO] [Stdout] Selection prompt: Use *.dev.localhost URLs
[2026-03-24 07:56:40.907] [INFO] [Stdout] Selection result: No
[2026-03-24 07:56:40.908] [INFO] [Stdout] Selection prompt: Use Redis Cache
[2026-03-24 07:56:41.625] [INFO] [Stdout] Selection result: Yes
[2026-03-24 07:56:41.625] [INFO] [Stdout] Using Redis Cache for caching.
[2026-03-24 07:56:41.629] [INFO] [Stdout] Selection prompt: Do you want to create a test project?
[2026-03-24 07:56:43.330] [INFO] [Stdout] Selection result: No
[2026-03-24 07:56:43.334] [INFO] [Stdout] Status: Getting templates...
[2026-03-24 07:56:49.682] [INFO] [Stdout] Using project templates version: 13.3.0-preview.1.26173.7
[2026-03-24 07:56:49.683] [INFO] [Stdout] Status: Creating new Aspire project...
[2026-03-24 07:57:17.380] [INFO] [Stdout] Status: Checking certificates...
[2026-03-24 07:57:18.545] [INFO] [Stdout] Created or updated NuGet.config in the project directory with required package sources.
[2026-03-24 07:57:18.545] [INFO] [Stdout] Success: Project created successfully in C:\Development\Temp\cli-ts\cli-ts.
[2026-03-24 07:57:18.545] [INFO] [Stdout] Project created successfully in C:\Development\Temp\cli-ts\cli-ts.
[2026-03-24 07:57:18.547] [INFO] [Stdout] Confirm: Would you like to configure AI agent environments for this project? (default: True)
[2026-03-24 07:57:21.299] [INFO] [Stdout] Confirm result: True
[2026-03-24 07:57:21.302] [INFO] [Stdout] Status: Detecting agent environments...
[2026-03-24 07:57:26.306] [INFO] [Stdout] Selection prompt: What would you like to configure? [dim](Enter to skip, Ctrl+C to cancel)[/]
[2026-03-24 07:57:59.389] [INFO] [Stdout] Selection results: Install Aspire skill file (Recommended)
[2026-03-24 07:57:59.393] [INFO] [Stdout] Create Aspire skill file (.github/skills/aspire/SKILL.md)
[2026-03-24 07:57:59.395] [INFO] [Stdout] Create Aspire skill file (.opencode/skill/aspire/SKILL.md)
[2026-03-24 07:57:59.397] [INFO] [Stdout] Create Aspire skill file (.claude/skills/aspire/SKILL.md)
[2026-03-24 07:57:59.397] [INFO] [Stdout] Success: Agent environment configuration complete.
[2026-03-24 07:57:59.397] [INFO] [Stdout] Agent environment configuration complete.
[2026-03-24 07:57:59.402] [INFO] [Program] Exit code: 0

A lot more information is available. But are there security concerns about recording output in a log file?

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

Adds diagnostic logging for ConsoleInteractionService so interactive CLI output (prompts, status, messages, etc.) is captured in the CLI log files under ~/.aspire/logs/, using separate logger categories for stdout vs stderr.

Changes:

  • Inject ILoggerFactory into ConsoleInteractionService and log key interaction events/messages.
  • Update CLI DI wiring in Program.cs to pass ILoggerFactory when constructing interaction services (extension + non-extension paths).
  • Update tests/helpers to provide a logger factory (NullLoggerFactory.Instance) where needed.

Reviewed changes

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

File Description
src/Aspire.Cli/Interaction/ConsoleInteractionService.cs Introduces stdout/stderr loggers and logs interaction output/events.
src/Aspire.Cli/Program.cs Passes ILoggerFactory into ConsoleInteractionService from DI.
tests/Aspire.Cli.Tests/Utils/CliTestHelper.cs Updates test DI factory to provide ILoggerFactory to interaction service.
tests/Aspire.Cli.Tests/Interaction/ConsoleInteractionServiceTests.cs Updates tests to construct interaction service with NullLoggerFactory.Instance.

@mitchdenny
Copy link
Member

I'm not too concerned about security here, its a local log file and its not like we are writing secrets or anything. The place to not log secrets is where you log the secret.

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.

I like the extra logging detail.

@JamesNK JamesNK force-pushed the jamesnk/cli-interaction-logging branch from 5fb63be to 399d42e Compare March 25, 2026 03:03
@github-actions
Copy link
Contributor

🎬 CLI E2E Test Recordings — 49 recordings uploaded (commit a1c87a0)

View recordings
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
CreateAndRunAspireStarterProject ▶️ View Recording
CreateAndRunAspireStarterProjectWithBundle ▶️ View Recording
CreateAndRunEmptyAppHostProject ▶️ View Recording
CreateAndRunJsReactProject ▶️ View Recording
CreateAndRunPythonReactProject ▶️ View Recording
CreateAndRunTypeScriptEmptyAppHostProject ▶️ View Recording
CreateAndRunTypeScriptStarterProject ▶️ 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 ▶️ View Recording
RestoreGeneratesSdkFiles ▶️ View Recording
RunWithMissingAwaitShowsHelpfulError ▶️ View Recording
SecretCrudOnDotNetAppHost ▶️ View Recording
SecretCrudOnTypeScriptAppHost ▶️ View Recording
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels ▶️ View Recording
StopAllAppHostsFromAppHostDirectory ▶️ View Recording
StopAllAppHostsFromUnrelatedDirectory ▶️ View Recording
StopNonInteractiveMultipleAppHostsShowsError ▶️ View Recording
StopNonInteractiveSingleAppHost ▶️ View Recording
StopWithNoRunningAppHostExitsSuccessfully ▶️ View Recording
TypeScriptAppHostWithProjectReferenceIntegration ▶️ View Recording

📹 Recordings uploaded automatically from CI run #23527001476

@JamesNK JamesNK merged commit 1d9629e into main Mar 25, 2026
493 of 496 checks passed
@JamesNK JamesNK deleted the jamesnk/cli-interaction-logging branch March 25, 2026 06:29
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.

4 participants