Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/Aspire.Cli/Commands/TelemetryCommandHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ internal static class TelemetryCommandHelpers
Description = TelemetryCommandStrings.SearchOptionDescription
};

/// <summary>
/// Minimum span duration option for spans and traces commands.
/// </summary>
internal static Option<double?> CreateMinimumDurationOption() => new("--min-duration", "--min-duration-ms")
{
Description = TelemetryCommandStrings.MinimumDurationOptionDescription
};

/// <summary>
/// Dashboard URL option for connecting directly to a standalone dashboard.
/// </summary>
Expand Down
8 changes: 6 additions & 2 deletions src/Aspire.Cli/Commands/TelemetrySpansCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ internal sealed class TelemetrySpansCommand : BaseCommand
private static readonly Option<string?> s_dashboardUrlOption = TelemetryCommandHelpers.CreateDashboardUrlOption();
private static readonly Option<string?> s_apiKeyOption = TelemetryCommandHelpers.CreateApiKeyOption();
private static readonly Option<string?> s_searchOption = TelemetryCommandHelpers.CreateSearchOption();
private static readonly Option<double?> s_minimumDurationOption = TelemetryCommandHelpers.CreateMinimumDurationOption();

public TelemetrySpansCommand(
IInteractionService interactionService,
Expand Down Expand Up @@ -74,6 +75,7 @@ public TelemetrySpansCommand(
Options.Add(s_dashboardUrlOption);
Options.Add(s_apiKeyOption);
Options.Add(s_searchOption);
Options.Add(s_minimumDurationOption);
}

protected override async Task<CommandResult> ExecuteAsync(ParseResult parseResult, CancellationToken cancellationToken)
Expand All @@ -90,6 +92,7 @@ protected override async Task<CommandResult> ExecuteAsync(ParseResult parseResul
var dashboardUrl = parseResult.GetValue(s_dashboardUrlOption);
var apiKey = parseResult.GetValue(s_apiKeyOption);
var search = parseResult.GetValue(s_searchOption);
var minimumDuration = parseResult.GetValue(s_minimumDurationOption);

// Validate --limit value
if (limit.HasValue && limit.Value < 1)
Expand All @@ -105,7 +108,7 @@ protected override async Task<CommandResult> ExecuteAsync(ParseResult parseResul
return CommandResult.FromExitCode(dashboardApi.ExitCode);
}

return CommandResult.FromExitCode(await FetchSpansAsync(dashboardApi.BaseUrl!, dashboardApi.ApiToken!, resourceName, traceId, hasError, limit, follow, format, dashboardOnly: dashboardUrl is not null, dashboardApi.DashboardUrl!, search, cancellationToken));
return CommandResult.FromExitCode(await FetchSpansAsync(dashboardApi.BaseUrl!, dashboardApi.ApiToken!, resourceName, traceId, hasError, limit, follow, format, dashboardOnly: dashboardUrl is not null, dashboardApi.DashboardUrl!, search, minimumDuration, cancellationToken));
}

private async Task<int> FetchSpansAsync(
Expand All @@ -120,6 +123,7 @@ private async Task<int> FetchSpansAsync(
bool dashboardOnly,
string dashboardUrl,
string? search,
double? minimumDuration,
CancellationToken cancellationToken)
{
try
Expand All @@ -143,7 +147,7 @@ private async Task<int> FetchSpansAsync(
// Build URL with query parameters
int? effectiveLimit = (limit.HasValue && !follow) ? limit.Value : null;

var url = DashboardUrls.TelemetrySpansApiUrl(baseUrl, resolvedResources, traceId: traceId, hasError: hasError, limit: effectiveLimit, follow: follow ? true : null, search: search);
var url = DashboardUrls.TelemetrySpansApiUrl(baseUrl, resolvedResources, traceId: traceId, hasError: hasError, limit: effectiveLimit, follow: follow ? true : null, search: search, minDurationMs: minimumDuration);

_logger.LogDebug("Fetching spans from {Url}", url);

Expand Down
13 changes: 9 additions & 4 deletions src/Aspire.Cli/Commands/TelemetryTracesCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ internal sealed class TelemetryTracesCommand : BaseCommand
private static readonly Option<string?> s_dashboardUrlOption = TelemetryCommandHelpers.CreateDashboardUrlOption();
private static readonly Option<string?> s_apiKeyOption = TelemetryCommandHelpers.CreateApiKeyOption();
private static readonly Option<string?> s_searchOption = TelemetryCommandHelpers.CreateSearchOption();
private static readonly Option<double?> s_minimumDurationOption = TelemetryCommandHelpers.CreateMinimumDurationOption();

public TelemetryTracesCommand(
IInteractionService interactionService,
Expand Down Expand Up @@ -73,6 +74,7 @@ public TelemetryTracesCommand(
Options.Add(s_dashboardUrlOption);
Options.Add(s_apiKeyOption);
Options.Add(s_searchOption);
Options.Add(s_minimumDurationOption);
}

protected override async Task<CommandResult> ExecuteAsync(ParseResult parseResult, CancellationToken cancellationToken)
Expand All @@ -88,6 +90,7 @@ protected override async Task<CommandResult> ExecuteAsync(ParseResult parseResul
var dashboardUrl = parseResult.GetValue(s_dashboardUrlOption);
var apiKey = parseResult.GetValue(s_apiKeyOption);
var search = parseResult.GetValue(s_searchOption);
var minimumDuration = parseResult.GetValue(s_minimumDurationOption);

// Validate --limit value
if (limit.HasValue && limit.Value < 1)
Expand All @@ -107,11 +110,11 @@ protected override async Task<CommandResult> ExecuteAsync(ParseResult parseResul
{
if (!string.IsNullOrEmpty(traceId))
{
return CommandResult.FromExitCode(await FetchSingleTraceAsync(dashboardApi.BaseUrl!, dashboardApi.ApiToken!, traceId, format, dashboardApi.DashboardUrl!, cancellationToken));
return CommandResult.FromExitCode(await FetchSingleTraceAsync(dashboardApi.BaseUrl!, dashboardApi.ApiToken!, traceId, format, dashboardApi.DashboardUrl!, minimumDuration, cancellationToken));
}
else
{
return CommandResult.FromExitCode(await FetchTracesAsync(dashboardApi.BaseUrl!, dashboardApi.ApiToken!, resourceName, hasError, limit, format, dashboardApi.DashboardUrl!, search, cancellationToken));
return CommandResult.FromExitCode(await FetchTracesAsync(dashboardApi.BaseUrl!, dashboardApi.ApiToken!, resourceName, hasError, limit, format, dashboardApi.DashboardUrl!, search, minimumDuration, cancellationToken));
}
}
catch (HttpRequestException ex)
Expand All @@ -129,6 +132,7 @@ private async Task<int> FetchSingleTraceAsync(
string traceId,
OutputFormat format,
string dashboardUrl,
double? minimumDuration,
CancellationToken cancellationToken)
{
using var client = TelemetryCommandHelpers.CreateApiClient(_httpClientFactory, apiToken);
Expand All @@ -140,7 +144,7 @@ private async Task<int> FetchSingleTraceAsync(
// Pre-resolve colors so assignment is deterministic regardless of data order
TelemetryCommandHelpers.ResolveResourceColors(_resourceColorMap, allOtlpResources);

var url = DashboardUrls.TelemetryTraceDetailApiUrl(baseUrl, traceId);
var url = DashboardUrls.TelemetryTraceDetailApiUrl(baseUrl, traceId, minDurationMs: minimumDuration);

_logger.LogDebug("Fetching trace {TraceId} from {Url}", traceId, url);

Expand Down Expand Up @@ -190,6 +194,7 @@ private async Task<int> FetchTracesAsync(
OutputFormat format,
string dashboardUrl,
string? search,
double? minimumDuration,
CancellationToken cancellationToken)
{
using var client = TelemetryCommandHelpers.CreateApiClient(_httpClientFactory, apiToken);
Expand All @@ -209,7 +214,7 @@ private async Task<int> FetchTracesAsync(
// Pre-resolve colors so assignment is deterministic regardless of data order
TelemetryCommandHelpers.ResolveResourceColors(_resourceColorMap, allOtlpResources);

var url = DashboardUrls.TelemetryTracesApiUrl(baseUrl, resolvedResources, hasError: hasError, limit: limit, search: search);
var url = DashboardUrls.TelemetryTracesApiUrl(baseUrl, resolvedResources, hasError: hasError, limit: limit, search: search, minDurationMs: minimumDuration);

_logger.LogDebug("Fetching traces from {Url}", url);

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/Aspire.Cli/Resources/TelemetryCommandStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@
<data name="SearchOptionDescription" xml:space="preserve">
<value>Full-text search across telemetry text fields, such as log messages, attribute values, names, source, and IDs</value>
</data>
<data name="MinimumDurationOptionDescription" xml:space="preserve">
<value>Filter by minimum span duration in milliseconds</value>
</data>
<data name="LimitMustBePositive" xml:space="preserve">
<value>The --limit value must be a positive number.</value>
</data>
Expand Down
5 changes: 5 additions & 0 deletions src/Aspire.Cli/Resources/xlf/TelemetryCommandStrings.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Aspire.Cli/Resources/xlf/TelemetryCommandStrings.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Aspire.Cli/Resources/xlf/TelemetryCommandStrings.es.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Aspire.Cli/Resources/xlf/TelemetryCommandStrings.fr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Aspire.Cli/Resources/xlf/TelemetryCommandStrings.it.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Aspire.Cli/Resources/xlf/TelemetryCommandStrings.ja.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Aspire.Cli/Resources/xlf/TelemetryCommandStrings.ko.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Aspire.Cli/Resources/xlf/TelemetryCommandStrings.pl.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Aspire.Cli/Resources/xlf/TelemetryCommandStrings.ru.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Aspire.Cli/Resources/xlf/TelemetryCommandStrings.tr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading