Skip to content

Conversation

@Hona
Copy link

@Hona Hona commented Jan 2, 2026

adds a WHOLE bunch of commands to be able to get all the OTEL data you could want via the CLI/MCP...

example usage:

🔥 Cool Demo Commands
Traces
# List recent traces (newest first)
aspire telemetry traces --dashboard-url https://localhost:18888
# Get specific trace by ID
aspire telemetry traces abc123def456 --dashboard-url https://localhost:18888
# Filter traces with errors only
aspire telemetry traces --filter "status=Error" --dashboard-url https://localhost:18888
# Search span names
aspire telemetry traces --search "api/orders" --dashboard-url https://localhost:18888
# Filter by resource and HTTP method
aspire telemetry traces --resource apiservice --filter "http.method=POST" --dashboard-url https://localhost:18888
# JSON output for piping to jq
aspire telemetry traces --json --limit 5 --dashboard-url https://localhost:18888 | jq '.traces[0]'
Logs
# List recent logs
aspire telemetry logs --dashboard-url https://localhost:18888
# Filter by severity (Warning and above)
aspire telemetry logs --severity Warning --dashboard-url https://localhost:18888
# Errors only
aspire telemetry logs --severity Error --dashboard-url https://localhost:18888
# Filter by resource
aspire telemetry logs --resource basket --dashboard-url https://localhost:18888
# Logs for a specific trace
aspire telemetry logs --trace abc123def456 --dashboard-url https://localhost:18888
# Message contains filter
aspire telemetry logs --filter "message~connection refused" --dashboard-url https://localhost:18888
Metrics
# List all metrics for a resource
aspire telemetry metrics --resource apiservice --dashboard-url https://localhost:18888
# Get specific metric data (meter/instrument format)
aspire telemetry metrics "System.Net.Http/http.client.request.duration" --resource apiservice --dashboard-url https://localhost:18888
# Custom time duration
aspire telemetry metrics "System.Net.Http/http.client.request.duration" --resource apiservice --duration 30m --dashboard-url https://localhost:18888
Fields Discovery
# List all available telemetry fields
aspire telemetry fields --dashboard-url https://localhost:18888
# List only trace fields
aspire telemetry fields --type traces --dashboard-url https://localhost:18888
# Get values for a specific field (great for building filters!)
aspire telemetry fields http.method --dashboard-url https://localhost:18888
# Get log categories
aspire telemetry fields category --type logs --dashboard-url https://localhost:18888
Combining Filters (Power User)
# Multiple filters (AND logic)
aspire telemetry traces \
  --resource apiservice \
  --filter "http.method=POST" \
  --filter "http.response.status_code>=400" \
  --dashboard-url https://localhost:18888
# Complex log query
aspire telemetry logs \
  --resource basket \
  --severity Warning \
  --filter "category~Microsoft.EntityFrameworkCore" \
  --limit 50 \
  --json \
  --dashboard-url https://localhost:18888
Help Commands (show polish)
aspire telemetry --help
aspire telemetry traces --help
aspire telemetry logs --help

Description

Please include a summary of the changes and the related issue. Please also include relevant motivation and context. List any dependencies that are required for this change.

Fixes # (issue)

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?

Hona added 30 commits January 2, 2026 18:43
- Add FilterExpressionParser.cs with ParsedFilter record and Parse method
- Support operators: =, !=, ~, !~, >, <, >=, <=
- Add FilterParseException for error handling
- Add comprehensive tests (54 test cases)
- Fix missing McpCommandStrings.StartCommand_ApiKeyWithoutDashboardUrlError
- Add ExitCodeConstants.FailedToParseCli
- Update plan.md to mark task 1.1 complete
Add filter-to-telemetry converter to ParsedFilter for JSON serialization:
- Add TelemetryFilterDto class matching Dashboard's FieldTelemetryFilter format
- Add ToTelemetryConditionString() extension for FilterCondition enum
- Map CLI FilterCondition to Dashboard-compatible strings (equals, contains, gt, etc.)
- Add comprehensive tests for converter and condition string mapping
Add ListTelemetryFields method to AspireFieldsMcpTools that enables
discovering available telemetry fields for filtering traces and logs.

- Add McpServerTool with optional type and resourceName parameters
- Return JSON with known fields and custom attribute keys
- Include field counts for each telemetry type
- Add comprehensive test suite (9 tests) covering all scenarios
Add GetTelemetryFieldValues method to AspireFieldsMcpTools that returns
distinct values for a specified telemetry field with occurrence counts,
ordered by count descending.

Features:
- Required fieldName parameter for specifying which field to query
- Optional type parameter to filter to 'traces' or 'logs'
- Optional resourceName parameter for resource validation
- Returns values with counts in JSON format
- Results ordered by count (highest first)

