Skip to content

Commit b3c636e

Browse files
authored
feat: make lookback configurable in minutes (#2685)
1 parent 4d0852c commit b3c636e

File tree

6 files changed

+89
-12
lines changed

6 files changed

+89
-12
lines changed

changelog/content/experimental/unreleased.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ version:
77
#### Scraper
88

99
- {{% tag fixed %}} Azure Monitor Scraper: batch based on aggregation in addition to existing criteria
10+
- {{% tag feature %}} Azure Monitor Scraper: make query lookback range configurable in minutes
1011

1112
#### Resource Discovery
1213

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
1-
namespace Promitor.Integrations.AzureMonitor.Configuration
1+
using System;
2+
namespace Promitor.Integrations.AzureMonitor.Configuration
23
{
34
public class AzureMonitorHistoryConfiguration
45
{
56
public int StartingFromInHours { get; set; } = 12;
7+
public TimeSpan? StartingFromOffset { get; set; }
8+
9+
public TimeSpan ResolveEffectiveStartingFrom()
10+
{
11+
return StartingFromOffset ?? TimeSpan.FromHours(StartingFromInHours);
12+
}
613
}
714
}

src/Promitor.Integrations.AzureMonitor/Extensions/AzureMonitorQueryTasks.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public static async Task<MetricResult> GetRelevantMetricSingleResource(this Metr
2020
{
2121
MetricsQueryOptions queryOptions;
2222
var querySizeLimit = metricLimit ?? Defaults.MetricDefaults.Limit;
23-
var historyStartingFromInHours = azureMonitorIntegrationConfiguration.Value.History.StartingFromInHours;
23+
var effectiveStartingFrom = azureMonitorIntegrationConfiguration.Value.History.ResolveEffectiveStartingFrom();
2424
var filter = BuildFilter(metricDimensions, metricFilter);
2525

2626
if (!string.IsNullOrEmpty(filter))
@@ -32,7 +32,7 @@ public static async Task<MetricResult> GetRelevantMetricSingleResource(this Metr
3232
Granularity = metricInterval,
3333
Filter = filter,
3434
Size = querySizeLimit,
35-
TimeRange= new QueryTimeRange(new DateTimeOffset(recordDateTime.AddHours(-historyStartingFromInHours)), new DateTimeOffset(recordDateTime))
35+
TimeRange= new QueryTimeRange(new DateTimeOffset(recordDateTime.Subtract(effectiveStartingFrom)), new DateTimeOffset(recordDateTime))
3636
};
3737
}
3838
else
@@ -43,7 +43,7 @@ public static async Task<MetricResult> GetRelevantMetricSingleResource(this Metr
4343
},
4444
Granularity = metricInterval,
4545
Size = querySizeLimit,
46-
TimeRange= new QueryTimeRange(new DateTimeOffset(recordDateTime.AddHours(-historyStartingFromInHours)), new DateTimeOffset(recordDateTime))
46+
TimeRange= new QueryTimeRange(new DateTimeOffset(recordDateTime.Subtract(effectiveStartingFrom)), new DateTimeOffset(recordDateTime))
4747
};
4848
}
4949

