@@ -12,9 +12,9 @@ namespace ServiceControl.Transports.ASBS;
1212using Azure . Core ;
1313using Azure . Core . Pipeline ;
1414using Azure . Identity ;
15- using Azure . Monitor . Query . Metrics ;
16- using Azure . Monitor . Query . Metrics . Models ;
1715using Azure . ResourceManager ;
16+ using Azure . ResourceManager . Monitor ;
17+ using Azure . ResourceManager . Monitor . Models ;
1818using Azure . ResourceManager . Resources ;
1919using Azure . ResourceManager . ServiceBus ;
2020using BrokerThroughput ;
@@ -33,8 +33,6 @@ public class AzureQuery(ILogger<AzureQuery> logger, TimeProvider timeProvider, T
3333 TokenCredential ? credential ;
3434 ResourceIdentifier ? resourceId ;
3535 ArmEnvironment armEnvironment ;
36- MetricsClientAudience metricsClientAudience ;
37- MetricsClient ? metricsClient ;
3836
3937 protected override void InitializeCore ( ReadOnlyDictionary < string , string > settings )
4038 {
@@ -107,7 +105,7 @@ protected override void InitializeCore(ReadOnlyDictionary<string, string> settin
107105 Diagnostics . AppendLine ( "Client secret set" ) ;
108106 }
109107
110- ( armEnvironment , metricsClientAudience ) = GetEnvironment ( ) ;
108+ armEnvironment = GetEnvironment ( ) ;
111109
112110 if ( managementUrl == null )
113111 {
@@ -146,26 +144,26 @@ protected override void InitializeCore(ReadOnlyDictionary<string, string> settin
146144
147145 return ;
148146
149- ( ArmEnvironment armEnvironment , MetricsClientAudience metricsClientAudience ) GetEnvironment ( )
147+ ArmEnvironment GetEnvironment ( )
150148 {
151149 if ( managementUrlParsed == null || managementUrlParsed == ArmEnvironment . AzurePublicCloud . Endpoint )
152150 {
153- return ( ArmEnvironment . AzurePublicCloud , MetricsClientAudience . AzurePublicCloud ) ;
151+ return ArmEnvironment . AzurePublicCloud ;
154152 }
155153
156154 if ( managementUrlParsed == ArmEnvironment . AzureChina . Endpoint )
157155 {
158- return ( ArmEnvironment . AzureChina , MetricsClientAudience . AzureChina ) ;
156+ return ArmEnvironment . AzureChina ;
159157 }
160158
161159 if ( managementUrlParsed == ArmEnvironment . AzureGermany . Endpoint )
162160 {
163- return ( ArmEnvironment . AzureGermany , MetricsClientAudience . AzurePublicCloud ) ;
161+ return ArmEnvironment . AzureGermany ;
164162 }
165163
166164 if ( managementUrlParsed == ArmEnvironment . AzureGovernment . Endpoint )
167165 {
168- return ( ArmEnvironment . AzureGovernment , MetricsClientAudience . AzureGovernment ) ;
166+ return ArmEnvironment . AzureGovernment ;
169167 }
170168
171169 string options = string . Join ( ", " ,
@@ -175,7 +173,7 @@ protected override void InitializeCore(ReadOnlyDictionary<string, string> settin
175173 } . Select ( environment => $ "\" { environment . Endpoint } \" ") ) ;
176174 InitialiseErrors . Add ( $ "Management url configuration is invalid, available options are { options } ") ;
177175
178- return ( ArmEnvironment . AzurePublicCloud , MetricsClientAudience . AzurePublicCloud ) ;
176+ return ArmEnvironment . AzurePublicCloud ;
179177 }
180178 }
181179
@@ -235,85 +233,27 @@ public override async IAsyncEnumerable<QueueThroughput> GetThroughputPerDay(IBro
235233 }
236234 }
237235
238- async Task < MetricsClient > InitializeMetricsClient ( CancellationToken cancellationToken = default )
239- {
240- if ( resourceId is null || armClient is null || credential is null )
241- {
242- throw new InvalidOperationException ( "AzureQuery has not been initialized correctly." ) ;
243- }
244-
245- var serviceBusNamespaceResource = await armClient
246- . GetServiceBusNamespaceResource ( resourceId ) . GetAsync ( cancellationToken )
247- ?? throw new Exception ( $ "Could not find an Azure Service Bus namespace with resource Id: \" { resourceId } \" ") ;
248-
249- // Determine the region of the namespace
250- var regionName = serviceBusNamespaceResource . Value . Data . Location . Name ;
251-
252- // Build the regional Azure Monitor Metrics endpoint from the audience
253- var metricsEndpoint = BuildMetricsEndpoint ( metricsClientAudience , regionName ) ;
254-
255- // CreateNewOnMetadataUpdateAttribute the MetricsClient for this namespace
256- return new MetricsClient (
257- metricsEndpoint ,
258- credential ! ,
259- new MetricsClientOptions
260- {
261- Audience = metricsClientAudience ,
262- Transport = new HttpClientTransport (
263- new HttpClient ( new SocketsHttpHandler
264- {
265- PooledConnectionIdleTimeout = TimeSpan . FromMinutes ( 2 )
266- } ) )
267- } ) ;
268- }
269-
270- static Uri BuildMetricsEndpoint ( MetricsClientAudience audience , string regionName )
271- {
272- var region = regionName . ToLowerInvariant ( ) ;
273- var builder = new UriBuilder ( audience . ToString ( ) ) ;
274- builder . Host = $ "{ region } .{ builder . Host } ";
275- return builder . Uri ;
276- }
277-
278- async Task < IReadOnlyList < MetricValue > > GetMetrics ( string queueName , DateOnly startTime , DateOnly endTime ,
236+ async Task < IReadOnlyList < MonitorMetricValue > > GetMetrics ( string queueName , DateOnly startTime , DateOnly endTime ,
279237 CancellationToken cancellationToken = default )
280238 {
281- metricsClient ??= await InitializeMetricsClient ( cancellationToken ) ;
282-
283- var response = await metricsClient . QueryResourcesAsync (
284- [ resourceId ! ] ,
285- [ CompleteMessageMetricName ] ,
286- MicrosoftServicebusNamespacesMetricsNamespace ,
287- new MetricsQueryResourcesOptions
288- {
289- Filter = $ "EntityName eq '{ queueName } '",
290- TimeRange = new MetricsQueryTimeRange ( startTime . ToDateTime ( TimeOnly . MinValue , DateTimeKind . Utc ) , endTime . ToDateTime ( TimeOnly . MaxValue , DateTimeKind . Utc ) ) ,
291- Granularity = TimeSpan . FromDays ( 1 )
292- } ,
293- cancellationToken ) ;
294-
295- var metricQueryResult = response . Value . Values . SingleOrDefault ( mr => mr . Namespace == MicrosoftServicebusNamespacesMetricsNamespace ) ;
296-
297- if ( metricQueryResult is null )
239+ var options = new ArmResourceGetMonitorMetricsOptions ( )
298240 {
299- throw new Exception ( $ "No metrics query results returned for { MicrosoftServicebusNamespacesMetricsNamespace } ") ;
300- }
241+ Metricnames = CompleteMessageMetricName ,
242+ Timespan = $ "{ startTime . ToDateTime ( TimeOnly . MinValue , DateTimeKind . Utc ) : o} /{ endTime . ToDateTime ( TimeOnly . MaxValue , DateTimeKind . Utc ) : o} ",
243+ Filter = $ "EntityName eq '{ queueName } '",
244+ Interval = TimeSpan . FromDays ( 1 ) ,
245+ Metricnamespace = MicrosoftServicebusNamespacesMetricsNamespace
246+ } ;
301247
302- var metricResult = metricQueryResult . GetMetricByName ( CompleteMessageMetricName ) ;
248+ var response = armClient . GetMonitorMetricsAsync ( resourceId , options , cancellationToken ) ;
303249
304- if ( metricResult . Error . Message is not null )
305- {
306- throw new Exception ( $ "Metrics query result for '{ metricResult . Name } ' failed: { metricResult . Error . Message } ") ;
307- }
250+ var metric = await response . SingleOrDefaultAsync ( m => m . Name . Value == CompleteMessageMetricName , cancellationToken )
251+ ?? throw new Exception ( $ "Metric { CompleteMessageMetricName } not found for { queueName } ") ;
308252
309- var timeSeries = metricResult . TimeSeries . SingleOrDefault ( ) ;
310-
311- if ( timeSeries is null )
312- {
313- throw new Exception ( $ "Metrics query result for '{ metricResult . Name } ' contained no time series") ;
314- }
253+ var timeSeries = metric . Timeseries . SingleOrDefault ( )
254+ ?? throw new Exception ( $ "Metric { metric . Name . Value } for { queueName } contains no time series") ;
315255
316- return timeSeries . Values . AsReadOnly ( ) ;
256+ return timeSeries . Data ;
317257 }
318258
319259 public override async IAsyncEnumerable < IBrokerQueue > GetQueueNames (
0 commit comments