Skip to content

Commit

Permalink
[Monitor Query] Update metric batch client (#33958)
Browse files Browse the repository at this point in the history
- Renamed the client to `MetricsClient`.
- Renamed `query_batch` to `query_resources`
- Made `query_resources` positional arguments keyword only

Signed-off-by: Paul Van Eck <paulvaneck@microsoft.com>
  • Loading branch information
pvaneck committed Feb 8, 2024
1 parent 936bf73 commit 6a3df96
Show file tree
Hide file tree
Showing 20 changed files with 401 additions and 395 deletions.
7 changes: 4 additions & 3 deletions sdk/monitor/azure-monitor-query/CHANGELOG.md
Expand Up @@ -4,13 +4,14 @@

### Features Added

- Added `roll_up_by` keyword argument to `MetricsBatchQueryClient.query_batch` to support rolling up metrics by dimension. ([#33752](https://github.com/Azure/azure-sdk-for-python/pull/33752))
- Added `roll_up_by` keyword argument to `MetricsClient.query_resources` to support rolling up metrics by dimension. ([#33752](https://github.com/Azure/azure-sdk-for-python/pull/33752))

### Breaking Changes

- The following changes are breaking against the previous preview release (i.e. `1.3.0b2`/`1.3.0b1`):
- Reordered the arguments for the async `MetricsBatchQueryClient` constructor so that `endpoint` is now the first positional argument. ([#33752](https://github.com/Azure/azure-sdk-for-python/pull/33752))
- Reordered the `metric_names` and `metric_namespace` positional arguments in `MetricsBatchQueryClient.query_batch`. ([#33752](https://github.com/Azure/azure-sdk-for-python/pull/33752))
- `MetricsBatchQueryClient` has been renamed to `MetricsClient`. ([#33958](https://github.com/Azure/azure-sdk-for-python/pull/33958))
- Reordered the arguments for the async `MetricsClient` constructor so that `endpoint` is now the first positional argument. ([#33752](https://github.com/Azure/azure-sdk-for-python/pull/33752))
- Positional arguments in `MetricsClient.query_resources` are now required keyword-only arguments. ([#33958](https://github.com/Azure/azure-sdk-for-python/pull/33958))

### Bugs Fixed

Expand Down
35 changes: 20 additions & 15 deletions sdk/monitor/azure-monitor-query/README.md
Expand Up @@ -19,7 +19,7 @@ The Azure Monitor Query client library is used to execute read-only queries agai

### Prerequisites

- Python 3.7 or later
- Python 3.8 or later
- An [Azure subscription][azure_subscription]
- A [TokenCredential](https://learn.microsoft.com/python/api/azure-core/azure.core.credentials.tokencredential?view=azure-python) implementation, such as an [Azure Identity library credential type](https://learn.microsoft.com/python/api/overview/azure/identity-readme?view=azure-python#credential-classes).
- To query Logs, you need one of the following things:
Expand All @@ -37,19 +37,20 @@ pip install azure-monitor-query

### Create the client

An authenticated client is required to query Logs or Metrics. The library includes both synchronous and asynchronous forms of the clients. To authenticate, create an instance of a token credential. Use that instance when creating a `LogsQueryClient`, `MetricsQueryClient`, or `MetricsBatchQueryClient`. The following examples use `DefaultAzureCredential` from the [azure-identity](https://pypi.org/project/azure-identity/) package.
An authenticated client is required to query Logs or Metrics. The library includes both synchronous and asynchronous forms of the clients. To authenticate, create an instance of a token credential. Use that instance when creating a `LogsQueryClient`, `MetricsQueryClient`, or `MetricsClient`. The following examples use `DefaultAzureCredential` from the [azure-identity](https://pypi.org/project/azure-identity/) package.

#### Synchronous clients

Consider the following example, which creates synchronous clients for both Logs and Metrics querying:

```python
from azure.identity import DefaultAzureCredential
from azure.monitor.query import LogsQueryClient, MetricsQueryClient
from azure.monitor.query import LogsQueryClient, MetricsQueryClient, MetricsClient

credential = DefaultAzureCredential()
logs_client = LogsQueryClient(credential)
metrics_client = MetricsQueryClient(credential)
logs_query_client = LogsQueryClient(credential)
metrics_query_client = MetricsQueryClient(credential)
metrics_client = MetricsClient("https://<regional endpoint>", credential)
```

#### Asynchronous clients
Expand All @@ -58,20 +59,22 @@ The asynchronous forms of the query client APIs are found in the `.aio`-suffixed

```python
from azure.identity.aio import DefaultAzureCredential
from azure.monitor.query.aio import LogsQueryClient, MetricsQueryClient
from azure.monitor.query.aio import LogsQueryClient, MetricsQueryClient, MetricsClient

credential = DefaultAzureCredential()
async_logs_client = LogsQueryClient(credential)
async_metrics_client = MetricsQueryClient(credential)
async_logs_query_client = LogsQueryClient(credential)
async_metrics_query_client = MetricsQueryClient(credential)
async_metrics_client = MetricsClient("https://<regional endpoint>", credential)
```
```
#### Configure clients for non-public Azure clouds
By default, `LogsQueryClient` and `MetricsQueryClient` are configured to connect to the public Azure cloud. These can be configured to connect to non-public Azure clouds by passing in the correct `endpoint` argument: For example:
```python
logs_client = LogsQueryClient(credential, endpoint="https://api.loganalytics.azure.cn/v1")
metrics_client = MetricsQueryClient(credential, endpoint="https://management.chinacloudapi.cn")
logs_query_client = LogsQueryClient(credential, endpoint="https://api.loganalytics.azure.cn/v1")
metrics_query_client = MetricsQueryClient(credential, endpoint="https://management.chinacloudapi.cn")
```

**Note**: Currently, `MetricsQueryClient` uses the Azure Resource Manager (ARM) endpoint for querying metrics, so you will need the corresponding management endpoint for your cloud when using this client. This is subject to change in the future.
Expand Down Expand Up @@ -114,6 +117,7 @@ Each set of metric values is a time series with the following characteristics:
- [Metrics query](#metrics-query)
- [Handle metrics query response](#handle-metrics-query-response)
- [Example of handling response](#example-of-handling-response)
- [Metrics batch query](#metrics-batch-query)

### Logs query

Expand Down Expand Up @@ -527,7 +531,7 @@ for metric in response.metrics:

### Metrics batch query

A user can also query metrics from multiple resources at once using the `query_batch` method of `MetricsBatchQueryClient`. This uses a different API than the `MetricsQueryClient` and requires that a user pass in a regional endpoint when instantiating the client (for example, "https://westus3.metrics.monitor.azure.com").
A user can also query metrics from multiple resources at once using the `query_resources` method of `MetricsClient`. This uses a different API than the `MetricsQueryClient` and requires that a user pass in a regional endpoint when instantiating the client (for example, "https://westus3.metrics.monitor.azure.com").

Note, each resource must be in the same region as the endpoint passed in when instantiating the client, and each resource must be in the same Azure subscription. Furthermore, the metric namespace that contains the metrics to be queried must also be passed. A list of metric namespaces can be found [here][metric_namespaces].

Expand All @@ -538,19 +542,19 @@ import os

from azure.core.exceptions import HttpResponseError
from azure.identity import DefaultAzureCredential
from azure.monitor.query import MetricsBatchQueryClient, MetricAggregationType
from azure.monitor.query import MetricsClient, MetricAggregationType


credential = DefaultAzureCredential()
client = MetricsBatchQueryClient(endpoint, credential)
client = MetricsClient(endpoint, credential)

resource_uris = [
"/subscriptions/<id>/resourceGroups/<rg-name>/providers/<source>/storageAccounts/<resource-name-1>",
"/subscriptions/<id>/resourceGroups/<rg-name>/providers/<source>/storageAccounts/<resource-name-2>"
]

response = client.query_batch(
resource_uris,
response = client.query_resources(
resource_uris=resource_uris,
metric_namespace="Microsoft.Storage/storageAccounts",
metric_names=["Ingress"],
timespan=timedelta(hours=2),
Expand Down Expand Up @@ -586,6 +590,7 @@ The following code samples show common scenarios with the Azure Monitor Query cl
#### Metrics query samples

- [Send a query using MetricsQueryClient](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_metrics_query.py) ([async sample](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metrics_query_async.py))
- [Send a query to multiple resources in a region and subscription using MetricsClient](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_metrics_query_multiple.py) ([async sample](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metrics_query_multiple_async.py))
- [Get a list of metric namespaces](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_metric_namespaces.py) ([async sample](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metric_namespaces_async.py))
- [Get a list of metric definitions](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_metric_definitions.py) ([async sample](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metric_definitions_async.py))

Expand Down
2 changes: 1 addition & 1 deletion sdk/monitor/azure-monitor-query/assets.json
Expand Up @@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "python",
"TagPrefix": "python/monitor/azure-monitor-query",
"Tag": "python/monitor/azure-monitor-query_7462cb1df1"
"Tag": "python/monitor/azure-monitor-query_152690fb22"
}
Expand Up @@ -6,7 +6,7 @@

from ._logs_query_client import LogsQueryClient
from ._metrics_query_client import MetricsQueryClient
from ._metrics_batch_query_client import MetricsBatchQueryClient
from ._metrics_client import MetricsClient

from ._enums import (
LogsQueryStatus,
Expand Down Expand Up @@ -46,7 +46,7 @@
"LogsTableRow",
"LogsBatchQuery",
"MetricsQueryClient",
"MetricsBatchQueryClient",
"MetricsClient",
"MetricNamespace",
"MetricNamespaceClassification",
"MetricDefinition",
Expand Down
Expand Up @@ -18,8 +18,8 @@
JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object


class MetricsBatchQueryClient: # pylint: disable=client-accepts-api-version-keyword
"""MetricsBatchQueryClient should be used for performing metrics queries on multiple monitored resources in the
class MetricsClient: # pylint: disable=client-accepts-api-version-keyword
"""MetricsClient should be used for performing metrics queries on multiple monitored resources in the
same region. A credential with authorization at the subscription level is required when using this client.
:param str endpoint: The regional endpoint to use, for example
Expand Down Expand Up @@ -47,12 +47,12 @@ def __init__(self, endpoint: str, credential: TokenCredential, **kwargs: Any) ->
self._batch_metrics_op = self._client.metrics_batch

@distributed_trace
def query_batch(
def query_resources(
self,
*,
resource_uris: Sequence[str],
metric_names: Sequence[str],
metric_namespace: str,
*,
metric_names: Sequence[str],
timespan: Optional[Union[timedelta, Tuple[datetime, timedelta], Tuple[datetime, datetime]]] = None,
granularity: Optional[timedelta] = None,
aggregations: Optional[Sequence[str]] = None,
Expand All @@ -64,12 +64,12 @@ def query_batch(
) -> List[MetricsQueryResult]:
"""Lists the metric values for multiple resources.
:param resource_uris: A list of resource URIs to query metrics for. Required.
:type resource_uris: list[str]
:param metric_names: The names of the metrics (comma separated) to retrieve. Required.
:type metric_names: list[str]
:param metric_namespace: Metric namespace that contains the requested metric names. Required.
:type metric_namespace: str
:keyword resource_uris: A list of resource URIs to query metrics for. Required.
:paramtype resource_uris: list[str]
:keyword metric_namespace: Metric namespace that contains the requested metric names. Required.
:paramtype metric_namespace: str
:keyword metric_names: The names of the metrics (comma separated) to retrieve. Required.
:paramtype metric_names: list[str]
:keyword timespan: The timespan for which to query the data. This can be a timedelta,
a timedelta and a start datetime, or a start datetime/end datetime.
:paramtype timespan: Optional[Union[~datetime.timedelta, tuple[~datetime.datetime, ~datetime.timedelta],
Expand Down Expand Up @@ -109,7 +109,7 @@ def query_batch(
.. admonition:: Example:
.. literalinclude:: ../samples/sample_metrics_batch_query.py
.. literalinclude:: ../samples/sample_metrics_query_multiple.py
:start-after: [START send_metrics_batch_query]
:end-before: [END send_metrics_batch_query]
:language: python
Expand Down Expand Up @@ -156,7 +156,7 @@ def close(self) -> None:
"""Close the client session."""
return self._client.close()

def __enter__(self) -> "MetricsBatchQueryClient":
def __enter__(self) -> "MetricsClient":
self._client.__enter__() # pylint:disable=no-member
return self

Expand Down
Expand Up @@ -137,7 +137,6 @@ def query_resource(
orderby=order_by,
filter=filter,
metricnamespace=metric_namespace,
connection_verify=False,
**kwargs
)
return MetricsQueryResult._from_generated(generated) # pylint: disable=protected-access
Expand Down
Expand Up @@ -6,6 +6,6 @@

from ._logs_query_client_async import LogsQueryClient
from ._metrics_query_client_async import MetricsQueryClient
from ._metrics_batch_query_client_async import MetricsBatchQueryClient
from ._metrics_client_async import MetricsClient

__all__ = ["LogsQueryClient", "MetricsQueryClient", "MetricsBatchQueryClient"]
__all__ = ["LogsQueryClient", "MetricsQueryClient", "MetricsClient"]
Expand Up @@ -19,8 +19,8 @@
JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object


class MetricsBatchQueryClient: # pylint: disable=client-accepts-api-version-keyword
"""MetricsBatchQueryClient should be used for performing metrics queries on multiple monitored resources in the
class MetricsClient: # pylint: disable=client-accepts-api-version-keyword
"""MetricsClient should be used for performing metrics queries on multiple monitored resources in the
same region. A credential with authorization at the subscription level is required when using this client.
:param str endpoint: The regional endpoint to use, for example
Expand Down Expand Up @@ -48,12 +48,12 @@ def __init__(self, endpoint: str, credential: AsyncTokenCredential, **kwargs: An
self._batch_metrics_op = self._client.metrics_batch

@distributed_trace_async
async def query_batch(
async def query_resources(
self,
*,
resource_uris: Sequence[str],
metric_names: Sequence[str],
metric_namespace: str,
*,
metric_names: Sequence[str],
timespan: Optional[Union[timedelta, Tuple[datetime, timedelta], Tuple[datetime, datetime]]] = None,
granularity: Optional[timedelta] = None,
aggregations: Optional[Sequence[str]] = None,
Expand All @@ -65,12 +65,12 @@ async def query_batch(
) -> List[MetricsQueryResult]:
"""Lists the metric values for multiple resources.
:param resource_uris: A list of resource URIs to query metrics for. Required.
:type resource_uris: list[str]
:param metric_names: The names of the metrics (comma separated) to retrieve. Required.
:type metric_names: list[str]
:param metric_namespace: Metric namespace that contains the requested metric names. Required.
:type metric_namespace: str
:keyword resource_uris: A list of resource URIs to query metrics for. Required.
:paramtype resource_uris: list[str]
:keyword metric_namespace: Metric namespace that contains the requested metric names. Required.
:paramtype metric_namespace: str
:keyword metric_names: The names of the metrics (comma separated) to retrieve. Required.
:paramtype metric_names: list[str]
:keyword timespan: The timespan for which to query the data. This can be a timedelta,
a timedelta and a start datetime, or a start datetime/end datetime.
:paramtype timespan: Optional[Union[~datetime.timedelta, tuple[~datetime.datetime, ~datetime.timedelta],
Expand Down Expand Up @@ -110,7 +110,7 @@ async def query_batch(
.. admonition:: Example:
.. literalinclude:: ../samples/async_samples/sample_metrics_batch_query_async.py
.. literalinclude:: ../samples/async_samples/sample_metrics_query_multiple_async.py
:start-after: [START send_metrics_batch_query_async]
:end-before: [END send_metrics_batch_query_async]
:language: python
Expand Down Expand Up @@ -153,7 +153,7 @@ async def query_batch(
for value in generated["values"]
]

async def __aenter__(self) -> "MetricsBatchQueryClient":
async def __aenter__(self) -> "MetricsClient":
await self._client.__aenter__()
return self

Expand Down
Expand Up @@ -138,7 +138,6 @@ async def query_resource(
orderby=order_by,
filter=filter,
metricnamespace=metric_namespace,
connection_verify=False,
**kwargs
)
return MetricsQueryResult._from_generated(generated) # pylint: disable=protected-access
Expand Down
4 changes: 2 additions & 2 deletions sdk/monitor/azure-monitor-query/samples/README.md
Expand Up @@ -35,13 +35,13 @@ For examples on authenticating with the Azure Monitor service, see [sample_authe
### Metrics query samples

- [Send a query using MetricsQueryClient](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_metrics_query.py) ([async sample](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metrics_query_async.py))
- [Send a batch of queries using MetricBatchQueryClient](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_metrics_batch_query.py) ([async sample](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metrics_batch_query_async.py))
- [Send a query to multiple resources at once using MetricsClient](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_metrics_query_multiple.py) ([async sample](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metrics_query_multiple_async.py))
- [Get a list of metric namespaces](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_metric_namespaces.py) ([async sample](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metric_namespaces_async.py))
- [Get a list of metric definitions](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_metric_definitions.py) ([async sample](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metric_definitions_async.py))

## Prerequisites

- Python 3.7 or later
- Python 3.8 or later
- An [Azure subscription][azure_subscription]
- To query Logs, you need an [Azure Log Analytics workspace][azure_monitor_create_using_portal].
- To query Metrics, you need an Azure resource of any kind (Storage Account, Key Vault, Cosmos DB, etc.).
Expand Down

0 comments on commit 6a3df96

Please sign in to comment.