@@ -28,8 +28,11 @@ public class AzureQuery(ILogger<AzureQuery> logger, TimeProvider timeProvider, T
2828 string serviceBusName = string . Empty ;
2929 MetricsClient ? client ;
3030 ArmClient ? armClient ;
31+ TokenCredential ? credential ;
32+ Uri ? metricsEndpoint ;
3133 string ? resourceId ;
3234 ArmEnvironment armEnvironment ;
35+ MetricsClientAudience metricsQueryAudience ;
3336
3437 protected override void InitializeCore ( ReadOnlyDictionary < string , string > settings )
3538 {
@@ -102,7 +105,7 @@ protected override void InitializeCore(ReadOnlyDictionary<string, string> settin
102105 Diagnostics . AppendLine ( "Client secret set" ) ;
103106 }
104107
105- ( armEnvironment , var metricsQueryAudience ) = GetEnvironment ( ) ;
108+ ( armEnvironment , metricsQueryAudience ) = GetEnvironment ( ) ;
106109
107110 if ( managementUrl == null )
108111 {
@@ -118,28 +121,17 @@ protected override void InitializeCore(ReadOnlyDictionary<string, string> settin
118121 return ;
119122 }
120123
121- TokenCredential clientCredentials ;
122124 if ( connectionSettings . AuthenticationMethod is TokenCredentialAuthentication tokenCredentialAuthentication )
123125 {
124126 Diagnostics . AppendLine ( "Attempting to use managed identity" ) ;
125- clientCredentials = tokenCredentialAuthentication . Credential ;
127+ credential = tokenCredentialAuthentication . Credential ;
126128 }
127129 else
128130 {
129- clientCredentials = new ClientSecretCredential ( tenantId , clientId , clientSecret ) ;
131+ credential = new ClientSecretCredential ( tenantId , clientId , clientSecret ) ;
130132 }
131133
132- client = new MetricsClient ( armEnvironment . Endpoint , clientCredentials ,
133- new MetricsClientOptions
134- {
135- Audience = metricsQueryAudience ,
136- Transport = new HttpClientTransport (
137- new HttpClient ( new SocketsHttpHandler
138- {
139- PooledConnectionIdleTimeout = TimeSpan . FromMinutes ( 2 )
140- } ) )
141- } ) ;
142- armClient = new ArmClient ( clientCredentials , subscriptionId ,
134+ armClient = new ArmClient ( credential , subscriptionId ,
143135 new ArmClientOptions
144136 {
145137 Environment = armEnvironment ,
@@ -229,7 +221,6 @@ public override async IAsyncEnumerable<QueueThroughput> GetThroughputPerDay(IBro
229221 while ( currentDate <= endDate )
230222 {
231223 data . Add ( currentDate , new QueueThroughput { TotalThroughput = 0 , DateUTC = currentDate } ) ;
232-
233224 currentDate = currentDate . AddDays ( 1 ) ;
234225 }
235226
@@ -274,12 +265,37 @@ public override async IAsyncEnumerable<IBrokerQueue> GetQueueNames(
274265 var namespaces =
275266 subscription . GetServiceBusNamespacesAsync ( cancellationToken ) ;
276267
277- await foreach ( var serviceBusNamespaceResource in namespaces . WithCancellation (
278- cancellationToken ) )
268+ await foreach ( var serviceBusNamespaceResource in namespaces . WithCancellation ( cancellationToken ) )
279269 {
280270 if ( validNamespaces . Contains ( serviceBusNamespaceResource . Data . Name ) )
281271 {
282272 resourceId = serviceBusNamespaceResource . Id ;
273+
274+ // Determine the region of the namespace
275+ var regionName = serviceBusNamespaceResource . Data . Location . Name ;
276+
277+ // Build the regional Azure Monitor Metrics endpoint from the audience
278+ var newEndpoint = BuildMetricsEndpointFromAudience ( metricsQueryAudience , regionName ) ;
279+
280+ // Create or refresh the MetricsClient if it's missing or points to a different region
281+ if ( client is null || metricsEndpoint ? . ToString ( ) != newEndpoint . ToString ( ) )
282+ {
283+ metricsEndpoint = newEndpoint ;
284+
285+ client = new MetricsClient (
286+ metricsEndpoint ,
287+ credential ! ,
288+ new MetricsClientOptions
289+ {
290+ Audience = metricsQueryAudience ,
291+ Transport = new HttpClientTransport (
292+ new HttpClient ( new SocketsHttpHandler
293+ {
294+ PooledConnectionIdleTimeout = TimeSpan . FromMinutes ( 2 )
295+ } ) )
296+ } ) ;
297+ }
298+
283299 await foreach ( var queue in serviceBusNamespaceResource . GetServiceBusQueues ( )
284300 . WithCancellation ( cancellationToken ) )
285301 {
@@ -303,6 +319,21 @@ public override async IAsyncEnumerable<IBrokerQueue> GetQueueNames(
303319 { ArmEnvironment . AzureChina , "servicebus.chinacloudapi.cn" } ,
304320 } ;
305321
322+ // Build metrics endpoint host directly from the configured audience.
323+ Uri BuildMetricsEndpointFromAudience ( MetricsClientAudience audience , string regionName )
324+ {
325+ var region = regionName . ToLowerInvariant ( ) ;
326+
327+ var audienceUri = new Uri ( audience . ToString ( ) ) ;
328+ var audienceHost = audienceUri . Host ; // e.g., "metrics.monitor.azure.com"
329+
330+ var regionalHost = audienceHost . StartsWith ( "metrics." , StringComparison . OrdinalIgnoreCase )
331+ ? audienceHost . Replace ( "metrics." , $ "{ region } .metrics.")
332+ : $ "{ region } .metrics.{ audienceHost } ";
333+
334+ return new Uri ( $ "https://{ regionalHost } ") ;
335+ }
336+
306337 async Task < HashSet < string > > GetValidNamespaceNames ( CancellationToken cancellationToken = default )
307338 {
308339 var validNamespaces = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) { serviceBusName } ;
@@ -374,4 +405,4 @@ public static class AzureServiceBusSettings
374405 public static readonly string ManagementUrl = "ASB/ManagementUrl" ;
375406 public static readonly string ManagementUrlDescription = "Azure management URL" ;
376407 }
377- }
408+ }
0 commit comments