Skip to content

Add CLI telemetry export#13963

Merged
DamianEdwards merged 1 commit intomainfrom
jamesnk/cli-telemetry
Jan 27, 2026
Merged

Add CLI telemetry export#13963
DamianEdwards merged 1 commit intomainfrom
jamesnk/cli-telemetry

Conversation

@JamesNK
Copy link
Copy Markdown
Member

@JamesNK JamesNK commented Jan 16, 2026

Description

This PR enables CLI telemetry export to AppInsights. High level changes:

  • There are two trace collection pipelines:
    • One is for recorded telemetry so we're explicit in what is exported to AppInsights.
    • More detailed telemetry for diagnostics is still available to be exported if an OTLP endpoint is configured.
  • OTEL Azure Monitor exporter added for sending telemetry to AppInsights.
    • It periodically sends telemetry in batches in the background, and also flushes when the CLI shuts down. There is a 100ms limit on how long it waits during shutdown to flush.
    • Azure Monitor exporter also has the capability to temporarily store telemetry to disk. This is a background thing that is built into the exporter and retries sending unsent telemetry. The only thing Aspire CLI does is configure a store location.
    • You can opt out with the ASPIRE_CLI_TELEMETRY_OPTOUT env var.
    • Connection string is hardcoded in app
  • A console exporter can be configured. Set ASPIRE_CLI_CONSOLE_EXPORTER_LEVEL=Reported to see what is exported.
  • Recorded telemetry are:
    • Activities (event + duration). Currently recorded is the CLI running and ensuring .NET SDK is present.
    • Activity events. Currently recorded is errors.
  • Common telemetry properties are added:
    • Hashed MAC address
    • DeviceId (matches logic in other apps, e.g. dotnet CLI)
    • Aspire CLI version
    • Is running in CI
    • User name (only used to capture MS internal accounts)
  • Some first-run welcome text is displayed the first time the dashboard is run.
    • Required to display a notice about telemetry.
    • A sentinel file is written to user profile to indicate this is displayed.
    • Can be surpressed with --nologo option.

Remaining tasks:

  • Finialize telemetry names and attributes
  • Hardcode MS AppInsights connection string

Addresses #14034

Example console output (displaying first run text and with console exporter enabled):

👋 Welcome to Aspire! Learn more about Aspire at https://aspire.dev

Telemetry
---------

The Aspire CLI collects usage data in order to help us improve your experience. It is collected by Microsoft and shared
with the community. You can opt-out of telemetry by setting the ASPIRE_CLI_TELEMETRY_OPTOUT environment variable to '1'
or 'true' using your favorite shell.

Read more about Aspire CLI telemetry: https://aka.ms/aspire/cli-telemetry


Activity.TraceId:            2dde914994489ae077563ddf8cbf2466
Activity.SpanId:             63b37a0b547f4ed4
Activity.TraceFlags:         Recorded
Activity.ParentSpanId:       f040ba41f561b4b2
Activity.DisplayName:        aspire/cli/ensure_sdk_installed
Activity.Kind:               Internal
Activity.StartTime:          2026-01-22T21:23:18.2961142Z
Activity.Duration:           00:00:00.0340887
Activity.Tags:
    machine.mac_address_hash: 8895967e30aa22196e97314089a8eb14df610e5cb98b6f70b70bee9c88d68cc0
    machine.device_id: 0d1b7ea1-42e8-456b-8307-d008225f18c9
    aspire.cli.version: 13.2.0-dev
    deployment.environment.name: local
    user.name: jamesnk
    user.domain: SOUTHPACIFIC
    aspire.cli.sdk.detected_version: 10.0.102
    aspire.cli.sdk.minimum_required_version: 10.0.100
    aspire.cli.sdk.check_result: already_installed
    aspire.cli.sdk.install_result: already_installed
    _MS.ProcessedByMetricExtractors: (Name: X,Ver:'1.1')
Instrumentation scope (ActivitySource):
    Name: Aspire.Cli.Reported
Resource associated with Activity:
    service.name: aspire-cli
    service.version: 13.2.0-dev
    service.instance.id: 798ea2d1-96e2-4770-8109-93f6da65e091
    telemetry.sdk.name: opentelemetry
    telemetry.sdk.language: dotnet
    telemetry.sdk.version: 1.14.0

🛠  Executing step publish
❌ An unexpected error occurred: Run completed without returning a backchannel.

A new version of the Aspire CLI is available: 13.2.0-preview.1.26072.3
To update, run: aspire update
For more information, see: https://aka.ms/aspire/update

Activity.TraceId:            2dde914994489ae077563ddf8cbf2466
Activity.SpanId:             f040ba41f561b4b2
Activity.TraceFlags:         Recorded
Activity.DisplayName:        aspire publish
Activity.Kind:               Internal
Activity.StartTime:          2026-01-22T21:23:18.2504992Z
Activity.Duration:           00:00:06.5892811
Activity.Tags:
    machine.mac_address_hash: 8895967e30aa22196e97314089a8eb14df610e5cb98b6f70b70bee9c88d68cc0
    machine.device_id: 0d1b7ea1-42e8-456b-8307-d008225f18c9
    aspire.cli.version: 13.2.0-dev
    deployment.environment.name: local
    user.name: jamesnk
    user.domain: SOUTHPACIFIC
    process.pid: 36348
    process.executable.name: aspire
    aspire.cli.command.name: aspire publish
    process.exit.code: 6
    _MS.ProcessedByMetricExtractors: (Name: X,Ver:'1.1')
Activity.Events:
    aspire/cli/error [22/1/2026 9:23:24 pm +00:00]
        exception.type: System.InvalidOperationException
        exception.message: Run completed without returning a backchannel.
        exception.stacktrace:    at Aspire.Cli.Commands.PipelineCommandBase.<>c__DisplayClass24_1.<<ExecuteAsync>b__0>d.MoveNext() in C:\Development\Source\aspire\src\Aspire.Cli\Commands\PipelineCommandBase.cs:line 197
--- End of stack trace from previous location ---
   at Aspire.Cli.Interaction.ConsoleInteractionService.ShowStatusAsync[T](String statusText, Func`1 action) in C:\Development\Source\aspire\src\Aspire.Cli\Interaction\ConsoleInteractionService.cs:line 45
   at Aspire.Cli.Commands.PipelineCommandBase.ExecuteAsync(ParseResult parseResult, CancellationToken cancellationToken) in C:\Development\Source\aspire\src\Aspire.Cli\Commands\PipelineCommandBase.cs:line 186
        machine.mac_address_hash: 8895967e30aa22196e97314089a8eb14df610e5cb98b6f70b70bee9c88d68cc0
        machine.device_id: 0d1b7ea1-42e8-456b-8307-d008225f18c9
        aspire.cli.version: 13.2.0-dev
        deployment.environment.name: local
        user.name: jamesnk
        user.domain: SOUTHPACIFIC
Instrumentation scope (ActivitySource):
    Name: Aspire.Cli.Reported
Resource associated with Activity:
    service.name: aspire-cli
    service.version: 13.2.0-dev
    service.instance.id: 798ea2d1-96e2-4770-8109-93f6da65e091
    telemetry.sdk.name: opentelemetry
    telemetry.sdk.language: dotnet
    telemetry.sdk.version: 1.14.0


C:\Development\Source\aspire\artifacts\bin\Aspire.Cli\Debug\net10.0\aspire.exe (process 36348) exited with code 6 (0x6).

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
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No
  • Does the change require an update in our Aspire docs?

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 16, 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 -- 13963

Or

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

@JamesNK JamesNK force-pushed the jamesnk/cli-telemetry branch 2 times, most recently from 6fc7a90 to 6b6e7b5 Compare January 19, 2026 07:19
@JamesNK JamesNK marked this pull request as ready for review January 19, 2026 08:59
Copilot AI review requested due to automatic review settings January 19, 2026 08:59
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 pull request adds telemetry export functionality to the Aspire CLI. The implementation includes OpenTelemetry instrumentation with Azure Monitor and OTLP exporters, platform-specific machine information providers for device identification, and comprehensive error tracking throughout CLI commands.

Changes:

  • Introduces telemetry infrastructure with dual activity sources (reported and diagnostics)
  • Adds machine information providers for Windows, Linux, and macOS to generate persistent device IDs
  • Integrates telemetry error recording into all command exception handlers
  • Updates test infrastructure to support initialized telemetry instances

Reviewed changes

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

Show a summary per file
File Description
src/Aspire.Cli/Telemetry/AspireCliTelemetry.cs Core telemetry service with activity creation and error recording
src/Aspire.Cli/Telemetry/TelemetryManager.cs Manages TracerProvider instances for Azure Monitor and debug exporters
src/Aspire.Cli/Telemetry/TelemetryConstants.cs Defines telemetry tag and event name constants
src/Aspire.Cli/Telemetry/*MachineInformationProvider.cs Platform-specific device ID and MAC address collection
src/Aspire.Cli/Program.cs Initializes telemetry, adds main activity tracking, and custom exception handling
src/Aspire.Cli/Commands/*.cs Integrates telemetry into all commands with error recording
src/Shared/IConfigurationExtensions.cs Adds CLI conditional compilation and simplifies string retrieval
tests/Aspire.Cli.Tests/Telemetry/*.cs Comprehensive test coverage for telemetry components
tests/Aspire.Cli.Tests/*Tests.cs Updates existing tests to use initialized telemetry
Directory.Packages.props, eng/Versions.props Adds Azure Monitor and Console exporter package references
eng/clipack/Common.projitems Increases max file size from 25MB to 30MB

Comment thread src/Aspire.Cli/Telemetry/TelemetryConstants.cs
@JamesNK JamesNK force-pushed the jamesnk/cli-telemetry branch from f519163 to d6ff61c Compare January 22, 2026 01:22
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 22, 2026

🎬 CLI E2E Test Recordings

The following terminal recordings are available for commit 7c6df61:

Test Recording
CreateAndDeployToDockerCompose ▶️ View Recording
CreateAndDeployToDockerComposeInteractive ▶️ View Recording
CreateAndRunAspireStarterProject ▶️ View Recording
CreateAndRunJsReactProject ▶️ View Recording
CreateAndRunPythonReactProject ▶️ View Recording
CreateEmptyAppHostProject ▶️ View Recording
CreateStartAndStopAspireProject ▶️ View Recording
CreateTypeScriptAppHostWithViteApp ▶️ View Recording
DoctorCommand_WithSslCertDir_ShowsTrusted ▶️ View Recording
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted ▶️ View Recording
PsCommandListsRunningAppHost ▶️ View Recording

📹 Recordings uploaded automatically from CI run #21388741305

@sebastienros
Copy link
Copy Markdown
Contributor

Is that related to #13727 ?

@JamesNK
Copy link
Copy Markdown
Member Author

JamesNK commented Jan 22, 2026

No. The is telemetry about what the CLI is doing

@JamesNK JamesNK requested a review from DamianEdwards January 22, 2026 23:26
@JamesNK JamesNK force-pushed the jamesnk/cli-telemetry branch from e6a28fd to 578dc31 Compare January 22, 2026 23:50
@github-actions
Copy link
Copy Markdown
Contributor

🎬 CLI E2E Test Recordings

The following terminal recordings are available for commit 578dc31:

Test Recording
CreateAndDeployToDockerCompose ▶️ View Recording
CreateAndDeployToDockerComposeInteractive ▶️ View Recording
CreateAndRunAspireStarterProject ▶️ View Recording
CreateAndRunJsReactProject ▶️ View Recording
CreateAndRunPythonReactProject ▶️ View Recording
CreateEmptyAppHostProject ▶️ View Recording
CreateStartAndStopAspireProject ▶️ View Recording
CreateTypeScriptAppHostWithViteApp ▶️ View Recording
DoctorCommand_WithSslCertDir_ShowsTrusted ▶️ View Recording
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted ▶️ View Recording
PsCommandListsRunningAppHost ▶️ View Recording

📹 Recordings uploaded automatically from CI run #21269135037

Comment thread src/Aspire.Cli/Telemetry/LinuxMachineInformationProvider.cs Outdated
Comment thread src/Aspire.Cli/Telemetry/TelemetryManager.cs
Comment thread src/Aspire.Cli/Telemetry/AspireCliTelemetry.cs Outdated
@JamesNK JamesNK force-pushed the jamesnk/cli-telemetry branch from 578dc31 to 3b0b68e Compare January 27, 2026 00:18
@JamesNK JamesNK force-pushed the jamesnk/cli-telemetry branch from 6c1b42d to 7c6df61 Compare January 27, 2026 07:41
Comment thread src/Aspire.Cli/Program.cs
await app.StartAsync().ConfigureAwait(false);

// Display first run experience if this is the first time the CLI is run on this machine
var noLogo = args.Any(a => a == "--nologo");
Copy link
Copy Markdown
Member

@DamianEdwards DamianEdwards Jan 27, 2026

Choose a reason for hiding this comment

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

@JamesNK we should support an env var for this too, e.g. ASPIRE_CLI_NOLOGO. We can add that in a follow up.

@DamianEdwards
Copy link
Copy Markdown
Member

@JamesNK would be great to get an E2E CLI test added that shows the welcome banner so we can see it in asciinema recordings (again, can do in follow up).

@DamianEdwards DamianEdwards merged commit 665f66e into main Jan 27, 2026
328 checks passed
@DamianEdwards DamianEdwards deleted the jamesnk/cli-telemetry branch January 27, 2026 16:58
@dotnet-policy-service dotnet-policy-service Bot added this to the 13.2 milestone Jan 27, 2026
Copilot AI mentioned this pull request Jan 27, 2026
10 tasks
Copilot AI added a commit that referenced this pull request Jan 27, 2026
Add missing AspireCliTelemetry parameter to ResourcesCommand and LogsCommand constructors, and pass it to the BaseCommand base constructor. This fixes the build failures introduced by PR #13963 which added telemetry support to BaseCommand.

Co-authored-by: radical <1472+radical@users.noreply.github.com>
adamint pushed a commit that referenced this pull request Jan 27, 2026
* Initial plan

* Fix missing telemetry parameter in ResourcesCommand and LogsCommand

Add missing AspireCliTelemetry parameter to ResourcesCommand and LogsCommand constructors, and pass it to the BaseCommand base constructor. This fixes the build failures introduced by PR #13963 which added telemetry support to BaseCommand.

Co-authored-by: radical <1472+radical@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: radical <1472+radical@users.noreply.github.com>
@github-actions github-actions Bot locked and limited conversation to collaborators Feb 27, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants