{"id":3031,"date":"2024-04-15T17:43:09","date_gmt":"2024-04-16T00:43:09","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/azure-sdk\/?p=3031"},"modified":"2024-04-15T17:43:09","modified_gmt":"2024-04-16T00:43:09","slug":"multi-resource-metrics-query-support-in-the-azure-monitor-query-libraries","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/azure-sdk\/multi-resource-metrics-query-support-in-the-azure-monitor-query-libraries\/","title":{"rendered":"Multi-resource metrics query support in the Azure Monitor Query libraries"},"content":{"rendered":"<p>This past January, the Azure Monitor team <a href=\"https:\/\/techcommunity.microsoft.com\/t5\/azure-observability-blog\/azure-monitor-announcing-general-availability-of-azure-monitor\/ba-p\/4041394\">announced<\/a> the stable release of the Azure Monitor Metrics data plane API. This API grants the ability to query metrics for up to 50 Azure resources in a single call, providing a faster and more efficient way to retrieve metrics data for multiple resources.<\/p>\n<p>To allow developers to seamlessly integrate multi-resource metrics queries into their applications, the Azure SDK team is excited to announce support in the latest stable releases of our Azure Monitor Query client libraries.<\/p>\n<p><div class=\"alert alert-primary\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Sovereign cloud support<\/strong><\/p><\/p>\n<p>At the time of writing, the Azure Monitor Query libraries&#8217; multi-resource metrics query feature is only available to Azure Public Cloud customers. Support for the Azure US Government and Azure China sovereign clouds is planned for later in the calendar year. For more information, see the language-specific GitHub issues:<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-net\/issues\/42526\">.NET<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-go\/issues\/22547\">Go<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-java\/issues\/39125\">Java<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-js\/issues\/28821\">JavaScript<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-python\/issues\/34693\">Python<\/a><\/li>\n<\/ul>\n<p><\/div><\/p>\n<p>You can access multi-resource metrics query APIs from the following package versions:<\/p>\n<table>\n<thead>\n<tr>\n<th>Ecosystem<\/th>\n<th>Minimum package version<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>.NET<\/td>\n<td><a href=\"https:\/\/www.nuget.org\/packages\/Azure.Monitor.Query\/1.3.0\">1.3.0<\/a><\/td>\n<\/tr>\n<tr>\n<td>Go<\/td>\n<td><a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/monitor\/query\/azmetrics@v1.0.0\">1.0.0<\/a><\/td>\n<\/tr>\n<tr>\n<td>Java<\/td>\n<td><a href=\"https:\/\/central.sonatype.com\/artifact\/com.azure\/azure-monitor-query\/1.3.0\/overview\">1.3.0<\/a><\/td>\n<\/tr>\n<tr>\n<td>JavaScript<\/td>\n<td><a href=\"https:\/\/www.npmjs.com\/package\/@azure\/monitor-query\/v\/1.2.0\">1.2.0<\/a><\/td>\n<\/tr>\n<tr>\n<td>Python<\/td>\n<td><a href=\"https:\/\/pypi.org\/project\/azure-monitor-query\/1.3.0\/\">1.3.0<\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>A new home for multi-resource metrics queries<\/h2>\n<p>Earlier versions of the Azure Monitor Query client libraries required sending calls to the Azure Resource Manager APIs to query metrics on a per-resource basis. However, with the introduction of the Azure Monitor Metrics data plane API, a new client, <code>MetricsClient<\/code>, was added to facilitate data plane metrics operations in the .NET, Java, JavaScript, and Python libraries. For Go, instead of introducing a new client in the existing <code>azquery<\/code> module, we released the new <code>azmetrics<\/code> module.<\/p>\n<p>Presently, a multi-resource metrics query is the sole supported operation in <code>MetricsClient<\/code> and <code>azmetrics<\/code>. However, we anticipate expanding the clients&#8217; functionality to support other metrics-related query operations in the future.<\/p>\n<h2>Developer usage<\/h2>\n<p>Developers can now provide a list of resource IDs to the new client operation, eliminating the need for individual calls for each resource. However, to use this API, the following criteria must be satisfied:<\/p>\n<ol>\n<li>Each resource must be in the same Azure region denoted by the endpoint specified when instantiating the client.<\/li>\n<li>Each resource must belong to the same Azure subscription.<\/li>\n<li>User must have authorization to read monitoring data at the subscription level. For example, the <a href=\"https:\/\/learn.microsoft.com\/azure\/role-based-access-control\/built-in-roles#monitoring-reader\"><code>Monitoring Reader<\/code><\/a> role on the subscription to be queried.<\/li>\n<\/ol>\n<p>The metric namespace that contains the metrics to be queried must also be specified. You can find a list of metric namespaces in this <a href=\"https:\/\/learn.microsoft.com\/azure\/azure-monitor\/reference\/supported-metrics\/metrics-index#supported-metrics-and-log-categories-by-resource-type\">list of supported metrics by resource type<\/a>.<\/p>\n<p>The following code snippets demonstrate how to query the &#8220;Ingress&#8221; metric for multiple storage account resources in various languages.<\/p>\n<h3>Python<\/h3>\n<pre><code class=\"language-python\">from azure.identity import DefaultAzureCredential\r\nfrom azure.monitor.query import MetricsClient\r\n\r\nresource_ids = [\r\n    \"\/subscriptions\/00000000-0000-0000-0000-000000000000\/resourceGroups\/myResourceGroup\/providers\/Microsoft.Storage\/storageAccounts\/myStorageAccount\",\r\n    \"\/subscriptions\/00000000-0000-0000-0000-000000000000\/resourceGroups\/myResourceGroup\/providers\/Microsoft.Storage\/storageAccounts\/myStorageAccount2\"\r\n]\r\n\r\ncredential = DefaultAzureCredential()\r\nendpoint = \"https:\/\/eastus.metrics.monitor.azure.com\"\r\nclient = MetricsClient(endpoint, credential)\r\n\r\nmetrics_query_results = client.query_resources(\r\n    resource_ids=resource_ids,\r\n    metric_namespace=\"Microsoft.Storage\/storageAccounts\",\r\n    metric_names=[\"Ingress\"]\r\n)<\/code><\/pre>\n<p>Check out the Azure SDK for Python repository for <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-python\/blob\/main\/sdk\/monitor\/azure-monitor-query\/samples\/sample_metrics_query_multiple.py\">more sample usage<\/a>.<\/p>\n<h3>JavaScript\/TypeScript<\/h3>\n<pre><code class=\"language-typescript\">import { DefaultAzureCredential } from \"@azure\/identity\";\r\nimport { MetricsClient } from \"@azure\/monitor-query\";\r\n\r\nexport async function main() {\r\n    let resourceIds: string[] = [\r\n      \"\/subscriptions\/00000000-0000-0000-0000-000000000000\/resourceGroups\/myResourceGroup\/providers\/Microsoft.Storage\/storageAccounts\/myStorageAccount\",\r\n      \"\/subscriptions\/00000000-0000-0000-0000-000000000000\/resourceGroups\/myResourceGroup\/providers\/Microsoft.Storage\/storageAccounts\/myStorageAccount2\"\r\n    ];\r\n    let metricsNamespace: string = \"Microsoft.Storage\/storageAccounts\";\r\n    let metricNames: string[] = [\"Ingress\"];\r\n    const endpoint: string = \"https:\/\/eastus.metrics.monitor.azure.com\";\r\n\r\n    const credential = new DefaultAzureCredential();\r\n    const metricsClient: MetricsClient = new MetricsClient(\r\n      endpoint,\r\n      credential\r\n    );\r\n\r\n    const result: : MetricsQueryResult[] = await metricsClient.queryResources(\r\n      resourceIds,\r\n      metricNames,\r\n      metricsNamespace\r\n    );\r\n}<\/code><\/pre>\n<p>Check out the Azure SDK for JavaScript repository for <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-js\/tree\/main\/sdk\/monitor\/monitor-query#query-metrics-for-multiple-resources\">more sample usage<\/a>.<\/p>\n<h3>Java<\/h3>\n<pre><code class=\"language-java\">import com.azure.identity.DefaultAzureCredentialBuilder;\r\nimport com.azure.monitor.query.models.MetricResult;\r\nimport com.azure.monitor.query.models.MetricsQueryResourcesResult;\r\nimport com.azure.monitor.query.models.MetricsQueryResult;\r\n\r\nimport java.util.Arrays;\r\nimport java.util.List;\r\n\r\npublic class MetricsSample {\r\n\r\n    public static void main(String[] args) {\r\n        MetricsClient metricsClient = new MetricsClientBuilder()\r\n                    .credential(new DefaultAzureCredentialBuilder().build())\r\n                    .endpoint(\"https:\/\/eastus.metrics.monitor.azure.com\")\r\n                    .buildClient();\r\n\r\n        List&lt;String&gt; resourceIds = Arrays.asList(\r\n            \"\/subscriptions\/00000000-0000-0000-0000-000000000000\/resourceGroups\/myResourceGroup\/providers\/Microsoft.Storage\/storageAccounts\/myStorageAccount\",\r\n            \"\/subscriptions\/00000000-0000-0000-0000-000000000000\/resourceGroups\/myResourceGroup\/providers\/Microsoft.Storage\/storageAccounts\/myStorageAccount2\"\r\n        );\r\n\r\n        MetricsQueryResourcesResult metricsQueryResourcesResult = metricsClient.queryResources(\r\n            resourceIds,\r\n            Arrays.asList(\"Ingress\"),\r\n            \"Microsoft.Storage\/storageAccounts\");\r\n\r\n        for (MetricsQueryResult result : metricsQueryResourcesResult.getMetricsQueryResults()) {\r\n            List&lt;MetricResult&gt; metrics = result.getMetrics();\r\n        }\r\n    }\r\n}<\/code><\/pre>\n<p>Check out the Azure SDK for Java repository for <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-java\/blob\/main\/sdk\/monitor\/azure-monitor-query\/src\/samples\/java\/com\/azure\/monitor\/query\/MetricsSample.java\">more sample usage<\/a>.<\/p>\n<h3>.NET<\/h3>\n<pre><code class=\"language-csharp\">using Azure;\r\nusing Azure.Core;\r\nusing Azure.Identity;\r\nusing Azure.Monitor.Query.Models;\r\nusing Azure.Monitor.Query;\r\n\r\nList&lt;ResourceIdentifier&gt; resourceIds = new List&lt;ResourceIdentifier&gt;\r\n{\r\n    new ResourceIdentifier(\"\/subscriptions\/00000000-0000-0000-0000-000000000000\/resourceGroups\/myResourceGroup\/providers\/Microsoft.Storage\/storageAccounts\/myStorageAccount\"),\r\n    new ResourceIdentifier(\"\/subscriptions\/00000000-0000-0000-0000-000000000000\/resourceGroups\/myResourceGroup\/providers\/Microsoft.Storage\/storageAccounts\/myStorageAccount2\")\r\n};\r\nvar client = new MetricsClient(\r\n    new Uri(\"https:\/\/eastus.metrics.monitor.azure.com\"),\r\n    new DefaultAzureCredential());\r\n\r\nResponse&lt;MetricsQueryResourcesResult&gt; result = await client.QueryResourcesAsync(\r\n    resourceIds: resourceIds,\r\n    metricNames: new List&lt;string&gt; { \"Ingress\" },\r\n    metricNamespace: \"Microsoft.Storage\/storageAccounts\").ConfigureAwait(false);\r\n\r\nMetricsQueryResourcesResult metricsQueryResults = result.Value;<\/code><\/pre>\n<p>Check out the Azure SDK for .NET repository for <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-net\/tree\/main\/sdk\/monitor\/Azure.Monitor.Query#query-metrics-for-multiple-resources\">more sample usage<\/a>.<\/p>\n<h3>Go<\/h3>\n<pre><code class=\"language-go\">import (\r\n    \"context\"\r\n\r\n    \"github.com\/Azure\/azure-sdk-for-go\/sdk\/azidentity\"\r\n    \"github.com\/Azure\/azure-sdk-for-go\/sdk\/monitor\/query\/azmetrics\"\r\n)\r\n\r\nfunc main() {\r\n    endpoint := \"https:\/\/eastus.metrics.monitor.azure.com\"\r\n    subscriptionID := \"00000000-0000-0000-0000-000000000000\"\r\n    resourceIDs := []string{\r\n        \"\/subscriptions\/00000000-0000-0000-0000-000000000000\/resourceGroups\/myResourceGroup\/providers\/Microsoft.Storage\/storageAccounts\/myStorageAccount\",\r\n        \"\/subscriptions\/00000000-0000-0000-0000-000000000000\/resourceGroups\/myResourceGroup\/providers\/Microsoft.Storage\/storageAccounts\/myStorageAccount2\",\r\n    }\r\n\r\n    cred, err := azidentity.NewDefaultAzureCredential(nil)\r\n    if err != nil {\r\n        \/\/ Handle error\r\n    }\r\n    client, err := azmetrics.NewClient(endpoint, cred, nil)\r\n    if err != nil {\r\n        \/\/ Handle error\r\n    }\r\n\r\n    res, err = client.QueryResources(\r\n        context.Background(),\r\n        subscriptionID,\r\n        \"Microsoft.Storage\/storageAccounts\",\r\n        []string{\"Ingress\"},\r\n        azmetrics.ResourceIDList{ResourceIDs: resourceIDs},\r\n        nil\r\n    )\r\n    if err != nil {\r\n        \/\/ Handle error\r\n    }\r\n}<\/code><\/pre>\n<p>Check out the Azure SDK for Go repository for <a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/monitor\/query\/azmetrics#pkg-examples\">more sample usage<\/a>.<\/p>\n<h2>Summary<\/h2>\n<p>The introduction of the Azure Monitor Metrics data plane API and this new functionality in our client libraries marks a significant advancement in the way developers can query metrics for Azure resources. This feature simplifies and streamlines the process of querying multiple resources, greatly reducing the number of HTTP requests that need to be processed. As we continue to enhance these features and expand their capabilities, we look forward to seeing the innovative ways developers use them to optimize their applications and workflows.<\/p>\n<p>Any feedback you have on how we can improve the libraries is greatly appreciated. Let&#8217;s have those conversations on GitHub at these locations:<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-net\/issues\">.NET<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-go\/issues\">Go<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-java\/issues\">Java<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-js\/issues\">JavaScript<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-python\/issues\">Python<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to query metrics for multiple Azure resources at once using the Azure Monitor Query libraries.<\/p>\n","protected":false},"author":151381,"featured_media":3030,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[701,804,810,160,159,162,24],"class_list":["post-3031","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-sdk","tag-net","tag-azure-monitor","tag-go","tag-java","tag-javascript","tag-python","tag-releases"],"acf":[],"blog_post_summary":"<p>Learn how to query metrics for multiple Azure resources at once using the Azure Monitor Query libraries.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/3031","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/users\/151381"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/comments?post=3031"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/3031\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media\/3030"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media?parent=3031"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/categories?post=3031"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/tags?post=3031"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}