1
1
using System ;
2
- using System . Collections . Concurrent ;
3
2
using System . Collections . Generic ;
4
- using System . Collections . Immutable ;
5
3
using System . Linq ;
6
4
using System . Threading . Tasks ;
7
5
using GuardNet ;
8
6
using Microsoft . Extensions . Logging ;
9
7
using Promitor . Core . Contracts ;
10
- using Promitor . Core . Extensions ;
11
8
using Promitor . Core . Metrics ;
12
9
using Promitor . Core . Scraping . Configuration . Model ;
13
10
using Promitor . Core . Scraping . Configuration . Model . Metrics ;
@@ -21,19 +18,13 @@ namespace Promitor.Core.Scraping
21
18
/// <typeparam name="TResourceDefinition">Type of metric definition that is being used</typeparam>
22
19
public abstract class AzureMonitorScraper < TResourceDefinition > : Scraper < TResourceDefinition >
23
20
where TResourceDefinition : class , IAzureResourceDefinition
24
- {
25
- /// <summary>
26
- /// A cache to store resource definitions. Used to hydrate resource info from resource ID, when processing batch query results
27
- /// </summary>
28
- private readonly ConcurrentDictionary < string , Tuple < IAzureResourceDefinition , TResourceDefinition > > _resourceDefinitions ; // using a dictionary for now since IMemoryCache involves layers of injection
29
-
21
+ {
30
22
/// <summary>
31
23
/// Constructor
32
24
/// </summary>
33
25
protected AzureMonitorScraper ( ScraperConfiguration scraperConfiguration ) :
34
26
base ( scraperConfiguration )
35
27
{
36
- _resourceDefinitions = new ConcurrentDictionary < string , Tuple < IAzureResourceDefinition , TResourceDefinition > > ( ) ;
37
28
}
38
29
39
30
/// <inheritdoc />
@@ -82,69 +73,6 @@ protected override async Task<ScrapeResult> ScrapeResourceAsync(string subscript
82
73
return new ScrapeResult ( subscriptionId , scrapeDefinition . ResourceGroupName , resourceDefinition . ResourceName , resourceUri , finalMetricValues , metricLabels ) ;
83
74
}
84
75
85
- protected override async Task < List < ScrapeResult > > BatchScrapeResourceAsync ( string subscriptionId , BatchScrapeDefinition < IAzureResourceDefinition > batchScrapeDefinition , PromitorMetricAggregationType aggregationType , TimeSpan aggregationInterval )
86
- {
87
- Guard . NotNull ( batchScrapeDefinition , nameof ( batchScrapeDefinition ) ) ;
88
- Guard . NotLessThan ( batchScrapeDefinition . ScrapeDefinitions . Count ( ) , 1 , nameof ( batchScrapeDefinition ) ) ;
89
- Guard . NotNull ( batchScrapeDefinition . ScrapeDefinitionBatchProperties . AzureMetricConfiguration , nameof ( batchScrapeDefinition . ScrapeDefinitionBatchProperties . AzureMetricConfiguration ) ) ;
90
-
91
- var metricName = batchScrapeDefinition . ScrapeDefinitionBatchProperties . AzureMetricConfiguration . MetricName ;
92
-
93
- // Build list of resource URIs based on definitions in the batch
94
- var resourceUriList = new List < string > ( ) ;
95
- foreach ( ScrapeDefinition < IAzureResourceDefinition > scrapeDefinition in batchScrapeDefinition . ScrapeDefinitions )
96
- {
97
- var resourceUri = $ "/{ BuildResourceUri ( subscriptionId , scrapeDefinition , ( TResourceDefinition ) scrapeDefinition . Resource ) } ";
98
- resourceUriList . Add ( resourceUri ) ;
99
- // cache resource info
100
- // the TResourceDefinition resource definition attached to scrape definition can sometimes missing some attributes, need to them in here
101
- var resourceDefinitionToCache = new AzureResourceDefinition
102
- (
103
- resourceType : scrapeDefinition . Resource . ResourceType ,
104
- resourceGroupName : scrapeDefinition . ResourceGroupName ,
105
- subscriptionId : scrapeDefinition . SubscriptionId ,
106
- resourceName : scrapeDefinition . Resource . ResourceName
107
- ) ;
108
- _resourceDefinitions . AddOrUpdate ( resourceUri , new Tuple < IAzureResourceDefinition , TResourceDefinition > ( resourceDefinitionToCache , ( TResourceDefinition ) scrapeDefinition . Resource ) , ( newTuple , oldTuple ) => oldTuple ) ;
109
- }
110
-
111
- var metricLimit = batchScrapeDefinition . ScrapeDefinitionBatchProperties . AzureMetricConfiguration . Limit ;
112
- var dimensionNames = DetermineMetricDimensions ( metricName , ( TResourceDefinition ) batchScrapeDefinition . ScrapeDefinitions [ 0 ] . Resource , batchScrapeDefinition . ScrapeDefinitionBatchProperties . AzureMetricConfiguration ) ; // TODO: resource definition doesn't seem to be used, can we remove it from function signature?
113
-
114
- var resourceIdTaggedMeasuredMetrics = new List < ResourceAssociatedMeasuredMetric > ( ) ;
115
- try
116
- {
117
- // Query Azure Monitor for metrics
118
- resourceIdTaggedMeasuredMetrics = await AzureMonitorClient . BatchQueryMetricAsync ( metricName , dimensionNames , aggregationType , aggregationInterval , resourceUriList , null , metricLimit ) ;
119
- }
120
- catch ( MetricInformationNotFoundException metricsNotFoundException )
121
- {
122
- Logger . LogWarning ( "No metric information found for metric {MetricName} with dimensions {MetricDimensions}. Details: {Details}" , metricsNotFoundException . Name , metricsNotFoundException . Dimensions , metricsNotFoundException . Details ) ;
123
-
124
- var measuredMetric = dimensionNames . Count > 0
125
- ? MeasuredMetric . CreateForDimensions ( dimensionNames )
126
- : MeasuredMetric . CreateWithoutDimensions ( null ) ;
127
- resourceIdTaggedMeasuredMetrics . Add ( measuredMetric . WithResourceIdAssociation ( null ) ) ;
128
- }
129
-
130
- var scrapeResults = new List < ScrapeResult > ( ) ;
131
- // group based on resource, then do enrichment per group
132
- var groupedMeasuredMetrics = resourceIdTaggedMeasuredMetrics . GroupBy ( measuredMetric => measuredMetric . ResourceId ) ;
133
- foreach ( IGrouping < string , ResourceAssociatedMeasuredMetric > resourceMetricsGroup in groupedMeasuredMetrics )
134
- {
135
- var resourceId = resourceMetricsGroup . Key ;
136
- if ( _resourceDefinitions . TryGetValue ( resourceId , out Tuple < IAzureResourceDefinition , TResourceDefinition > resourceDefinitionTuple ) )
137
- {
138
- var resourceDefinition = resourceDefinitionTuple . Item1 ;
139
- var metricLabels = DetermineMetricLabels ( resourceDefinitionTuple . Item2 ) ;
140
- var finalMetricValues = EnrichMeasuredMetrics ( resourceDefinitionTuple . Item2 , dimensionNames , resourceMetricsGroup . ToImmutableList ( ) ) ;
141
- scrapeResults . Add ( new ScrapeResult ( subscriptionId , resourceDefinition . ResourceGroupName , resourceDefinition . ResourceName , resourceId , finalMetricValues , metricLabels ) ) ;
142
- }
143
- }
144
-
145
- return scrapeResults ;
146
- }
147
-
148
76
private int ? DetermineMetricLimit ( ScrapeDefinition < IAzureResourceDefinition > scrapeDefinition )
149
77
{
150
78
return scrapeDefinition . AzureMetricConfiguration . Limit ;
@@ -161,9 +89,9 @@ protected override async Task<List<ScrapeResult>> BatchScrapeResourceAsync(strin
161
89
/// <param name="dimensionNames">List of names of the specified dimensions provided by the scraper.</param>
162
90
/// <param name="metricValues">Measured metric values that were found</param>
163
91
/// <returns></returns>
164
- protected virtual List < MeasuredMetric > EnrichMeasuredMetrics ( TResourceDefinition resourceDefinition , List < string > dimensionNames , IReadOnlyList < MeasuredMetric > metricValues )
92
+ protected virtual List < MeasuredMetric > EnrichMeasuredMetrics ( TResourceDefinition resourceDefinition , List < string > dimensionNames , List < MeasuredMetric > metricValues )
165
93
{
166
- return metricValues . ToList ( ) ;
94
+ return metricValues ;
167
95
}
168
96
169
97
/// <summary>
0 commit comments