@@ -56,8 +56,7 @@ public static async Task<List<MetricResult>> GetRelevantMetricForResources(this
5656
{
5757
MetricsQueryResourcesOptions queryOptions;
5858
var querySizeLimit = metricLimit ?? Defaults.MetricDefaults.Limit;
59-
//var historyStartingFromInHours = azureMonitorIntegrationConfiguration.Value.History.StartingFromInHours;
60-
var historyStartingFromInHours = 2;
59+
var effectiveStartingFrom = azureMonitorIntegrationConfiguration.Value.History.ResolveEffectiveStartingFrom();
6160
var filter = BuildFilter(metricDimensions, metricFilter);
6261
List<ResourceIdentifier> resourceIdentifiers = resourceIds.Select(id => new ResourceIdentifier(id)).ToList();
6362

@@ -68,15 +67,15 @@ public static async Task<List<MetricResult>> GetRelevantMetricForResources(this
6867
Granularity = metricInterval,
6968
Filter = filter,
7069
Size = querySizeLimit,
71-
TimeRange= new QueryTimeRange(new DateTimeOffset(recordDateTime.AddHours(-historyStartingFromInHours)), new DateTimeOffset(recordDateTime))
70+
TimeRange= new QueryTimeRange(new DateTimeOffset(recordDateTime.Subtract(effectiveStartingFrom)), new DateTimeOffset(recordDateTime))
7271
};
7372
}
7473
else
7574
{
7675
queryOptions = new MetricsQueryResourcesOptions {
7776
Aggregations = { metricAggregation.ToString().ToLower() },
7877
Granularity = metricInterval,
79-
TimeRange= new QueryTimeRange(new DateTimeOffset(recordDateTime.AddHours(-historyStartingFromInHours)), new DateTimeOffset(recordDateTime))
78+
TimeRange= new QueryTimeRange(new DateTimeOffset(recordDateTime.Subtract(effectiveStartingFrom)), new DateTimeOffset(recordDateTime))
8079
};
8180
}
8281

src/Promitor.Integrations.AzureMonitor/LegacyAzureMonitorClient.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,9 @@ private MetricValue GetMostRecentMetricValue(string metricName, TimeSeriesElemen
241241
private IWithMetricsQueryExecute CreateMetricsQuery(AggregationType metricAggregation, TimeSpan metricsInterval, string metricFilter, List<string> metricDimensions,
242242
int? metricLimit, IMetricDefinition metricDefinition, DateTime recordDateTime)
243243
{
244-
var historyStartingFromInHours = _azureMonitorIntegrationConfiguration.Value.History.StartingFromInHours;
244+
var effectiveStartingFrom = _azureMonitorIntegrationConfiguration.Value.History.ResolveEffectiveStartingFrom();
245245
var metricQuery = metricDefinition.DefineQuery()
246-
.StartingFrom(recordDateTime.AddHours(-historyStartingFromInHours))
246+
.StartingFrom(recordDateTime.Subtract(effectiveStartingFrom))
247247
.EndsBefore(recordDateTime)
248248
.WithAggregation(metricAggregation.ToString())
249249
.WithInterval(metricsInterval);

src/Promitor.Tests.Unit/Configuration/RuntimeConfigurationUnitTest.cs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.ComponentModel;
1+
using System;
2+
using System.ComponentModel;
23
using System.Threading.Tasks;
34
using Microsoft.Azure.Management.ResourceManager.Fluent.Core;
45
using Microsoft.Extensions.Configuration;
@@ -96,6 +97,66 @@ public async Task RuntimeConfiguration_HasStartingFromInHoursConfiguredForAzureM
9697
Assert.Equal(expectedStartingFromInHours, runtimeConfiguration.AzureMonitor.Integration.History.StartingFromInHours);
9798
}
9899

100+
[Fact]
101+
public async Task RuntimeConfiguration_HasStartingFromOffsetConfigured_TakesPriorityOverHours()
102+
{
103+
// Arrange
104+
var expectedOffset = TimeSpan.FromMinutes(5);
105+
var configuration = await RuntimeConfigurationGenerator.WithServerConfiguration()
106+
.WithAzureMonitorIntegration(startingFromInHours: 24, startingFromOffset: expectedOffset)
107+
.GenerateAsync();
108+
109+
// Act
110+
var runtimeConfiguration = configuration.Get<ScraperRuntimeConfiguration>();
111+
112+
// Assert
113+
Assert.NotNull(runtimeConfiguration);
114+
Assert.NotNull(runtimeConfiguration.AzureMonitor);
115+
Assert.NotNull(runtimeConfiguration.AzureMonitor.Integration);
116+
Assert.NotNull(runtimeConfiguration.AzureMonitor.Integration.History);
117+
Assert.Equal(expectedOffset, runtimeConfiguration.AzureMonitor.Integration.History.StartingFromOffset);
118+
}
119+
120+
[Fact]
121+
public async Task RuntimeConfiguration_HasOnlyStartingFromOffsetConfigured_SetsOffset()
122+
{
123+
// Arrange
124+
var expectedOffset = TimeSpan.FromMinutes(15);
125+
var configuration = await RuntimeConfigurationGenerator.WithServerConfiguration()
126+
.WithAzureMonitorIntegration(startingFromInHours: null, startingFromOffset: expectedOffset)
127+
.GenerateAsync();
128+
129+
// Act
130+
var runtimeConfiguration = configuration.Get<ScraperRuntimeConfiguration>();
131+
132+
// Assert
133+
Assert.NotNull(runtimeConfiguration);
134+
Assert.NotNull(runtimeConfiguration.AzureMonitor);
135+
Assert.NotNull(runtimeConfiguration.AzureMonitor.Integration);
136+
Assert.NotNull(runtimeConfiguration.AzureMonitor.Integration.History);
137+
Assert.Equal(expectedOffset, runtimeConfiguration.AzureMonitor.Integration.History.StartingFromOffset);
138+
}
139+
140+
[Fact]
141+
public async Task RuntimeConfiguration_HasNoStartingFromOffsetConfigured_FallsBackToStartingFromInHoursDefault()
142+
{
143+
// Arrange
144+
var configuration = await RuntimeConfigurationGenerator.WithServerConfiguration()
145+
.WithAzureMonitorIntegration(startingFromInHours: null, startingFromOffset: null)
146+
.GenerateAsync();
147+
148+
// Act
149+
var runtimeConfiguration = configuration.Get<ScraperRuntimeConfiguration>();
150+
151+
// Assert
152+
Assert.NotNull(runtimeConfiguration);
153+
Assert.NotNull(runtimeConfiguration.AzureMonitor);
154+
Assert.NotNull(runtimeConfiguration.AzureMonitor.Integration);
155+
Assert.NotNull(runtimeConfiguration.AzureMonitor.Integration.History);
156+
Assert.Equal(12, runtimeConfiguration.AzureMonitor.Integration.History.StartingFromInHours);
157+
Assert.Null(runtimeConfiguration.AzureMonitor.Integration.History.StartingFromOffset);
158+
}
159+
99160
[Fact]
100161
public async Task RuntimeConfiguration_HasNoNewSdkFlagForAzureMonitorIntegration_DefaultsToTrue()
101162
{

src/Promitor.Tests.Unit/Generators/Config/RuntimeConfigurationGenerator.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ public RuntimeConfigurationGenerator WithAzureMonitorLogging(bool isEnabled = tr
235235
return this;
236236
}
237237

238-
public RuntimeConfigurationGenerator WithAzureMonitorIntegration(int? startingFromInHours = 100, bool? useAzureMonitorSdk = true, int? batchSize = null)
238+
public RuntimeConfigurationGenerator WithAzureMonitorIntegration(int? startingFromInHours = 100, bool? useAzureMonitorSdk = true, int? batchSize = null, TimeSpan? startingFromOffset = null)
239239
{
240240
_runtimeConfiguration.AzureMonitor ??= new AzureMonitorConfiguration();
241241
_runtimeConfiguration.AzureMonitor.Integration ??= new AzureMonitorIntegrationConfiguration();
@@ -247,6 +247,11 @@ public RuntimeConfigurationGenerator WithAzureMonitorIntegration(int? startingFr
247247
_runtimeConfiguration.AzureMonitor.Integration.History.StartingFromInHours = startingFromInHours.Value;
248248
}
249249

250+
if (startingFromOffset != null)
251+
{
252+
_runtimeConfiguration.AzureMonitor.Integration.History.StartingFromOffset = startingFromOffset;
253+
}
254+
250255
if (useAzureMonitorSdk != null)
251256
{
252257
_runtimeConfiguration.AzureMonitor.Integration.UseAzureMonitorSdk = useAzureMonitorSdk.Value;
@@ -371,6 +376,10 @@ public async Task<IConfiguration> GenerateAsync()
371376
configurationBuilder.AppendLine($" useAzureMonitorSdk: {_runtimeConfiguration?.AzureMonitor.Integration.UseAzureMonitorSdk}");
372377
configurationBuilder.AppendLine(" history:");
373378
configurationBuilder.AppendLine($" startingFromInHours: {_runtimeConfiguration?.AzureMonitor.Integration.History.StartingFromInHours}");
379+
if (_runtimeConfiguration?.AzureMonitor.Integration.History.StartingFromOffset != null)
380+
{
381+
configurationBuilder.AppendLine($" startingFromOffset: {_runtimeConfiguration?.AzureMonitor.Integration.History.StartingFromOffset}");
382+
}
374383
configurationBuilder.AppendLine(" metricsBatching:");
375384
configurationBuilder.AppendLine($" enabled: {_runtimeConfiguration?.AzureMonitor.Integration.MetricsBatching.Enabled}");
376385
configurationBuilder.AppendLine($" maxBatchSize: {_runtimeConfiguration?.AzureMonitor.Integration.MetricsBatching.MaxBatchSize}");

0 commit comments

Comments
 (0)