|  | 
| 8 | 8 | using System.Threading.Tasks; | 
| 9 | 9 | using Azure.Identity; | 
| 10 | 10 | using Azure.Storage.Files.DataLake; | 
|  | 11 | +using Microsoft.Extensions.AI.Evaluation.Console.Telemetry; | 
| 11 | 12 | using Microsoft.Extensions.AI.Evaluation.Console.Utilities; | 
| 12 | 13 | using Microsoft.Extensions.AI.Evaluation.Reporting; | 
| 13 | 14 | using Microsoft.Extensions.AI.Evaluation.Reporting.Storage; | 
| 14 | 15 | using Microsoft.Extensions.Logging; | 
| 15 | 16 | 
 | 
| 16 | 17 | namespace Microsoft.Extensions.AI.Evaluation.Console.Commands; | 
| 17 | 18 | 
 | 
| 18 |  | -internal sealed class CleanResultsCommand(ILogger logger) | 
|  | 19 | +internal sealed class CleanResultsCommand(ILogger logger, TelemetryHelper telemetryHelper) | 
| 19 | 20 | { | 
| 20 | 21 |     internal async Task<int> InvokeAsync( | 
| 21 | 22 |         DirectoryInfo? storageRootDir, | 
| 22 | 23 |         Uri? endpointUri, | 
| 23 | 24 |         int lastN, | 
| 24 | 25 |         CancellationToken cancellationToken = default) | 
| 25 | 26 |     { | 
| 26 |  | -        IEvaluationResultStore resultStore; | 
| 27 |  | - | 
| 28 |  | -        if (storageRootDir is not null) | 
| 29 |  | -        { | 
| 30 |  | -            string storageRootPath = storageRootDir.FullName; | 
| 31 |  | -            logger.LogInformation("Storage root path: {storageRootPath}", storageRootPath); | 
|  | 27 | +        var telemetryProperties = | 
|  | 28 | +            new Dictionary<string, string> | 
|  | 29 | +            { | 
|  | 30 | +                [TelemetryConstants.PropertyNames.LastN] = lastN.ToTelemetryPropertyValue() | 
|  | 31 | +            }; | 
| 32 | 32 | 
 | 
| 33 |  | -            resultStore = new DiskBasedResultStore(storageRootPath); | 
| 34 |  | -        } | 
| 35 |  | -        else if (endpointUri is not null) | 
| 36 |  | -        { | 
| 37 |  | -            logger.LogInformation("Azure Storage endpoint: {endpointUri}", endpointUri); | 
|  | 33 | +        await logger.ExecuteWithCatchAsync( | 
|  | 34 | +            operation: () => | 
|  | 35 | +                telemetryHelper.ReportOperationAsync( | 
|  | 36 | +                    operationName: TelemetryConstants.EventNames.CleanResultsCommand, | 
|  | 37 | +                    operation: async ValueTask () => | 
|  | 38 | +                    { | 
|  | 39 | +                        IEvaluationResultStore resultStore; | 
| 38 | 40 | 
 | 
| 39 |  | -            var fsClient = new DataLakeDirectoryClient(endpointUri, new DefaultAzureCredential()); | 
| 40 |  | -            resultStore = new AzureStorageResultStore(fsClient); | 
| 41 |  | -        } | 
| 42 |  | -        else | 
| 43 |  | -        { | 
| 44 |  | -            throw new InvalidOperationException("Either --path or --endpoint must be specified"); | 
| 45 |  | -        } | 
|  | 41 | +                        if (storageRootDir is not null) | 
|  | 42 | +                        { | 
|  | 43 | +                            string storageRootPath = storageRootDir.FullName; | 
|  | 44 | +                            logger.LogInformation("Storage root path: {storageRootPath}", storageRootPath); | 
| 46 | 45 | 
 | 
| 47 |  | -        await logger.ExecuteWithCatchAsync( | 
| 48 |  | -            async ValueTask () => | 
| 49 |  | -            { | 
| 50 |  | -                if (lastN is 0) | 
| 51 |  | -                { | 
| 52 |  | -                    logger.LogInformation("Deleting all results..."); | 
|  | 46 | +                            resultStore = new DiskBasedResultStore(storageRootPath); | 
| 53 | 47 | 
 | 
| 54 |  | -                    await resultStore.DeleteResultsAsync(cancellationToken: cancellationToken).ConfigureAwait(false); | 
| 55 |  | -                } | 
| 56 |  | -                else | 
| 57 |  | -                { | 
| 58 |  | -                    logger.LogInformation("Deleting all results except the {lastN} most recent ones...", lastN); | 
|  | 48 | +                            telemetryProperties[TelemetryConstants.PropertyNames.StorageType] = | 
|  | 49 | +                                TelemetryConstants.PropertyValues.StorageTypeDisk; | 
|  | 50 | +                        } | 
|  | 51 | +                        else if (endpointUri is not null) | 
|  | 52 | +                        { | 
|  | 53 | +                            logger.LogInformation("Azure Storage endpoint: {endpointUri}", endpointUri); | 
| 59 | 54 | 
 | 
| 60 |  | -                    HashSet<string> toPreserve = []; | 
|  | 55 | +                            var fsClient = new DataLakeDirectoryClient(endpointUri, new DefaultAzureCredential()); | 
|  | 56 | +                            resultStore = new AzureStorageResultStore(fsClient); | 
| 61 | 57 | 
 | 
| 62 |  | -                    await foreach (string executionName in | 
| 63 |  | -                        resultStore.GetLatestExecutionNamesAsync(lastN, cancellationToken).ConfigureAwait(false)) | 
| 64 |  | -                    { | 
| 65 |  | -                        _ = toPreserve.Add(executionName); | 
| 66 |  | -                    } | 
|  | 58 | +                            telemetryProperties[TelemetryConstants.PropertyNames.StorageType] = | 
|  | 59 | +                                TelemetryConstants.PropertyValues.StorageTypeAzure; | 
|  | 60 | +                        } | 
|  | 61 | +                        else | 
|  | 62 | +                        { | 
|  | 63 | +                            throw new InvalidOperationException("Either --path or --endpoint must be specified"); | 
|  | 64 | +                        } | 
| 67 | 65 | 
 | 
| 68 |  | -                    await foreach (string executionName in | 
| 69 |  | -                        resultStore.GetLatestExecutionNamesAsync( | 
| 70 |  | -                            cancellationToken: cancellationToken).ConfigureAwait(false)) | 
| 71 |  | -                    { | 
| 72 |  | -                        if (!toPreserve.Contains(executionName)) | 
|  | 66 | +                        if (lastN is 0) | 
| 73 | 67 |                         { | 
|  | 68 | +                            logger.LogInformation("Deleting all results..."); | 
|  | 69 | + | 
| 74 | 70 |                             await resultStore.DeleteResultsAsync( | 
| 75 |  | -                                executionName, | 
| 76 | 71 |                                 cancellationToken: cancellationToken).ConfigureAwait(false); | 
| 77 | 72 |                         } | 
| 78 |  | -                    } | 
| 79 |  | -                } | 
| 80 |  | -            }).ConfigureAwait(false); | 
|  | 73 | +                        else | 
|  | 74 | +                        { | 
|  | 75 | +                            logger.LogInformation( | 
|  | 76 | +                                "Deleting all results except the {lastN} most recent ones...", | 
|  | 77 | +                                lastN); | 
|  | 78 | + | 
|  | 79 | +                            HashSet<string> toPreserve = []; | 
|  | 80 | + | 
|  | 81 | +                            await foreach (string executionName in | 
|  | 82 | +                                resultStore.GetLatestExecutionNamesAsync( | 
|  | 83 | +                                    lastN, | 
|  | 84 | +                                    cancellationToken).ConfigureAwait(false)) | 
|  | 85 | +                            { | 
|  | 86 | +                                _ = toPreserve.Add(executionName); | 
|  | 87 | +                            } | 
|  | 88 | + | 
|  | 89 | +                            await foreach (string executionName in | 
|  | 90 | +                                resultStore.GetLatestExecutionNamesAsync( | 
|  | 91 | +                                    cancellationToken: cancellationToken).ConfigureAwait(false)) | 
|  | 92 | +                            { | 
|  | 93 | +                                if (!toPreserve.Contains(executionName)) | 
|  | 94 | +                                { | 
|  | 95 | +                                    await resultStore.DeleteResultsAsync( | 
|  | 96 | +                                        executionName, | 
|  | 97 | +                                        cancellationToken: cancellationToken).ConfigureAwait(false); | 
|  | 98 | +                                } | 
|  | 99 | +                            } | 
|  | 100 | +                        } | 
|  | 101 | +                    }, | 
|  | 102 | +                    properties: telemetryProperties)).ConfigureAwait(false); | 
| 81 | 103 | 
 | 
| 82 | 104 |         return 0; | 
| 83 | 105 |     } | 
|  | 
0 commit comments