diff --git a/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ToolLoading/CommandFactoryToolLoader.cs b/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ToolLoading/CommandFactoryToolLoader.cs index 8c6cd61f74..817c581b75 100644 --- a/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ToolLoading/CommandFactoryToolLoader.cs +++ b/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ToolLoading/CommandFactoryToolLoader.cs @@ -215,11 +215,7 @@ public override async ValueTask CallToolHandler(RequestContext IBaseCommand.ExecuteAsync(CommandContext context, Pa protected virtual void HandleException(CommandContext context, Exception ex) { - context.Activity?.SetStatus(ActivityStatusCode.Error) - ?.SetTag(TagName.ExceptionType, ex.GetType().ToString()) - ?.SetTag(TagName.ExceptionStackTrace, ex.StackTrace); + context.SetTelemetryStatus(ActivityStatusCode.Error) + .SetTelemetryTag(TagName.ExceptionType, ex.GetType().ToString()) + .SetTelemetryTag(TagName.ExceptionStackTrace, ex.StackTrace); var response = context.Response; @@ -134,7 +134,7 @@ protected virtual void HandleException(CommandContext context, Exception ex) // Include the command validation exception message as it should be safe. Requires custom validators to // exclude any sensitive information from their error messages. - context.Activity?.SetTag(TagName.ExceptionMessage, response.Message); + context.SetTelemetryTag(TagName.ExceptionMessage, response.Message); response.Results = null; return; } @@ -160,7 +160,7 @@ protected virtual void HandleException(CommandContext context, Exception ex) exceptionDetails.Add("CorrelationId", msalClientException.CorrelationId); } - context.Activity?.SetTag(TagName.ExceptionMessage, exceptionDetails); + context.SetTelemetryTag(TagName.ExceptionMessage, exceptionDetails); var result = new ExceptionResult( Message: ex.Message ?? string.Empty, diff --git a/core/Microsoft.Mcp.Core/src/Models/Command/CommandContext.cs b/core/Microsoft.Mcp.Core/src/Models/Command/CommandContext.cs index e51fb4960f..c463871888 100644 --- a/core/Microsoft.Mcp.Core/src/Models/Command/CommandContext.cs +++ b/core/Microsoft.Mcp.Core/src/Models/Command/CommandContext.cs @@ -21,7 +21,7 @@ public class CommandContext /// /// Current telemetry context if there is one available. /// - public Activity? Activity { get; } + private Activity? _activity { get; } /// /// The MCP server handling the current tool call. Used by commands that need to send @@ -49,11 +49,47 @@ public class CommandContext /// public CommandContext(Activity? activity = default) { - Activity = activity; + _activity = activity; Response = new CommandResponse { Status = HttpStatusCode.OK, Message = "Success" }; } + + /// + /// Adds a telemetry tag to the current activity if one is available. This is a no-op if there is no current activity. + /// + /// + /// Equivalent to . + /// + /// The telemetry tag name. + /// The telemetry tag value to add. + /// The CommandContext + public CommandContext AddTelemetryTag(string key, object? value) + { + _activity?.AddTag(key, value); + return this; + } + + /// + /// Set a telemetry tag to the current activity if one is available. This is a no-op if there is no current activity. + /// + /// + /// Equivalent to . + /// + /// The telemetry tag name. + /// The telemetry tag value to set. + /// The CommandContext + public CommandContext SetTelemetryTag(string key, object? value) + { + _activity?.SetTag(key, value); + return this; + } + + internal CommandContext SetTelemetryStatus(ActivityStatusCode status) + { + _activity?.SetStatus(status); + return this; + } } diff --git a/tools/Azure.Mcp.Tools.Advisor/src/Commands/Recommendation/RecommendationApplyCommand.cs b/tools/Azure.Mcp.Tools.Advisor/src/Commands/Recommendation/RecommendationApplyCommand.cs index 9edaba9fed..294661b03a 100644 --- a/tools/Azure.Mcp.Tools.Advisor/src/Commands/Recommendation/RecommendationApplyCommand.cs +++ b/tools/Azure.Mcp.Tools.Advisor/src/Commands/Recommendation/RecommendationApplyCommand.cs @@ -53,7 +53,7 @@ public override Task ExecuteAsync(CommandContext context, Recom context.Response.Results = ResponseResult.Create([recommendationApplyRules], AdvisorJsonContext.Default.ListString); - context.Activity?.AddTag("RecommendationRules_Resource", options.Resource); + context.AddTelemetryTag("RecommendationRules_Resource", options.Resource); } catch (Exception ex) { diff --git a/tools/Azure.Mcp.Tools.AppService/src/Commands/Database/DatabaseAddCommand.cs b/tools/Azure.Mcp.Tools.AppService/src/Commands/Database/DatabaseAddCommand.cs index 471a1713ae..fb04498e2b 100644 --- a/tools/Azure.Mcp.Tools.AppService/src/Commands/Database/DatabaseAddCommand.cs +++ b/tools/Azure.Mcp.Tools.AppService/src/Commands/Database/DatabaseAddCommand.cs @@ -37,7 +37,7 @@ public override async Task ExecuteAsync(CommandContext context, { try { - context.Activity?.AddTag("subscription", options.Subscription); + context.AddTelemetryTag("subscription", options.Subscription); var connectionInfo = await _appServiceService.AddDatabaseAsync( options.App, diff --git a/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Deployment/DeploymentGetCommand.cs b/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Deployment/DeploymentGetCommand.cs index cdecf5d5fd..73868f24e6 100644 --- a/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Deployment/DeploymentGetCommand.cs +++ b/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Deployment/DeploymentGetCommand.cs @@ -39,7 +39,7 @@ public override async Task ExecuteAsync(CommandContext context, { try { - context.Activity?.AddTag("subscription", options.Subscription); + context.AddTelemetryTag("subscription", options.Subscription); var deployments = await _appServiceService.GetDeploymentsAsync( options.Subscription!, diff --git a/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Diagnostic/DetectorDiagnoseCommand.cs b/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Diagnostic/DetectorDiagnoseCommand.cs index 0746636f90..6ec2c5b0f4 100644 --- a/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Diagnostic/DetectorDiagnoseCommand.cs +++ b/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Diagnostic/DetectorDiagnoseCommand.cs @@ -51,7 +51,7 @@ public override async Task ExecuteAsync(CommandContext context, { try { - context.Activity?.AddTag("subscription", options.Subscription); + context.AddTelemetryTag("subscription", options.Subscription); var diagnoses = await _appServiceService.DiagnoseDetectorAsync( options.Subscription!, diff --git a/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Diagnostic/DetectorListCommand.cs b/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Diagnostic/DetectorListCommand.cs index 957b3bbc78..5ab1b23c21 100644 --- a/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Diagnostic/DetectorListCommand.cs +++ b/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Diagnostic/DetectorListCommand.cs @@ -38,7 +38,7 @@ public override async Task ExecuteAsync(CommandContext context, { try { - context.Activity?.AddTag("subscription", options.Subscription); + context.AddTelemetryTag("subscription", options.Subscription); var detectors = await _appServiceService.ListDetectorsAsync( options.Subscription!, diff --git a/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Settings/AppSettingsGetCommand.cs b/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Settings/AppSettingsGetCommand.cs index 96a51fce17..1a35e7a0c0 100644 --- a/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Settings/AppSettingsGetCommand.cs +++ b/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Settings/AppSettingsGetCommand.cs @@ -35,7 +35,7 @@ public override async Task ExecuteAsync(CommandContext context, { try { - context.Activity?.AddTag("subscription", options.Subscription); + context.AddTelemetryTag("subscription", options.Subscription); var appSettings = await _appServiceService.GetAppSettingsAsync( options.Subscription!, diff --git a/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Settings/AppSettingsUpdateCommand.cs b/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Settings/AppSettingsUpdateCommand.cs index c4f5293c7c..62d739a96a 100644 --- a/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Settings/AppSettingsUpdateCommand.cs +++ b/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/Settings/AppSettingsUpdateCommand.cs @@ -81,7 +81,7 @@ public override async Task ExecuteAsync(CommandContext context, { try { - context.Activity?.AddTag("subscription", options.Subscription); + context.AddTelemetryTag("subscription", options.Subscription); var updateResult = await _appServiceService.UpdateAppSettingsAsync( options.Subscription!, diff --git a/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/WebappChangeStateCommand.cs b/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/WebappChangeStateCommand.cs index 11c03d216e..a2f0303d1a 100644 --- a/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/WebappChangeStateCommand.cs +++ b/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/WebappChangeStateCommand.cs @@ -86,7 +86,7 @@ public override async Task ExecuteAsync(CommandContext context, { try { - context.Activity?.AddTag("subscription", options.Subscription); + context.AddTelemetryTag("subscription", options.Subscription); var stateChange = await appServiceService.ChangeWebAppStateAsync( options.Subscription!, diff --git a/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/WebappGetCommand.cs b/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/WebappGetCommand.cs index a8112a18a3..a6becea3ab 100644 --- a/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/WebappGetCommand.cs +++ b/tools/Azure.Mcp.Tools.AppService/src/Commands/Webapp/WebappGetCommand.cs @@ -49,7 +49,7 @@ public override async Task ExecuteAsync(CommandContext context, { try { - context.Activity?.AddTag("subscription", options.Subscription); + context.AddTelemetryTag("subscription", options.Subscription); var webapps = await _appServiceService.GetWebAppsAsync( options.Subscription!, diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Backup/BackupStatusCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Backup/BackupStatusCommand.cs index 4353ec0a3a..162d8c0d11 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Backup/BackupStatusCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Backup/BackupStatusCommand.cs @@ -37,8 +37,8 @@ public sealed class BackupStatusCommand(ILogger logger, IAz public override async Task ExecuteAsync(CommandContext context, BackupStatusOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - context.Activity?.AddTag(AzureBackupTelemetryTags.OperationScope, "status-check"); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + context.AddTelemetryTag(AzureBackupTelemetryTags.OperationScope, "status-check"); try { diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/DisasterRecovery/DisasterRecoveryEnableCrrCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/DisasterRecovery/DisasterRecoveryEnableCrrCommand.cs index a1e96f95bb..5983eadab6 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/DisasterRecovery/DisasterRecoveryEnableCrrCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/DisasterRecovery/DisasterRecoveryEnableCrrCommand.cs @@ -31,8 +31,8 @@ public sealed class DisasterRecoveryEnableCrrCommand(ILogger ExecuteAsync(CommandContext context, BaseAzureBackupOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - AzureBackupTelemetryTags.AddVaultTags(context.Activity, options.VaultType); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + AzureBackupTelemetryTags.AddVaultTags(context, options.VaultType); try { diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Governance/GovernanceFindUnprotectedCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Governance/GovernanceFindUnprotectedCommand.cs index 06226d23ff..4d01d355c9 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Governance/GovernanceFindUnprotectedCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Governance/GovernanceFindUnprotectedCommand.cs @@ -56,8 +56,8 @@ public sealed class GovernanceFindUnprotectedCommand(ILogger ExecuteAsync(CommandContext context, GovernanceFindUnprotectedOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - context.Activity?.AddTag(AzureBackupTelemetryTags.OperationScope, "scan"); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + context.AddTelemetryTag(AzureBackupTelemetryTags.OperationScope, "scan"); try { diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Governance/GovernanceImmutabilityCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Governance/GovernanceImmutabilityCommand.cs index aada2ea21d..568aa46399 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Governance/GovernanceImmutabilityCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Governance/GovernanceImmutabilityCommand.cs @@ -47,8 +47,8 @@ public override void ValidateOptions(GovernanceImmutabilityOptions options, Vali public override async Task ExecuteAsync(CommandContext context, GovernanceImmutabilityOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - AzureBackupTelemetryTags.AddVaultTags(context.Activity, options.VaultType); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + AzureBackupTelemetryTags.AddVaultTags(context, options.VaultType); try { diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Governance/GovernanceSoftDeleteCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Governance/GovernanceSoftDeleteCommand.cs index 25e6ed795b..3a2c0b4716 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Governance/GovernanceSoftDeleteCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Governance/GovernanceSoftDeleteCommand.cs @@ -54,8 +54,8 @@ public override void ValidateOptions(GovernanceSoftDeleteOptions options, Valida public override async Task ExecuteAsync(CommandContext context, GovernanceSoftDeleteOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - AzureBackupTelemetryTags.AddVaultTags(context.Activity, options.VaultType); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + AzureBackupTelemetryTags.AddVaultTags(context, options.VaultType); try { diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Job/JobGetCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Job/JobGetCommand.cs index b38a5a0d63..808dc7398e 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Job/JobGetCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Job/JobGetCommand.cs @@ -39,9 +39,9 @@ public sealed class JobGetCommand(ILogger logger, IAzureBackupSer public override async Task ExecuteAsync(CommandContext context, JobGetOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - AzureBackupTelemetryTags.AddVaultTags(context.Activity, options.VaultType); - context.Activity?.AddTag(AzureBackupTelemetryTags.OperationScope, string.IsNullOrEmpty(options.Job) ? "list" : "single"); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + AzureBackupTelemetryTags.AddVaultTags(context, options.VaultType); + context.AddTelemetryTag(AzureBackupTelemetryTags.OperationScope, string.IsNullOrEmpty(options.Job) ? "list" : "single"); try { diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Policy/PolicyCreateCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Policy/PolicyCreateCommand.cs index ca6651f8a6..6b595d4d17 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Policy/PolicyCreateCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Policy/PolicyCreateCommand.cs @@ -31,8 +31,8 @@ public sealed class PolicyCreateCommand(ILogger logger, IAz public override async Task ExecuteAsync(CommandContext context, PolicyCreateOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - AzureBackupTelemetryTags.AddVaultAndWorkloadTags(context.Activity, options.VaultType, options.WorkloadType); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + AzureBackupTelemetryTags.AddVaultAndWorkloadTags(context, options.VaultType, options.WorkloadType); var validation = Services.Policy.PolicyCreateValidator.Validate(options); if (!validation.IsValid) diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Policy/PolicyGetCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Policy/PolicyGetCommand.cs index 2d5e60a325..3cd09e49fb 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Policy/PolicyGetCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Policy/PolicyGetCommand.cs @@ -39,9 +39,9 @@ public sealed class PolicyGetCommand(ILogger logger, IAzureBac public override async Task ExecuteAsync(CommandContext context, PolicyGetOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - AzureBackupTelemetryTags.AddVaultTags(context.Activity, options.VaultType); - context.Activity?.AddTag(AzureBackupTelemetryTags.OperationScope, string.IsNullOrEmpty(options.Policy) ? "list" : "single"); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + AzureBackupTelemetryTags.AddVaultTags(context, options.VaultType); + context.AddTelemetryTag(AzureBackupTelemetryTags.OperationScope, string.IsNullOrEmpty(options.Policy) ? "list" : "single"); try { diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Policy/PolicyUpdateCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Policy/PolicyUpdateCommand.cs index df5b5b1616..3a943bdeb3 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Policy/PolicyUpdateCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Policy/PolicyUpdateCommand.cs @@ -31,8 +31,8 @@ public sealed class PolicyUpdateCommand(ILogger logger, IAz public override async Task ExecuteAsync(CommandContext context, PolicyUpdateOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - AzureBackupTelemetryTags.AddVaultTags(context.Activity, options.VaultType); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + AzureBackupTelemetryTags.AddVaultTags(context, options.VaultType); try { diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/ProtectableItem/ProtectableItemListCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/ProtectableItem/ProtectableItemListCommand.cs index 7aeef9e61b..85d8f92b19 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/ProtectableItem/ProtectableItemListCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/ProtectableItem/ProtectableItemListCommand.cs @@ -53,8 +53,8 @@ public override void ValidateOptions(ProtectableItemListOptions options, Validat public override async Task ExecuteAsync(CommandContext context, ProtectableItemListOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - AzureBackupTelemetryTags.AddVaultAndWorkloadTags(context.Activity, options.VaultType ?? "rsv", options.WorkloadType); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + AzureBackupTelemetryTags.AddVaultAndWorkloadTags(context, options.VaultType ?? "rsv", options.WorkloadType); try { diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/ProtectedItem/ProtectedItemGetCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/ProtectedItem/ProtectedItemGetCommand.cs index b678a891cd..355c7a5714 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/ProtectedItem/ProtectedItemGetCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/ProtectedItem/ProtectedItemGetCommand.cs @@ -41,9 +41,9 @@ public sealed class ProtectedItemGetCommand(ILogger log public override async Task ExecuteAsync(CommandContext context, BaseProtectedItemOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - AzureBackupTelemetryTags.AddVaultTags(context.Activity, options.VaultType); - context.Activity?.AddTag(AzureBackupTelemetryTags.OperationScope, string.IsNullOrEmpty(options.ProtectedItem) ? "list" : "single"); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + AzureBackupTelemetryTags.AddVaultTags(context, options.VaultType); + context.AddTelemetryTag(AzureBackupTelemetryTags.OperationScope, string.IsNullOrEmpty(options.ProtectedItem) ? "list" : "single"); try { diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/ProtectedItem/ProtectedItemProtectCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/ProtectedItem/ProtectedItemProtectCommand.cs index 1f5c6795a6..1eb84ef689 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/ProtectedItem/ProtectedItemProtectCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/ProtectedItem/ProtectedItemProtectCommand.cs @@ -89,9 +89,9 @@ public override void ValidateOptions(ProtectedItemProtectOptions options, Valida public override async Task ExecuteAsync(CommandContext context, ProtectedItemProtectOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - AzureBackupTelemetryTags.AddVaultTags(context.Activity, options.VaultType); - context.Activity?.AddTag(AzureBackupTelemetryTags.DatasourceType, AzureBackupTelemetryTags.NormalizeWorkloadType(options.DatasourceType)); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + AzureBackupTelemetryTags.AddVaultTags(context, options.VaultType); + context.AddTelemetryTag(AzureBackupTelemetryTags.DatasourceType, AzureBackupTelemetryTags.NormalizeWorkloadType(options.DatasourceType)); try { diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/ProtectedItem/ProtectedItemUndeleteCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/ProtectedItem/ProtectedItemUndeleteCommand.cs index cd9c973fd0..4d5be47d2d 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/ProtectedItem/ProtectedItemUndeleteCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/ProtectedItem/ProtectedItemUndeleteCommand.cs @@ -38,8 +38,8 @@ public sealed class ProtectedItemUndeleteCommand(ILogger ExecuteAsync(CommandContext context, ProtectedItemUndeleteOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - AzureBackupTelemetryTags.AddVaultTags(context.Activity, options.VaultType); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + AzureBackupTelemetryTags.AddVaultTags(context, options.VaultType); try { diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/RecoveryPoint/RecoveryPointGetCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/RecoveryPoint/RecoveryPointGetCommand.cs index bc52306bdb..4d91390e34 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/RecoveryPoint/RecoveryPointGetCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/RecoveryPoint/RecoveryPointGetCommand.cs @@ -39,9 +39,9 @@ public sealed class RecoveryPointGetCommand(ILogger log public override async Task ExecuteAsync(CommandContext context, RecoveryPointGetOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - AzureBackupTelemetryTags.AddVaultTags(context.Activity, options.VaultType); - context.Activity?.AddTag(AzureBackupTelemetryTags.OperationScope, string.IsNullOrEmpty(options.RecoveryPoint) ? "list" : "single"); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + AzureBackupTelemetryTags.AddVaultTags(context, options.VaultType); + context.AddTelemetryTag(AzureBackupTelemetryTags.OperationScope, string.IsNullOrEmpty(options.RecoveryPoint) ? "list" : "single"); try { diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Security/SecurityConfigureEncryptionCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Security/SecurityConfigureEncryptionCommand.cs index 03d1a53a21..9d9c99fd2f 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Security/SecurityConfigureEncryptionCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Security/SecurityConfigureEncryptionCommand.cs @@ -82,8 +82,8 @@ public override void ValidateOptions(SecurityConfigureEncryptionOptions options, public override async Task ExecuteAsync(CommandContext context, SecurityConfigureEncryptionOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - AzureBackupTelemetryTags.AddVaultTags(context.Activity, options.VaultType); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + AzureBackupTelemetryTags.AddVaultTags(context, options.VaultType); _lastVaultType = options.VaultType; try diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Security/SecurityConfigureMuaCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Security/SecurityConfigureMuaCommand.cs index 1e3e32e97d..772c9244d2 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Security/SecurityConfigureMuaCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Security/SecurityConfigureMuaCommand.cs @@ -48,8 +48,8 @@ public override void ValidateOptions(SecurityConfigureMuaOptions options, Valida public override async Task ExecuteAsync(CommandContext context, SecurityConfigureMuaOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - AzureBackupTelemetryTags.AddVaultTags(context.Activity, options.VaultType); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + AzureBackupTelemetryTags.AddVaultTags(context, options.VaultType); try { diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Vault/VaultCreateCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Vault/VaultCreateCommand.cs index 26800d8742..a21dd765eb 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Vault/VaultCreateCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Vault/VaultCreateCommand.cs @@ -58,8 +58,8 @@ public override void ValidateOptions(VaultCreateOptions options, ValidationResul public override async Task ExecuteAsync(CommandContext context, VaultCreateOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - AzureBackupTelemetryTags.AddVaultTags(context.Activity, options.VaultType); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + AzureBackupTelemetryTags.AddVaultTags(context, options.VaultType); try { diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Vault/VaultGetCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Vault/VaultGetCommand.cs index 61580c66ca..ee2fcd25a4 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Vault/VaultGetCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Vault/VaultGetCommand.cs @@ -59,9 +59,9 @@ public override void ValidateOptions(VaultGetOptions options, ValidationResult v public override async Task ExecuteAsync(CommandContext context, VaultGetOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - AzureBackupTelemetryTags.AddVaultTags(context.Activity, options.VaultType); - context.Activity?.AddTag(AzureBackupTelemetryTags.OperationScope, string.IsNullOrEmpty(options.Vault) ? "list" : "single"); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + AzureBackupTelemetryTags.AddVaultTags(context, options.VaultType); + context.AddTelemetryTag(AzureBackupTelemetryTags.OperationScope, string.IsNullOrEmpty(options.Vault) ? "list" : "single"); try { diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Vault/VaultUpdateCommand.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Vault/VaultUpdateCommand.cs index cd28049bce..7fd726397c 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Vault/VaultUpdateCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Commands/Vault/VaultUpdateCommand.cs @@ -67,8 +67,8 @@ public override void ValidateOptions(VaultUpdateOptions options, ValidationResul public override async Task ExecuteAsync(CommandContext context, VaultUpdateOptions options, CancellationToken cancellationToken) { - AzureBackupTelemetryTags.AddSubscriptionTag(context.Activity, options.Subscription); - AzureBackupTelemetryTags.AddVaultTags(context.Activity, options.VaultType); + AzureBackupTelemetryTags.AddSubscriptionTag(context, options.Subscription); + AzureBackupTelemetryTags.AddVaultTags(context, options.VaultType); try { diff --git a/tools/Azure.Mcp.Tools.AzureBackup/src/Models/AzureBackupTelemetryTags.cs b/tools/Azure.Mcp.Tools.AzureBackup/src/Models/AzureBackupTelemetryTags.cs index 01608e9506..967f0fb1b7 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/src/Models/AzureBackupTelemetryTags.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/src/Models/AzureBackupTelemetryTags.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -using System.Diagnostics; +using Microsoft.Mcp.Core.Models.Command; namespace Azure.Mcp.Tools.AzureBackup.Models; @@ -22,17 +22,17 @@ public static class AzureBackupTelemetryTags public const string SubscriptionGuid = "AzSubscriptionGuid"; /// - /// Adds the AzSubscriptionGuid tag to the activity. Matches McpRuntime.CallToolHandler + /// Adds the AzSubscriptionGuid tag to the context. Matches McpRuntime.CallToolHandler /// behavior by emitting any non-null subscription value (including empty string). /// - public static void AddSubscriptionTag(Activity? activity, string? subscription) + public static void AddSubscriptionTag(CommandContext context, string? subscription) { - if (activity is null || subscription is null) + if (subscription is null) { return; } - activity.SetTag(SubscriptionGuid, subscription); + context.SetTelemetryTag(SubscriptionGuid, subscription); } /// @@ -50,19 +50,19 @@ public static string NormalizeWorkloadType(string? workloadType) => string.IsNullOrWhiteSpace(workloadType) ? "unspecified" : workloadType.ToLowerInvariant(); /// - /// Adds a normalized vault type tag to the activity. + /// Adds a normalized vault type tag to the context. /// - public static void AddVaultTags(Activity? activity, string? vaultType) + public static void AddVaultTags(CommandContext context, string? vaultType) { - activity?.AddTag(VaultType, NormalizeVaultType(vaultType)); + context.AddTelemetryTag(VaultType, NormalizeVaultType(vaultType)); } /// - /// Adds normalized vault type and workload type tags to the activity. + /// Adds normalized vault type and workload type tags to the context. /// - public static void AddVaultAndWorkloadTags(Activity? activity, string? vaultType, string? workloadType) + public static void AddVaultAndWorkloadTags(CommandContext context, string? vaultType, string? workloadType) { - activity?.AddTag(VaultType, NormalizeVaultType(vaultType)); - activity?.AddTag(WorkloadType, NormalizeWorkloadType(workloadType)); + context.AddTelemetryTag(VaultType, NormalizeVaultType(vaultType)) + .AddTelemetryTag(WorkloadType, NormalizeWorkloadType(workloadType)); } } diff --git a/tools/Azure.Mcp.Tools.AzureBackup/tests/Azure.Mcp.Tools.AzureBackup.Tests/Models/AzureBackupTelemetryTagsTests.cs b/tools/Azure.Mcp.Tools.AzureBackup/tests/Azure.Mcp.Tools.AzureBackup.Tests/Models/AzureBackupTelemetryTagsTests.cs index 95a339eafa..a05193dcb8 100644 --- a/tools/Azure.Mcp.Tools.AzureBackup/tests/Azure.Mcp.Tools.AzureBackup.Tests/Models/AzureBackupTelemetryTagsTests.cs +++ b/tools/Azure.Mcp.Tools.AzureBackup/tests/Azure.Mcp.Tools.AzureBackup.Tests/Models/AzureBackupTelemetryTagsTests.cs @@ -36,7 +36,7 @@ public void NormalizeWorkloadType_ReturnsExpectedValue(string? input, string exp [Fact] public void AddVaultTags_NullActivity_DoesNotThrow() { - AzureBackupTelemetryTags.AddVaultTags(null, "rsv"); + AzureBackupTelemetryTags.AddVaultTags(new(null), "rsv"); } [Fact] @@ -53,7 +53,7 @@ public void AddVaultTags_NullVaultType_SetsAutoTag() using var activity = source.StartActivity("test-op"); Assert.NotNull(activity); - AzureBackupTelemetryTags.AddVaultTags(activity, null); + AzureBackupTelemetryTags.AddVaultTags(new(activity), null); var tag = activity.GetTagItem(AzureBackupTelemetryTags.VaultType); Assert.Equal("auto", tag); @@ -73,7 +73,7 @@ public void AddVaultTags_WithVaultType_SetsNormalizedTag() using var activity = source.StartActivity("test-op"); Assert.NotNull(activity); - AzureBackupTelemetryTags.AddVaultTags(activity, "RSV"); + AzureBackupTelemetryTags.AddVaultTags(new(activity), "RSV"); var tag = activity.GetTagItem(AzureBackupTelemetryTags.VaultType); Assert.Equal("rsv", tag); @@ -93,7 +93,7 @@ public void AddVaultAndWorkloadTags_SetsAllTags() using var activity = source.StartActivity("test-op"); Assert.NotNull(activity); - AzureBackupTelemetryTags.AddVaultAndWorkloadTags(activity, null, null); + AzureBackupTelemetryTags.AddVaultAndWorkloadTags(new(activity), null, null); Assert.Equal("auto", activity.GetTagItem(AzureBackupTelemetryTags.VaultType)); Assert.Equal("unspecified", activity.GetTagItem(AzureBackupTelemetryTags.WorkloadType)); @@ -118,7 +118,7 @@ public void SubscriptionGuid_MatchesGlobalAzureTagName() [Fact] public void AddSubscriptionTag_NullActivity_DoesNotThrow() { - AzureBackupTelemetryTags.AddSubscriptionTag(null, "00000000-0000-0000-0000-000000000000"); + AzureBackupTelemetryTags.AddSubscriptionTag(new(null), "00000000-0000-0000-0000-000000000000"); } [Fact] @@ -135,7 +135,7 @@ public void AddSubscriptionTag_NullSubscription_DoesNotEmitTag() using var activity = source.StartActivity("test-op"); Assert.NotNull(activity); - AzureBackupTelemetryTags.AddSubscriptionTag(activity, null); + AzureBackupTelemetryTags.AddSubscriptionTag(new(activity), null); Assert.Null(activity.GetTagItem(AzureBackupTelemetryTags.SubscriptionGuid)); } @@ -157,7 +157,7 @@ public void AddSubscriptionTag_NonNullValue_EmitsTag(string subscription) using var activity = source.StartActivity("test-op"); Assert.NotNull(activity); - AzureBackupTelemetryTags.AddSubscriptionTag(activity, subscription); + AzureBackupTelemetryTags.AddSubscriptionTag(new(activity), subscription); Assert.Equal(subscription, activity.GetTagItem(AzureBackupTelemetryTags.SubscriptionGuid)); } diff --git a/tools/Azure.Mcp.Tools.AzureBestPractices/src/Commands/BestPracticesCommand.cs b/tools/Azure.Mcp.Tools.AzureBestPractices/src/Commands/BestPracticesCommand.cs index 0e73a485d2..f47dcbbfb4 100644 --- a/tools/Azure.Mcp.Tools.AzureBestPractices/src/Commands/BestPracticesCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureBestPractices/src/Commands/BestPracticesCommand.cs @@ -80,8 +80,8 @@ public override Task ExecuteAsync(CommandContext context, BestP context.Response.Results = ResponseResult.Create([bestPractices], AzureBestPracticesJsonContext.Default.ListString); context.Response.Message = string.Empty; - context.Activity?.AddTag("BestPractices_Resource", options.Resource); - context.Activity?.AddTag("BestPractices_Action", options.Action); + context.AddTelemetryTag("BestPractices_Resource", options.Resource); + context.AddTelemetryTag("BestPractices_Action", options.Action); } catch (Exception ex) { diff --git a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AvmDocumentationGetCommand.cs b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AvmDocumentationGetCommand.cs index e66f03100e..f43b7955fc 100644 --- a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AvmDocumentationGetCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AvmDocumentationGetCommand.cs @@ -50,9 +50,8 @@ public override async Task ExecuteAsync( new(options.ModuleName, options.ModuleVersion, documentation), AzureTerraformJsonContext.Default.AvmDocumentationResult); - context.Activity - ?.AddTag(AzureTerraformTelemetryTags.ToolArea, "avm") - .AddTag(AzureTerraformTelemetryTags.ModuleName, options.ModuleName); + context.AddTelemetryTag(AzureTerraformTelemetryTags.ToolArea, "avm") + .AddTelemetryTag(AzureTerraformTelemetryTags.ModuleName, options.ModuleName); } catch (Exception ex) { diff --git a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AvmModuleListCommand.cs b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AvmModuleListCommand.cs index 11f28bf5e3..97bd232ed7 100644 --- a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AvmModuleListCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AvmModuleListCommand.cs @@ -43,7 +43,7 @@ public override async Task ExecuteAsync( context.Response.Results = ResponseResult.Create(new(modules), AzureTerraformJsonContext.Default.AvmModuleListResult); - context.Activity?.AddTag(AzureTerraformTelemetryTags.ToolArea, "avm"); + context.AddTelemetryTag(AzureTerraformTelemetryTags.ToolArea, "avm"); } catch (Exception ex) { diff --git a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AvmVersionListCommand.cs b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AvmVersionListCommand.cs index 55d6e9cc60..98aeda660a 100644 --- a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AvmVersionListCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AvmVersionListCommand.cs @@ -49,9 +49,8 @@ public override async Task ExecuteAsync( new(options.ModuleName, versions), AzureTerraformJsonContext.Default.AvmVersionListResult); - context.Activity - ?.AddTag(AzureTerraformTelemetryTags.ToolArea, "avm") - .AddTag(AzureTerraformTelemetryTags.ModuleName, options.ModuleName); + context.AddTelemetryTag(AzureTerraformTelemetryTags.ToolArea, "avm") + .AddTelemetryTag(AzureTerraformTelemetryTags.ModuleName, options.ModuleName); } catch (Exception ex) { diff --git a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AzApiDocsGetCommand.cs b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AzApiDocsGetCommand.cs index f09b838f8a..29e83f4014 100644 --- a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AzApiDocsGetCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AzApiDocsGetCommand.cs @@ -65,9 +65,8 @@ public override async Task ExecuteAsync( context.Response.Results = ResponseResult.Create(result, AzureTerraformJsonContext.Default.AzApiDocsResult); - context.Activity - ?.AddTag(AzureTerraformTelemetryTags.ToolArea, "azapi") - .AddTag(AzureTerraformTelemetryTags.ResourceType, options.ResourceType); + context.AddTelemetryTag(AzureTerraformTelemetryTags.ToolArea, "azapi") + .AddTelemetryTag(AzureTerraformTelemetryTags.ResourceType, options.ResourceType); } catch (Exception ex) { diff --git a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AztfexportQueryCommand.cs b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AztfexportQueryCommand.cs index 7cd9a61148..3a197a56ec 100644 --- a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AztfexportQueryCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AztfexportQueryCommand.cs @@ -64,9 +64,8 @@ public override async Task ExecuteAsync( context.Response.Results = ResponseResult.Create(result, AzureTerraformJsonContext.Default.AztfexportCommandResult); - context.Activity - ?.AddTag(AzureTerraformTelemetryTags.ToolArea, "aztfexport") - .AddTag(AzureTerraformTelemetryTags.Provider, options.Provider ?? "azurerm"); + context.AddTelemetryTag(AzureTerraformTelemetryTags.ToolArea, "aztfexport") + .AddTelemetryTag(AzureTerraformTelemetryTags.Provider, options.Provider ?? "azurerm"); } catch (Exception ex) { diff --git a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AztfexportResourceCommand.cs b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AztfexportResourceCommand.cs index 6adee78f06..ad66706b4e 100644 --- a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AztfexportResourceCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AztfexportResourceCommand.cs @@ -63,9 +63,8 @@ public override async Task ExecuteAsync( context.Response.Results = ResponseResult.Create(result, AzureTerraformJsonContext.Default.AztfexportCommandResult); - context.Activity - ?.AddTag(AzureTerraformTelemetryTags.ToolArea, "aztfexport") - .AddTag(AzureTerraformTelemetryTags.Provider, options.Provider ?? "azurerm"); + context.AddTelemetryTag(AzureTerraformTelemetryTags.ToolArea, "aztfexport") + .AddTelemetryTag(AzureTerraformTelemetryTags.Provider, options.Provider ?? "azurerm"); } catch (Exception ex) { diff --git a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AztfexportResourceGroupCommand.cs b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AztfexportResourceGroupCommand.cs index 409aa8739c..a45ae5eee3 100644 --- a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AztfexportResourceGroupCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AztfexportResourceGroupCommand.cs @@ -63,9 +63,8 @@ public override async Task ExecuteAsync( context.Response.Results = ResponseResult.Create(result, AzureTerraformJsonContext.Default.AztfexportCommandResult); - context.Activity - ?.AddTag(AzureTerraformTelemetryTags.ToolArea, "aztfexport") - .AddTag(AzureTerraformTelemetryTags.Provider, options.Provider ?? "azurerm"); + context.AddTelemetryTag(AzureTerraformTelemetryTags.ToolArea, "aztfexport") + .AddTelemetryTag(AzureTerraformTelemetryTags.Provider, options.Provider ?? "azurerm"); } catch (Exception ex) { diff --git a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AzureRMDocsGetCommand.cs b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AzureRMDocsGetCommand.cs index 8e7f3fee3b..13d18a5e36 100644 --- a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AzureRMDocsGetCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AzureRMDocsGetCommand.cs @@ -50,9 +50,8 @@ public override async Task ExecuteAsync( context.Response.Results = ResponseResult.Create(result, AzureTerraformJsonContext.Default.AzureRMDocsResult); - context.Activity - ?.AddTag(AzureTerraformTelemetryTags.ToolArea, "azurerm") - .AddTag(AzureTerraformTelemetryTags.ResourceType, options.ResourceType); + context.AddTelemetryTag(AzureTerraformTelemetryTags.ToolArea, "azurerm") + .AddTelemetryTag(AzureTerraformTelemetryTags.ResourceType, options.ResourceType); } catch (Exception ex) { diff --git a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/Conftest/ConftestPlanValidationCommand.cs b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/Conftest/ConftestPlanValidationCommand.cs index ef66acf9a6..7c7103b007 100644 --- a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/Conftest/ConftestPlanValidationCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/Conftest/ConftestPlanValidationCommand.cs @@ -60,9 +60,8 @@ public override async Task ExecuteAsync( context.Response.Results = ResponseResult.Create(result, AzureTerraformJsonContext.Default.ConftestCommandResult); - context.Activity - ?.AddTag(AzureTerraformTelemetryTags.ToolArea, "conftest") - .AddTag(AzureTerraformTelemetryTags.PolicySet, options.PolicySet ?? "all"); + context.AddTelemetryTag(AzureTerraformTelemetryTags.ToolArea, "conftest") + .AddTelemetryTag(AzureTerraformTelemetryTags.PolicySet, options.PolicySet ?? "all"); } catch (Exception ex) { diff --git a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/Conftest/ConftestWorkspaceValidationCommand.cs b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/Conftest/ConftestWorkspaceValidationCommand.cs index ad64d3bf53..bde215230e 100644 --- a/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/Conftest/ConftestWorkspaceValidationCommand.cs +++ b/tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/Conftest/ConftestWorkspaceValidationCommand.cs @@ -61,9 +61,8 @@ public override async Task ExecuteAsync( context.Response.Results = ResponseResult.Create(result, AzureTerraformJsonContext.Default.ConftestCommandResult); - context.Activity - ?.AddTag(AzureTerraformTelemetryTags.ToolArea, "conftest") - .AddTag(AzureTerraformTelemetryTags.PolicySet, options.PolicySet ?? "all"); + context.AddTelemetryTag(AzureTerraformTelemetryTags.ToolArea, "conftest") + .AddTelemetryTag(AzureTerraformTelemetryTags.PolicySet, options.PolicySet ?? "all"); } catch (Exception ex) { diff --git a/tools/Azure.Mcp.Tools.BicepSchema/src/Commands/BicepSchemaGetCommand.cs b/tools/Azure.Mcp.Tools.BicepSchema/src/Commands/BicepSchemaGetCommand.cs index 9a92ae5289..9a9e0cdfcd 100644 --- a/tools/Azure.Mcp.Tools.BicepSchema/src/Commands/BicepSchemaGetCommand.cs +++ b/tools/Azure.Mcp.Tools.BicepSchema/src/Commands/BicepSchemaGetCommand.cs @@ -46,7 +46,7 @@ public override Task ExecuteAsync(CommandContext context, Bicep // Only log the resource type if we are able to get the schema from it. // There is a slight chance that the LLM hallucinates the resource type // parameter with value containing data that we shouldn't log. - context.Activity?.AddTag("resourceType", options.ResourceType); + context.AddTelemetryTag("resourceType", options.ResourceType); context.Response.Results = ResponseResult.Create(new(response), BicepSchemaJsonContext.Default.BicepSchemaGetCommandResult); } diff --git a/tools/Azure.Mcp.Tools.Compute/src/Commands/Vm/VmCreateCommand.cs b/tools/Azure.Mcp.Tools.Compute/src/Commands/Vm/VmCreateCommand.cs index eae7d811cb..9081c02410 100644 --- a/tools/Azure.Mcp.Tools.Compute/src/Commands/Vm/VmCreateCommand.cs +++ b/tools/Azure.Mcp.Tools.Compute/src/Commands/Vm/VmCreateCommand.cs @@ -77,7 +77,7 @@ public override async Task ExecuteAsync(CommandContext context, { try { - context.Activity?.AddTag("subscription", options.Subscription); + context.AddTelemetryTag("subscription", options.Subscription); var result = await _computeService.CreateVmAsync( options.VmName, diff --git a/tools/Azure.Mcp.Tools.Compute/src/Commands/Vm/VmDeleteCommand.cs b/tools/Azure.Mcp.Tools.Compute/src/Commands/Vm/VmDeleteCommand.cs index 86defcdd74..d569ffa805 100644 --- a/tools/Azure.Mcp.Tools.Compute/src/Commands/Vm/VmDeleteCommand.cs +++ b/tools/Azure.Mcp.Tools.Compute/src/Commands/Vm/VmDeleteCommand.cs @@ -42,7 +42,7 @@ public override async Task ExecuteAsync(CommandContext context, { try { - context.Activity?.AddTag("subscription", options.Subscription); + context.AddTelemetryTag("subscription", options.Subscription); var deleted = await _computeService.DeleteVmAsync( options.VmName, diff --git a/tools/Azure.Mcp.Tools.Compute/src/Commands/Vm/VmPowerStateCommand.cs b/tools/Azure.Mcp.Tools.Compute/src/Commands/Vm/VmPowerStateCommand.cs index f8e72c8c17..664569a3b3 100644 --- a/tools/Azure.Mcp.Tools.Compute/src/Commands/Vm/VmPowerStateCommand.cs +++ b/tools/Azure.Mcp.Tools.Compute/src/Commands/Vm/VmPowerStateCommand.cs @@ -65,7 +65,7 @@ public override async Task ExecuteAsync(CommandContext context, { try { - context.Activity?.AddTag("subscription", options.Subscription); + context.AddTelemetryTag("subscription", options.Subscription); var result = await _computeService.ChangeVmPowerStateAsync( options.VmName, diff --git a/tools/Azure.Mcp.Tools.Compute/src/Commands/Vm/VmUpdateCommand.cs b/tools/Azure.Mcp.Tools.Compute/src/Commands/Vm/VmUpdateCommand.cs index 52eb3adbfd..a2c85e67bb 100644 --- a/tools/Azure.Mcp.Tools.Compute/src/Commands/Vm/VmUpdateCommand.cs +++ b/tools/Azure.Mcp.Tools.Compute/src/Commands/Vm/VmUpdateCommand.cs @@ -58,7 +58,7 @@ public override async Task ExecuteAsync(CommandContext context, { try { - context.Activity?.AddTag("subscription", options.Subscription); + context.AddTelemetryTag("subscription", options.Subscription); var result = await _computeService.UpdateVmAsync( options.VmName!, diff --git a/tools/Azure.Mcp.Tools.Compute/src/Commands/Vmss/VmssCreateCommand.cs b/tools/Azure.Mcp.Tools.Compute/src/Commands/Vmss/VmssCreateCommand.cs index 5c3bd584a8..1d08378aff 100644 --- a/tools/Azure.Mcp.Tools.Compute/src/Commands/Vmss/VmssCreateCommand.cs +++ b/tools/Azure.Mcp.Tools.Compute/src/Commands/Vmss/VmssCreateCommand.cs @@ -79,7 +79,7 @@ public override async Task ExecuteAsync(CommandContext context, { try { - context.Activity?.AddTag("subscription", options.Subscription); + context.AddTelemetryTag("subscription", options.Subscription); var result = await _computeService.CreateVmssAsync( options.VmssName, diff --git a/tools/Azure.Mcp.Tools.Compute/src/Commands/Vmss/VmssDeleteCommand.cs b/tools/Azure.Mcp.Tools.Compute/src/Commands/Vmss/VmssDeleteCommand.cs index 9bb191e209..84cb19b2e9 100644 --- a/tools/Azure.Mcp.Tools.Compute/src/Commands/Vmss/VmssDeleteCommand.cs +++ b/tools/Azure.Mcp.Tools.Compute/src/Commands/Vmss/VmssDeleteCommand.cs @@ -40,7 +40,7 @@ public override async Task ExecuteAsync(CommandContext context, { try { - context.Activity?.AddTag("subscription", options.Subscription); + context.AddTelemetryTag("subscription", options.Subscription); var deleted = await _computeService.DeleteVmssAsync( options.VmssName, diff --git a/tools/Azure.Mcp.Tools.Compute/src/Commands/Vmss/VmssUpdateCommand.cs b/tools/Azure.Mcp.Tools.Compute/src/Commands/Vmss/VmssUpdateCommand.cs index 12e0b2ec46..450562f3a8 100644 --- a/tools/Azure.Mcp.Tools.Compute/src/Commands/Vmss/VmssUpdateCommand.cs +++ b/tools/Azure.Mcp.Tools.Compute/src/Commands/Vmss/VmssUpdateCommand.cs @@ -58,7 +58,7 @@ public override async Task ExecuteAsync(CommandContext context, { try { - context.Activity?.AddTag("subscription", options.Subscription); + context.AddTelemetryTag("subscription", options.Subscription); var result = await _computeService.UpdateVmssAsync( options.VmssName, diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Commands/Architecture/DiagramGenerateCommand.cs b/tools/Azure.Mcp.Tools.Deploy/src/Commands/Architecture/DiagramGenerateCommand.cs index eec4826bd6..ae9e545858 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Commands/Architecture/DiagramGenerateCommand.cs +++ b/tools/Azure.Mcp.Tools.Deploy/src/Commands/Architecture/DiagramGenerateCommand.cs @@ -53,10 +53,9 @@ public override Task ExecuteAsync(CommandContext context, Diagr AppTopology appTopology = JsonSerializer.Deserialize(rawMcpToolInput, DeployJsonContext.Default.AppTopology) ?? throw new ArgumentException("Failed to deserialize app topology.", nameof(rawMcpToolInput)); - context.Activity? - .AddTag(DeployTelemetryTags.ServiceCount, appTopology.Services.Length) - .AddTag(DeployTelemetryTags.ComputeHostResources, string.Join(", ", appTopology.Services.Select(s => s.AzureComputeHost))) - .AddTag(DeployTelemetryTags.BackingServiceResources, string.Join(", ", appTopology.Services.SelectMany(s => s.Dependencies).Select(d => d.ServiceType))); + context.AddTelemetryTag(DeployTelemetryTags.ServiceCount, appTopology.Services.Length) + .AddTelemetryTag(DeployTelemetryTags.ComputeHostResources, string.Join(", ", appTopology.Services.Select(s => s.AzureComputeHost))) + .AddTelemetryTag(DeployTelemetryTags.BackingServiceResources, string.Join(", ", appTopology.Services.SelectMany(s => s.Dependencies).Select(d => d.ServiceType))); _logger.LogInformation("Successfully parsed app topology with {ServiceCount} services", appTopology.Services.Length); diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Commands/Infrastructure/RulesGetCommand.cs b/tools/Azure.Mcp.Tools.Deploy/src/Commands/Infrastructure/RulesGetCommand.cs index 2efa3bc703..f93b75ea25 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Commands/Infrastructure/RulesGetCommand.cs +++ b/tools/Azure.Mcp.Tools.Deploy/src/Commands/Infrastructure/RulesGetCommand.cs @@ -29,10 +29,9 @@ public override Task ExecuteAsync(CommandContext context, Rules { try { - context.Activity? - .AddTag(DeployTelemetryTags.DeploymentTool, options.DeploymentTool) - .AddTag(DeployTelemetryTags.IacType, options.IacType) - .AddTag(DeployTelemetryTags.ComputeHostResources, options.ResourceTypes); + context.AddTelemetryTag(DeployTelemetryTags.DeploymentTool, options.DeploymentTool) + .AddTelemetryTag(DeployTelemetryTags.IacType, options.IacType) + .AddTelemetryTag(DeployTelemetryTags.ComputeHostResources, options.ResourceTypes); var resourceTypes = options.ResourceTypes?.Split(',') .Select(rt => rt.Trim().ToLowerInvariant()) diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Commands/Plan/GetCommand.cs b/tools/Azure.Mcp.Tools.Deploy/src/Commands/Plan/GetCommand.cs index 0125b30146..7c26a6f8d5 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Commands/Plan/GetCommand.cs +++ b/tools/Azure.Mcp.Tools.Deploy/src/Commands/Plan/GetCommand.cs @@ -32,13 +32,12 @@ public override Task ExecuteAsync(CommandContext context, GetOp try { var bytes = SHA256.HashData(Encoding.UTF8.GetBytes(options.ProjectName)); - context.Activity?.AddTag(DeployTelemetryTags.ProjectName, Convert.ToHexStringLower(bytes)); - context.Activity? - .AddTag(DeployTelemetryTags.ComputeHostResources, options.TargetAppService) - .AddTag(DeployTelemetryTags.DeploymentTool, options.ProvisioningTool) - .AddTag(DeployTelemetryTags.IacType, options.IacOptions ?? string.Empty) - .AddTag(DeployTelemetryTags.DeployOption, options.DeployOption ?? string.Empty) - .AddTag(DeployTelemetryTags.SourceType, options.SourceType ?? string.Empty); + context.AddTelemetryTag(DeployTelemetryTags.ProjectName, Convert.ToHexStringLower(bytes)) + .AddTelemetryTag(DeployTelemetryTags.ComputeHostResources, options.TargetAppService) + .AddTelemetryTag(DeployTelemetryTags.DeploymentTool, options.ProvisioningTool) + .AddTelemetryTag(DeployTelemetryTags.IacType, options.IacOptions ?? string.Empty) + .AddTelemetryTag(DeployTelemetryTags.DeployOption, options.DeployOption ?? string.Empty) + .AddTelemetryTag(DeployTelemetryTags.SourceType, options.SourceType ?? string.Empty); var planTemplate = DeploymentPlanTemplateUtil.GetPlanTemplate( options.ProjectName, diff --git a/tools/Azure.Mcp.Tools.Extension/src/Commands/CliGenerateCommand.cs b/tools/Azure.Mcp.Tools.Extension/src/Commands/CliGenerateCommand.cs index 7a32a789ca..5de0b132ec 100644 --- a/tools/Azure.Mcp.Tools.Extension/src/Commands/CliGenerateCommand.cs +++ b/tools/Azure.Mcp.Tools.Extension/src/Commands/CliGenerateCommand.cs @@ -45,7 +45,7 @@ public override async Task ExecuteAsync(CommandContext context, var cliType = options.CliType?.ToLowerInvariant(); // Only log the cli type when we know for sure it doesn't have private data. - context.Activity?.AddTag("cliType", cliType); + context.AddTelemetryTag("cliType", cliType); if (cliType == Constants.AzureCliType) { diff --git a/tools/Azure.Mcp.Tools.Extension/src/Commands/CliInstallCommand.cs b/tools/Azure.Mcp.Tools.Extension/src/Commands/CliInstallCommand.cs index c79360e175..e80823dd60 100644 --- a/tools/Azure.Mcp.Tools.Extension/src/Commands/CliInstallCommand.cs +++ b/tools/Azure.Mcp.Tools.Extension/src/Commands/CliInstallCommand.cs @@ -45,7 +45,7 @@ public override async Task ExecuteAsync(CommandContext context, var cliType = options.CliType.ToLowerInvariant(); // Only log the cli type when we know for sure it doesn't have private data. - context.Activity?.AddTag("cliType", cliType); + context.AddTelemetryTag("cliType", cliType); using HttpResponseMessage responseMessage = await _cliInstallService.GetCliInstallInstructions(cliType, cancellationToken); responseMessage.EnsureSuccessStatusCode(); diff --git a/tools/Azure.Mcp.Tools.Quota/src/Commands/Region/AvailabilityListCommand.cs b/tools/Azure.Mcp.Tools.Quota/src/Commands/Region/AvailabilityListCommand.cs index 7218f91948..ab1641d8a0 100644 --- a/tools/Azure.Mcp.Tools.Quota/src/Commands/Region/AvailabilityListCommand.cs +++ b/tools/Azure.Mcp.Tools.Quota/src/Commands/Region/AvailabilityListCommand.cs @@ -42,7 +42,7 @@ public override async Task ExecuteAsync(CommandContext context, { try { - context.Activity?.AddTag(QuotaTelemetryTags.ResourceTypes, options.ResourceTypes); + context.AddTelemetryTag(QuotaTelemetryTags.ResourceTypes, options.ResourceTypes); var resourceTypes = options.ResourceTypes.Split(',') .Select(rt => rt.Trim()) diff --git a/tools/Azure.Mcp.Tools.Quota/src/Commands/Usage/CheckCommand.cs b/tools/Azure.Mcp.Tools.Quota/src/Commands/Usage/CheckCommand.cs index 2cae7edfd7..86da11a7bf 100644 --- a/tools/Azure.Mcp.Tools.Quota/src/Commands/Usage/CheckCommand.cs +++ b/tools/Azure.Mcp.Tools.Quota/src/Commands/Usage/CheckCommand.cs @@ -43,9 +43,8 @@ public override async Task ExecuteAsync(CommandContext context, { try { - context.Activity? - .AddTag(QuotaTelemetryTags.Region, options.Region) - .AddTag(QuotaTelemetryTags.ResourceTypes, options.ResourceTypes); + context.AddTelemetryTag(QuotaTelemetryTags.Region, options.Region) + .AddTelemetryTag(QuotaTelemetryTags.ResourceTypes, options.ResourceTypes); var resourceTypes = options.ResourceTypes.Split(',') .Select(rt => rt.Trim()) diff --git a/tools/Azure.Mcp.Tools.WellArchitectedFramework/src/Commands/ServiceGuide/ServiceGuideGetCommand.cs b/tools/Azure.Mcp.Tools.WellArchitectedFramework/src/Commands/ServiceGuide/ServiceGuideGetCommand.cs index 4d904e85d7..3ff225bac1 100644 --- a/tools/Azure.Mcp.Tools.WellArchitectedFramework/src/Commands/ServiceGuide/ServiceGuideGetCommand.cs +++ b/tools/Azure.Mcp.Tools.WellArchitectedFramework/src/Commands/ServiceGuide/ServiceGuideGetCommand.cs @@ -35,7 +35,7 @@ public override Task ExecuteAsync( ServiceGuideGetOptions options, CancellationToken cancellationToken) { - context.Activity?.AddTag("WellArchitectedFramework_Service", options.Service); + context.AddTelemetryTag("WellArchitectedFramework_Service", options.Service); try {