Tests added for:
- Valid field returning values
- Multiple values with counts
- Unknown field returning empty list
- Type filtering (traces/logs)
- Resource validation
- Count ordering
- Missing field name error
- Invalid type error
Document the requirement to set DOTNET_ROOT when running tests so that
the local SDK runtimes (e.g., .NET 8.0.21) are used instead of the
global dotnet installation which may not have the required versions.
- Add 'filters' parameter to ListTraces method accepting JSON array of filter objects
- Add 'searchText' parameter for span name search
- Implement TryParseFilters helper to parse JSON filters into TelemetryFilter list
- Support multiple condition formats (equals, !equals, contains, gt, lt, etc.)
- Add comprehensive tests for filtering by attributes, status, and text search
…se 3.2)

- Add 'filters' parameter for JSON array of filter objects (field, condition, value)
- Add 'severity' parameter for minimum log level filtering (Trace, Debug, Info, Warning, Error, Critical)
- Support common severity aliases (info->Information, warn->Warning, fatal->Critical)
- Add TryParseSeverity helper method with helpful error messages
- Add 8 new tests covering severity filtering, category filtering, message filtering, custom attributes, multiple filters, and error cases
Implements Phase 4 of the Aspire CLI telemetry commands plan:
- Create AspireMetricsMcpTools.cs with list_metrics and get_metric_data tools
- list_metrics: Lists available instruments for a resource, grouped by meter
- get_metric_data: Retrieves metric values for a specific instrument with
  configurable duration (1m, 5m, 15m, 30m, 1h, 3h, 6h, 12h)
- Register tools in McpExtensions.cs
- Add comprehensive test coverage (24 tests)
Implement CLI proxy tool for list_telemetry_fields that forwards
requests to the Dashboard MCP endpoint, following the established
proxy pattern from ListTracesTool.
Update ListTracesTool.cs to expose the filters and searchText parameters
that the Dashboard MCP tool already supports. This enables CLI MCP clients
to filter traces by field conditions and search span names.

Added ListTracesToolTests.cs with comprehensive tests for schema validation.
Implement Phase 5.3 - CLI MCP proxy tools for metrics that forward
requests to the Dashboard MCP endpoint:

- ListMetricsTool: Lists available metrics/instruments for a resource
- GetMetricDataTool: Gets metric data for a specific instrument

Both tools follow the existing proxy pattern and include comprehensive
tests for schema validation and metadata.
…ce output

- Create TelemetryOutputFormatter class using Spectre.Console for CLI telemetry output
- Implement FormatTraces() method with:
  - Header showing count and newest first indicator
  - Trace ID, timestamp, duration, and error status display
  - Resource flow visualization (source -> destination)
  - Span hierarchy with proper indentation
  - Error highlighting in red
  - Attribute truncation for long values
- Add FormatSingleTrace() for detailed trace view with full span attributes
- Add comprehensive test suite in TelemetryOutputFormatterTests.cs
- Update plan.md marking Phase 6.2 trace formatting complete
…log output

Implement log formatting with:
- Severity-based color coding (Critical=red bold, Error=red, Warning=yellow, etc.)
- Resource name and log category display
- Trace/span ID correlation (hides zero IDs)
- Attribute display with truncation for long values
- Exception stack trace formatting with truncation
- Dashboard link support
- Newest first ordering by log_id

Add 16 new tests covering all formatting scenarios.
…Formatter

Implement metrics formatting for human-readable console output:
- FormatMetricsList: Groups instruments by meter name, shows name/type/unit/description
- FormatMetricData: Shows instrument summary, dimensions with values, formats units nicely (bytes, durations, percentages)
- Add 15 tests covering empty/null cases, grouping, dimension display, unit formatting

Phase 6.4 complete: Metrics formatting for CLI telemetry commands
Implement fields formatting for human-readable console output:
- FormatFields() displays known fields and custom attributes separately
- FormatFieldValues() shows distinct values with occurrence counts
- Both support traces-only, logs-only, or combined output
- Added comprehensive tests for edge cases and formatting
- Create TelemetryCommand.cs with --project, --dashboard-url, and --api-key options
- Register TelemetryCommand in DI (Program.cs, CliTestHelper.cs, RootCommand.cs)
- Add TelemetryCommandStrings resource file for localized strings
- Create TelemetryCommandTests.cs with 5 passing tests
- Update plan.md to mark Phase 7.1 as complete
Implement 'aspire telemetry fields' subcommand that allows users to:
- List available telemetry fields (known fields and custom attributes)
- Get distinct values for a specific field with occurrence counts
- Filter by type (traces/logs) and resource name
- Output in human-readable or JSON format

The command connects to the Dashboard MCP endpoint either via running
AppHost (discovered via backchannel) or standalone Dashboard URL.
Implement the 'aspire telemetry traces' command that allows querying
distributed traces from running Aspire applications. The command supports:

