Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Aug 30, 2025

This PR modifies the BackchannelService to support multiple Unix domain socket connections, enabling the new aspire log <resource-name> CLI command to work alongside a running aspire run session.

Problem

The original implementation only accepted a single connection to the backchannel Unix domain socket. This meant that when aspire run was active and connected, transient commands like aspire log could not establish their own connection to retrieve logs.

Solution

Modified the BackchannelService to:

  1. Accept connections in a loop: The service now continuously accepts new connections rather than stopping after the first one
  2. Handle each connection independently: Each connection gets its own JsonRpc instance running in a background task
  3. Share the same AppHostRpcTarget: Since the RPC target is stateless for most operations, multiple connections can safely use the same instance
  4. Maintain backward compatibility: The first connection still signals completion for existing aspire run behavior

Key Changes

  • BackchannelService.cs: Refactored to accept multiple connections with proper connection lifecycle management
  • Added integration test: Verifies that multiple connections can be established and both can successfully invoke RPC methods

Usage

# Terminal 1: Start the AppHost
aspire run

# Terminal 2: View logs from specific resource (now works!)
aspire log web-api --lines 50 --tail

The aspire run session remains active while aspire log connects, retrieves logs, and disconnects without disrupting the main session.

Backward Compatibility

All existing functionality remains unchanged. The socket path generation and first connection behavior are preserved, ensuring compatibility with existing aspire run workflows.

This pull request was created as a result of the following prompt from Copilot chat.

Goal
Create a new pull request that ONLY introduces a single new CLI command: aspire log <resource-name> to display (and optionally tail) logs for an individual resource in a running Aspire AppHost. This replaces the broader prior draft PR ( #11102 ) that added start/stop/log plus broader refactors. We want a focused, reviewable minimal slice that exercises the end‑to‑end backchannel without introducing start/stop yet.

Source Reference
Previous (do not reuse wholesale) draft PR: #11102. Use it only as guidance to extract the smallest set of changes necessary to support aspire log.

Requirements

  1. New CLI command syntax

    • aspire log <resource-name>
    • Options:
      • --lines|-n <int>: number of previous lines to show (default 100)
      • --tail|-f: follow / stream new log lines until Ctrl+C
      • --project|-p <AppHostProjectPath>: optional explicit AppHost project (mirrors existing run command options)
    • Help text localized consistent with existing commands.
  2. Backchannel RPC

    • Add ONE new method to the backchannel interface for retrieving logs, e.g. GetResourceLogEntriesAsync(string resourceName, int lineCount, bool follow, CancellationToken). Name can follow existing conventions.
    • Server side (AppHost): Implement handler that streams existing buffered log lines (limited by lineCount) then (if follow=true) continues to push appended lines until client disconnect or cancellation.
    • Keep the protocol additive & backward compatible (do not break existing run scenario). Avoid adding start/stop methods.
  3. Deterministic connection (ONLY if required)

    • If the existing main branch already has a stable way for transient commands to discover the backchannel, use it. Otherwise, introduce a minimal deterministic socket / named pipe path derivation based on the AppHost project path hash (as in PR Add CLI commands for individual Aspire resource control with reliable backchannel connections #11102) BUT scope it narrowly to what aspire log needs.
    • MUST include proper cleanup on AppHost shutdown and stale socket detection (attempt connection; remove if unreachable) to avoid orphaned files causing false positives.
  4. Multiple (sequential) transient clients

    • Ensure the AppHost can accept a transient connection for the log command after the primary aspire run connection is established. If the current implementation only allows a single connection, minimally adjust it so that a secondary (short‑lived) client can connect for log streaming without tearing down the host.
    • Do NOT implement generalized multi‑client orchestration beyond what is needed for a single extra log streaming session.
  5. Logging source

    • Reuse existing logging infrastructure in the AppHost. If there is already an in‑memory buffer or subscription mechanism, tap into it. If not, implement a ring buffer (size ~ a few hundred / a config constant) for recent log lines for each resource. Simplicity > configurability for this first slice.
    • Each log entry transmitted should at minimum include: timestamp (UTC), level, resource name, message text. Additional fields (exception, category) are optional.
  6. Output formatting in CLI

    • Format: [HH:mm:ss.fff] [Level] [resource] Message (e.g. [12:34:56.789] [Information] [web-api] Started HTTP server on :8080)
    • Colorization: align with existing Aspire CLI conventions (if any). If none easily available, skip color to stay minimal.
  7. Tail behavior

    • When --tail is specified, keep the process running and stream lines as they arrive. Handle Ctrl+C (SIGINT) to exit gracefully.
    • Make sure cancellation propagates to the backchannel so server stops sending lines.
  8. Tests

    • Unit / integration tests for:
      • Help output (includes options)
      • Invalid arguments (missing resource name, negative line count)
      • Basic fetch of last N lines
      • Tail mode yields additional lines after initial batch (can simulate by writing lines after subscription)
    • Keep test surface focused solely on log command.
  9. Documentation / Discoverability

    • Update any CLI command listing / README / help aggregator to include log.
    • Add XML doc comments where appropriate.
  10. Exclusions / Out of Scope

  • Do NOT include start/stop resource control commands.
  • Do NOT over‑engineer multi‑client management.
  • Do NOT introduce unrelated refactors from the prior broader PR.

Implementation Guidance

  • Favor smallest diff: isolate new files where possible instead of large edits. If a large existing file must change, keep changes surgical.
  • Backchannel contract versioning: if there is an enum or version number, increment minimally or add a capability flag.
  • Consider cancellation tokens for streaming.

Acceptance Criteria

  • aspire run works unchanged.
  • While AppHost is running, aspire log <resource> returns last 100 lines.
  • aspire log <resource> -n 10 -f shows last 10 lines then streams new ones until interrupted.
  • No start/stop commands exist in the CLI.
  • CI tests for new command pass.

Please open a new branch from main (e.g. feature/aspire-log-command) and create the PR with the above scope.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@Copilot Copilot AI changed the title [WIP] Add minimal 'aspire log' CLI command for viewing resource logs Add aspire log <resource-name> CLI command for resource log streaming Aug 30, 2025
@Copilot Copilot AI requested a review from davidfowl August 30, 2025 06:47
Copilot finished work on behalf of davidfowl August 30, 2025 06:47
@davidfowl
Copy link
Member

@copilot The apphost needs to support multiple unix domain socket connections to the same apphost based on a stable backchannel name

Copy link
Contributor Author

Copilot AI commented Aug 30, 2025

@copilot The apphost needs to support multiple unix domain socket connections to the same apphost based on a stable backchannel name

I've modified the BackchannelService to support multiple Unix domain socket connections. The service now accepts connections in a loop, handling each one in a separate background task while maintaining the same AppHostRpcTarget instance. This allows the main aspire run connection to coexist with transient aspire log connections. The first connection still signals the completion source for backward compatibility. See commit 6c96950.

@Copilot Copilot AI changed the title Add aspire log <resource-name> CLI command for resource log streaming Add support for multiple Unix domain socket connections to enable aspire log command Aug 30, 2025
Copilot finished work on behalf of davidfowl August 30, 2025 07:14
@Copilot Copilot AI requested a review from davidfowl August 30, 2025 07:14
Copy link
Contributor

🚀 Dogfood this PR with:

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

Or

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

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.

2 participants