Multi-resource metrics query support in the Azure Monitor Query libraries

Paul Van Eck

This past January, the Azure Monitor team announced 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.

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.

Sovereign cloud support


At the time of writing, the Azure Monitor Query libraries’ 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:

You can access multi-resource metrics query APIs from the following package versions:

Ecosystem Minimum package version
.NET 1.3.0
Go 1.0.0
Java 1.3.0
JavaScript 1.2.0
Python 1.3.0

A new home for multi-resource metrics queries

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, MetricsClient, 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 azquery module, we released the new azmetrics module.

Presently, a multi-resource metrics query is the sole supported operation in MetricsClient and azmetrics. However, we anticipate expanding the clients’ functionality to support other metrics-related query operations in the future.

Developer usage

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:

  1. Each resource must be in the same Azure region denoted by the endpoint specified when instantiating the client.
  2. Each resource must belong to the same Azure subscription.
  3. User must have authorization to read monitoring data at the subscription level. For example, the Monitoring Reader role on the subscription to be queried.

The metric namespace that contains the metrics to be queried must also be specified. You can find a list of metric namespaces in this list of supported metrics by resource type.

The following code snippets demonstrate how to query the “Ingress” metric for multiple storage account resources in various languages.

Python

from azure.identity import DefaultAzureCredential
from azure.monitor.query import MetricsClient

resource_ids = [
    "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/myStorageAccount",
    "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/myStorageAccount2"
]

credential = DefaultAzureCredential()
endpoint = "https://eastus.metrics.monitor.azure.com"
client = MetricsClient(endpoint, credential)

metrics_query_results = client.query_resources(
    resource_ids=resource_ids,
    metric_namespace="Microsoft.Storage/storageAccounts",
    metric_names=["Ingress"]
)

Check out the Azure SDK for Python repository for more sample usage.

JavaScript/TypeScript

import { DefaultAzureCredential } from "@azure/identity";
import { MetricsClient } from "@azure/monitor-query";

export async function main() {
    let resourceIds: string[] = [
      "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/myStorageAccount",
      "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/myStorageAccount2"
    ];
    let metricsNamespace: string = "Microsoft.Storage/storageAccounts";
    let metricNames: string[] = ["Ingress"];
    const endpoint: string = "https://eastus.metrics.monitor.azure.com";

    const credential = new DefaultAzureCredential();
    const metricsClient: MetricsClient = new MetricsClient(
      endpoint,
      credential
    );

    const result: : MetricsQueryResult[] = await metricsClient.queryResources(
      resourceIds,
      metricNames,
      metricsNamespace
    );
}

Check out the Azure SDK for JavaScript repository for more sample usage.

Java

import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.monitor.query.models.MetricResult;
import com.azure.monitor.query.models.MetricsQueryResourcesResult;
import com.azure.monitor.query.models.MetricsQueryResult;

import java.util.Arrays;
import java.util.List;

public class MetricsSample {

    public static void main(String[] args) {
        MetricsClient metricsClient = new MetricsClientBuilder()
                    .credential(new DefaultAzureCredentialBuilder().build())
                    .endpoint("https://eastus.metrics.monitor.azure.com")
                    .buildClient();

        List<String> resourceIds = Arrays.asList(
            "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/myStorageAccount",
            "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/myStorageAccount2"
        );

        MetricsQueryResourcesResult metricsQueryResourcesResult = metricsClient.queryResources(
            resourceIds,
            Arrays.asList("Ingress"),
            "Microsoft.Storage/storageAccounts");

        for (MetricsQueryResult result : metricsQueryResourcesResult.getMetricsQueryResults()) {
            List<MetricResult> metrics = result.getMetrics();
        }
    }
}

Check out the Azure SDK for Java repository for more sample usage.

.NET

using Azure;
using Azure.Core;
using Azure.Identity;
using Azure.Monitor.Query.Models;
using Azure.Monitor.Query;

List<ResourceIdentifier> resourceIds = new List<ResourceIdentifier>
{
    new ResourceIdentifier("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/myStorageAccount"),
    new ResourceIdentifier("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/myStorageAccount2")
};
var client = new MetricsClient(
    new Uri("https://eastus.metrics.monitor.azure.com"),
    new DefaultAzureCredential());

Response<MetricsQueryResourcesResult> result = await client.QueryResourcesAsync(
    resourceIds: resourceIds,
    metricNames: new List<string> { "Ingress" },
    metricNamespace: "Microsoft.Storage/storageAccounts").ConfigureAwait(false);

MetricsQueryResourcesResult metricsQueryResults = result.Value;

Check out the Azure SDK for .NET repository for more sample usage.

Go

import (
    "context"

    "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
    "github.com/Azure/azure-sdk-for-go/sdk/monitor/query/azmetrics"
)

func main() {
    endpoint := "https://eastus.metrics.monitor.azure.com"
    subscriptionID := "00000000-0000-0000-0000-000000000000"
    resourceIDs := []string{
        "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/myStorageAccount",
        "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/myStorageAccount2",
    }

    cred, err := azidentity.NewDefaultAzureCredential(nil)
    if err != nil {
        // Handle error
    }
    client, err := azmetrics.NewClient(endpoint, cred, nil)
    if err != nil {
        // Handle error
    }

    res, err = client.QueryResources(
        context.Background(),
        subscriptionID,
        "Microsoft.Storage/storageAccounts",
        []string{"Ingress"},
        azmetrics.ResourceIDList{ResourceIDs: resourceIDs},
        nil
    )
    if err != nil {
        // Handle error
    }
}

Check out the Azure SDK for Go repository for more sample usage.

Summary

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.

Any feedback you have on how we can improve the libraries is greatly appreciated. Let’s have those conversations on GitHub at these locations:

0 comments

Leave a comment

Feedback usabilla icon