- Listing recent traces with filtering options
- Getting specific trace details by trace ID
- Filter expressions (e.g., 'status=Error', 'http.method=POST')
- Searching span names with --search option
- Resource filtering with --resource option
- JSON or human-readable output formats
- Configurable result limit (default 100)

The command connects to the Dashboard's MCP server to query trace data,
supporting both AppHost connections and standalone Dashboard via --dashboard-url.

This completes Phase 8.1 of the telemetry CLI implementation plan.
Implement Phase 9.1 of the Aspire CLI telemetry commands plan:

- Add TelemetryLogsCommand with options for resource, trace ID, span ID,
  filter expressions, severity level, limit, and JSON output
- Register logs command as subcommand of telemetry parent command
- Add resource strings for all logs command options and errors
- Add comprehensive tests for command structure and options

The logs command queries structured OTel logs from a running Aspire
Dashboard, supporting filtering by resource, correlation IDs, severity,
and custom filter expressions.
- Move filter expression parsing to occur before Dashboard connection
- Add InvalidArguments exit code (18) for early validation failures
- Add test TelemetryTracesCommand_InvalidFilterSyntax_ReturnsError
- Update plan.md with completed Phase 8.3 items
Add the 'aspire telemetry metrics' subcommand to query metrics data from
running Aspire applications. The command supports:
- Required --resource option (metrics always require a specific resource)
- Optional --duration for time window (1m, 5m, 15m, 30m, 1h, 3h, 6h, 12h)
- Optional --json flag for JSON output
- Optional meter/instrument argument for specific metric data

This completes Phase 10.1 of the CLI telemetry commands implementation.
Hona added 19 commits January 2, 2026 22:46
Remove the -d short alias from --duration option in the telemetry metrics
command since it conflicts with --debug (-d) which is defined as a recursive
option on the root command.
- All error handling tests pass (20 FilterFieldValidatorTests)
- Invalid filter fields suggest similar valid fields using Levenshtein distance
- Connection errors include actionable guidance (--project, --dashboard-url)
Add examples section to all telemetry command descriptions following the
pattern used by the exec command. This makes it easier for users to understand
how to use the commands by showing common usage patterns.

Commands updated:
- telemetry (parent command)
- telemetry traces
- telemetry logs
- telemetry metrics
- telemetry fields
DisplayPlainText used _ansiConsole.WriteLine() which caused Spectre.Console
to insert line breaks in output when rendered to narrow terminals. This
broke JSON output that tools like jq couldn't parse.

Changed to use Console.WriteLine() directly for machine-readable output.
Add tests to verify telemetry command help text includes examples:
- TelemetryCommand_Description_IncludesExamples
- TelemetrySubcommand_Description_IncludesExamples (parameterized for all subcommands)
- TelemetryTracesCommand_Description_IncludesFilterExamples
- TelemetryLogsCommand_Description_IncludesSeverityExample
- TelemetryMetricsCommand_Description_IncludesDurationExample
- TelemetryFieldsCommand_Description_IncludesTypeExample

Update plan.md to mark Phase 11.3 documentation and help text tasks as complete.
Add ValidateFilterFieldsAsync method that validates user-provided filter
fields against available fields from the Dashboard before executing the
query. This provides early feedback with suggestions when users specify
invalid field names (e.g., typos like 'log.messag' instead of 'log.message').

The validation:
- Calls the list_telemetry_fields MCP tool to get available log fields
- Uses FilterFieldValidator to check each filter field
- Returns helpful error messages with 'Did you mean?' suggestions
- Gracefully skips validation if the Dashboard doesn't support the tool

This brings TelemetryLogsCommand to feature parity with TelemetryTracesCommand
which already had this validation.
Verified:
- Full test suite passes (936 CLI tests, 1127 Dashboard tests)
- No new TODO comments in telemetry code
- No breaking changes to existing commands (all existing tests pass)
Extract common utility methods shared across telemetry commands into
a new TelemetryCommandHelper static class to improve code consistency
and reduce duplication:
- GetDashboardConnection: shared Dashboard connection logic
- GetTextFromResult: MCP result text extraction
- ExtractJsonFromResult: JSON extraction from MCP responses
- EscapeJsonString: JSON string escaping

This reduces ~200 lines of duplicate code across the four telemetry
commands (traces, logs, fields, metrics).
- Performance review: all telemetry commands respond in <300ms
- Filter expressions validated before Dashboard connection
- Invalid filters return helpful error messages with Levenshtein suggestions
- Human-readable output uses TelemetryOutputFormatter with Spectre.Console
- All 936 CLI tests pass
- No regression in existing CLI commands verified via test suite
Add CLI MCP proxy tool that forwards get_trace calls to the Dashboard.
This provides MCP feature parity for fetching specific distributed traces
by trace ID.

- Create GetTraceTool.cs with input schema and forwarding logic
- Add GetTraceToolTests.cs with 6 tests for schema and metadata
- Update plan.md with Phase 5.4 and file summary
Verified that all Dashboard MCP telemetry tools have corresponding CLI proxy
counterparts, confirming feature parity:
- list_structured_logs -> ListStructuredLogsTool
- list_traces -> ListTracesTool
- get_trace -> GetTraceTool
- list_telemetry_fields -> ListTelemetryFieldsTool
- get_telemetry_field_values -> GetTelemetryFieldValuesTool
- list_metrics -> ListMetricsTool
- get_metric_data -> GetMetricDataTool
Add Implementation Status section noting all implementation work is complete.
Updated remaining unchecked test items to explicitly note they require
a running Dashboard or AppHost to execute.

All unit tests pass (942 CLI tests, 1127 Dashboard tests).
- Update status to COMPLETE with verification date
- Update test count to 942 CLI tests, 1127 Dashboard tests
- Clarify remaining unchecked items require live Dashboard infrastructure
Add assertions to McpServiceTests to verify that the new telemetry
MCP tools (get_trace, list_telemetry_fields, get_telemetry_field_values,
list_metrics, get_metric_data) are properly registered and available
when the Dashboard MCP endpoint is accessed.

This ensures the new tools added as part of the telemetry commands
implementation are wired up correctly in the MCP infrastructure.
Copilot AI review requested due to automatic review settings January 2, 2026 14:14
@github-actions
Copy link
Contributor

github-actions bot commented Jan 2, 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 -- 13727

Or

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

@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Jan 2, 2026
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

This PR introduces a proof-of-concept CLI interface for querying telemetry data (traces, logs, metrics) from the Aspire Dashboard via the Model Context Protocol (MCP). The implementation adds filtering capabilities, field discovery tools, and human-readable formatting for CLI output.

Key changes:

  • New MCP tools for querying metrics and discovering available telemetry fields
  • Enhanced trace and log filtering with JSON-based filter expressions
  • CLI output formatter with support for traces, logs, metrics, and field data
  • Comprehensive test coverage for new functionality

Reviewed changes

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

Show a summary per file
File Description
tests/Aspire.Dashboard.Tests/Mcp/AspireTelemetryMcpToolsTests.cs Adds tests for filtering traces/logs and the new get_trace tool
tests/Aspire.Dashboard.Tests/Mcp/AspireMetricsMcpToolsTests.cs New test file for metrics MCP tools functionality
tests/Aspire.Dashboard.Tests/Mcp/AspireFieldsMcpToolsTests.cs New test file for telemetry fields discovery tools
tests/Aspire.Dashboard.Tests/Integration/McpServiceTests.cs Updates integration tests to verify new MCP tools are registered
tests/Aspire.Cli.Tests/Utils/TelemetryOutputFormatterTests.cs Comprehensive tests for CLI telemetry output formatting
tests/Aspire.Cli.Tests/Utils/FilterFieldValidatorTests.cs Tests for validating filter fields against available telemetry fields
tests/Aspire.Cli.Tests/Utils/FilterExpressionParserTests.cs Tests for parsing filter expressions with various operators
tests/Aspire.Cli.Tests/Utils/CliTestHelper.cs Registers new telemetry command services for testing
tests/Aspire.Cli.Tests/Mcp/*.cs Schema tests for new MCP tools (ListTraces, GetTrace, ListMetrics, etc.)
tests/Aspire.Cli.Tests/Commands/*.cs Command tests for new telemetry CLI commands
src/Aspire.Dashboard/Mcp/McpExtensions.cs Registers new AspireFieldsMcpTools and AspireMetricsMcpTools
src/Aspire.Dashboard/Mcp/AspireTelemetryMcpTools.cs Adds filtering and get_trace functionality to existing tools
src/Aspire.Dashboard/Mcp/AspireMetricsMcpTools.cs New MCP tools for listing and querying metrics data
src/Aspire.Dashboard/Mcp/AspireFieldsMcpTools.cs New MCP tools for discovering available telemetry fields and their values
src/Aspire.Cli/Utils/TelemetryOutputFormatter.cs New formatter for human-readable telemetry output in CLI
src/Aspire.Cli/Utils/TelemetryCommandHelper.cs Helper utilities for telemetry commands
src/Aspire.Cli/Resources/*.resx Localization updates for new MCP command options
Files not reviewed (2)
  • src/Aspire.Cli/Resources/McpCommandStrings.Designer.cs: Language not supported
  • src/Aspire.Cli/Resources/TelemetryCommandStrings.Designer.cs: Language not supported

@davidfowl
Copy link
Member

Very cool, we will be using it as inspiration for first class commands in #14138

@davidfowl davidfowl closed this Jan 29, 2026
@dotnet-policy-service dotnet-policy-service bot added this to the 13.2 milestone Jan 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants