Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Monitor Query] Update metrics batch query client #33958

Merged
merged 1 commit into from Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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,
kashifkhan marked this conversation as resolved.
Show resolved Hide resolved
**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