diff --git a/src/AppCommon/Commands/AzureServiceBusCommand.cs b/src/AppCommon/Commands/AzureServiceBusCommand.cs index 27608dce..dac1730c 100644 --- a/src/AppCommon/Commands/AzureServiceBusCommand.cs +++ b/src/AppCommon/Commands/AzureServiceBusCommand.cs @@ -1,4 +1,5 @@ using System.CommandLine; +using Azure.Monitor.Query.Metrics.Models; using Particular.EndpointThroughputCounter.Infra; using Particular.LicensingComponent.Report; using Particular.ThroughputQuery; @@ -6,6 +7,10 @@ class AzureServiceBusCommand : BaseCommand { + // ASB keeps 90 days of data but will only return 30 days in a single query + const int MaxDaysToCollect = 90; + const int MaxDaysToCollectInOneQuery = 30; + public static Command CreateCommand() { var command = new Command("azureservicebus", "Measure endpoints and throughput using Azure Service Bus metrics"); @@ -54,12 +59,17 @@ public static Command CreateCommand() var cancellationToken = context.GetCancellationToken(); #if DEBUG + // So we don't have to keep an Azure Service Bus resource id and region in launchSettings.json + // Create a local.settings.json file with the keys below. if (resourceId == "LOAD_FROM_CONFIG") { - // So we don't have to keep an Azure Service Bus resource id in launchSettings.json - // Create a local.settings.json file with the key below. resourceId = AppConfig.Get("AZURESERVICEBUS_RESOURCE_ID"); } + + if (region == "LOAD_FROM_CONFIG") + { + region = AppConfig.Get("AZURESERVICEBUS_REGION"); + } #endif var runner = new AzureServiceBusCommand(shared, resourceId, serviceBusDomain, region, metricsDomain); @@ -85,7 +95,7 @@ protected override async Task GetData(CancellationToken cancellati try { var endTime = DateOnly.FromDateTime(DateTime.UtcNow); - var startTime = endTime.AddDays(-90); // Azure Monitor only gives a data for a month back, but we ask for more just in case + var startTime = endTime.AddDays(-MaxDaysToCollect); var results = new List(); azure.ResetConnectionQueue(); @@ -97,7 +107,7 @@ protected override async Task GetData(CancellationToken cancellati Out.Write($"Gathering metrics for queue {i + 1}/{queueNames.Length}: {queueName}"); - var metricValues = (await azure.GetMetrics(queueName, startTime, endTime, cancellationToken)).OrderBy(m => m.TimeStamp).ToArray(); + var metricValues = await GetMetricValues(queueName, startTime, endTime, cancellationToken); var maxThroughput = metricValues.Select(timeEntry => timeEntry.Total).Max(); var start = DateOnly.FromDateTime(metricValues.First().TimeStamp.UtcDateTime); @@ -159,6 +169,18 @@ protected override async Task GetData(CancellationToken cancellati } } + async Task GetMetricValues(string queueName, DateOnly start, DateOnly end, CancellationToken cancellationToken) + { + var metricValues = new List(); + + foreach (var (startTime, endTime) in ReportingWindow.GetReportingWindow(start, end, MaxDaysToCollectInOneQuery)) + { + metricValues.AddRange(await azure.GetMetrics(queueName, startTime, endTime, cancellationToken)); + } + + return [.. metricValues.OrderBy(x => x.TimeStamp)]; + } + protected override async Task GetEnvironment(CancellationToken cancellationToken = default) { Out.WriteLine($"Getting data from {azure.FullyQualifiedNamespace}..."); diff --git a/src/AppCommon/Infra/ReportingWindow.cs b/src/AppCommon/Infra/ReportingWindow.cs new file mode 100644 index 00000000..a63ec08a --- /dev/null +++ b/src/AppCommon/Infra/ReportingWindow.cs @@ -0,0 +1,17 @@ +public static class ReportingWindow +{ + public static IEnumerable<(DateOnly Start, DateOnly End)> GetReportingWindow(DateOnly startDate, DateOnly endDate, int maxDaysPerPeriod) + { + DateOnly currentStart = startDate; + while (currentStart <= endDate) + { + DateOnly currentEnd = currentStart.AddDays(maxDaysPerPeriod); + if (currentEnd > endDate) + { + currentEnd = endDate; + } + yield return (currentStart, currentEnd); + currentStart = currentEnd.AddDays(1); + } + } +} \ No newline at end of file diff --git a/src/Tool/Properties/launchSettings.json b/src/Tool/Properties/launchSettings.json index 235cda47..16bb22e0 100644 --- a/src/Tool/Properties/launchSettings.json +++ b/src/Tool/Properties/launchSettings.json @@ -30,7 +30,7 @@ }, "ThroughputTool-ASB": { "commandName": "Project", - "commandLineArgs": "azureservicebus --resourceId LOAD_FROM_CONFIG --queueNameMasks Samples --customerName \"Particular Software\" --unattended", + "commandLineArgs": "azureservicebus --resourceId LOAD_FROM_CONFIG --region LOAD_FROM_CONFIG --queueNameMasks Samples --customerName \"Particular Software\" --unattended", "environmentVariables": { "IS_DEVELOPMENT": "true" }