Skip to content

Commit 3156895

Browse files
pvaneckscottaddie
andauthored
[Monitor Query] Add v2 migration guide (#42263)
Migration guide added for the 2.0.0 azure-monitor-query library. Signed-off-by: Paul Van Eck <[email protected]> Co-authored-by: Scott Addie <[email protected]>
1 parent ba363c4 commit 3156895

File tree

2 files changed

+335
-0
lines changed

2 files changed

+335
-0
lines changed

sdk/monitor/azure-monitor-query/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ The Azure Monitor Query client library is used to execute read-only queries agai
44

55
- [Logs](https://learn.microsoft.com/azure/azure-monitor/logs/data-platform-logs) - Collects and organizes log and performance data from monitored resources. Data from different sources such as platform logs from Azure services, log and performance data from virtual machines agents, and usage and performance data from apps can be consolidated into a single [Azure Log Analytics workspace](https://learn.microsoft.com/azure/azure-monitor/logs/data-platform-logs#log-analytics-and-workspaces). The various data types can be analyzed together using the [Kusto Query Language][kusto_query_language].
66

7+
> **Important**: As of version 2.0.0, `MetricsClient` and `MetricsQueryClient` have been removed from the `azure-monitor-query` package. For metrics querying capabilities, please use the separate [`azure-monitor-querymetrics`](https://pypi.org/project/azure-monitor-querymetrics/) package which provides `MetricsClient`, or the [`azure-mgmt-monitor`](https://pypi.org/project/azure-mgmt-monitor/) package. For more details, see the [migration guide](https://aka.ms/azsdk/python/monitor/query/migration).
8+
79
**Resources:**
810

911
- [Source code][source]
Lines changed: 333 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,333 @@
1+
# Guide to migrating from v1 to v2
2+
3+
Version 2.0.0 of `azure-monitor-query` removes the metrics querying capabilities, which are now handled by separate packages.
4+
This guide assists you in the migration from [azure-monitor-query](https://pypi.org/project/azure-monitor-query/) versions 1.x to 2.x, and outlines how to adapt your code to leverage the new packages for metrics querying.
5+
6+
## Table of contents
7+
8+
- [Quick migration decision tree](#quick-migration-decision-tree)
9+
- [Motivation for v2](#motivation-for-v2)
10+
- [Key changes](#key-changes)
11+
- [Logs querying with LogsQueryClient](#logs-querying-with-logsqueryclient)
12+
- [Metrics querying with MetricsClient](#metrics-querying-with-metricsclient)
13+
- [Metrics operations with MetricsQueryClient](#metrics-operations-with-metricsqueryclient)
14+
- [Querying metrics](#querying-metrics)
15+
- [Listing metric definitions](#listing-metric-definitions)
16+
- [Listing metric namespaces](#listing-metric-namespaces)
17+
- [Common migration tasks](#common-migration-tasks)
18+
19+
## Quick migration decision tree
20+
21+
**Which client are you currently using?**
22+
23+
- **`LogsQueryClient`****No changes needed** - continue using `azure-monitor-query` package
24+
- **`MetricsClient`****Simple migration** - switch to `azure-monitor-querymetrics` package (same API, different import)
25+
- **`MetricsQueryClient`****Choose your path:**
26+
- For **metrics querying**: Use `MetricsClient` from `azure-monitor-querymetrics` (recommended - higher query limits)
27+
- For **full metrics management capabilities**: Use `MonitorManagementClient` from `azure-mgmt-monitor` package (requires code changes)
28+
29+
## Motivation for v2
30+
31+
Historically, the Azure Monitor Query library was a monolithic package that included both Log Analytics and Metrics querying capabilities across 5 different services/endpoints. While this may have seemed convenient, it introduced challenges for users. A single package combining multiple services meant customers couldn’t upgrade one service independently of others. Any breaking change in one service forced updates across all services in the package, disrupting customer workflows.
32+
33+
To address these issues, Azure adopted a formal definition of a service as a set of operations that version uniformly. Each service version now has a dedicated package, documentation, and API contract. This structure allows libraries to be generated directly from [TypeSpec](https://typespec.io/) definitions, improving consistency, reducing manual intervention, and aligning with Azure’s long-term tooling strategy.
34+
35+
With this in mind, the `azure-monitor-query` package will now focus solely on logs querying, while resource metrics querying will be handled by the new `azure-monitor-querymetrics` package and `azure-mgmt-monitor`.
36+
37+
## Key changes
38+
39+
### Logs querying with `LogsQueryClient`
40+
41+
There is **no change** in the way you query logs using the `LogsQueryClient`. The client remains the same, and you can continue to use it as before.
42+
43+
### Metrics querying with `MetricsClient`
44+
45+
The `MetricsClient` has been moved to a separate package called `azure-monitor-querymetrics`. You can install it using:
46+
47+
```bash
48+
pip install azure-monitor-querymetrics
49+
```
50+
51+
The only code change that needs to be made is the import path:
52+
53+
```diff
54+
- from azure.monitor.query import MetricsClient, MetricAggregationType
55+
+ from azure.monitor.querymetrics import MetricsClient, MetricAggregationType
56+
```
57+
58+
### Metrics operations with `MetricsQueryClient`
59+
60+
`MetricsQueryClient` has been removed from `azure-monitor-query`, and its functionality is **not included** in the `azure-monitor-querymetrics` package.
61+
62+
`MetricsQueryClient` provided three functions: `query_resource`, `list_metric_definitions`, and `list_metric_namespaces`. If you were using it for querying metrics from resources, you should consider switching to `MetricsClient` from the [`azure-monitor-querymetrics`](https://pypi.org/project/azure-monitor-querymetrics/) package, which provides similar functionality and higher query limits compared to the [Azure Resource Manager (ARM) APIs](https://learn.microsoft.com/azure/azure-resource-manager/management/request-limits-and-throttling) that `MetricsQueryClient` used.
63+
64+
Otherwise, you can switch to using the `MonitorManagementClient` from the `azure-mgmt-monitor` package, which provides comprehensive Azure Monitor resource management capabilities.
65+
66+
You can install it using:
67+
68+
```bash
69+
pip install azure-mgmt-monitor
70+
```
71+
72+
The APIs are similar, but there are some differences in method names, parameters, and responses. Below are comparisons for each operation.
73+
74+
#### Querying metrics
75+
76+
**Migration**: Use `client.metrics.list()` instead of `client.query_resource()`.
77+
78+
***With `azure-monitor-query 1.x`:***
79+
80+
```python
81+
import os
82+
from datetime import timedelta
83+
84+
from azure.identity import DefaultAzureCredential
85+
from azure.monitor.query import MetricsQueryClient, MetricAggregationType
86+
87+
credential = DefaultAzureCredential()
88+
client = MetricsQueryClient(credential)
89+
90+
resource_uri = os.environ["METRICS_RESOURCE_URI"]
91+
92+
# Query metrics for a specific resource
93+
response = client.query_resource(
94+
resource_uri,
95+
metric_names=["cacheWrite"],
96+
timespan=timedelta(hours=2),
97+
granularity=timedelta(minutes=5),
98+
aggregations=[MetricAggregationType.AVERAGE],
99+
max_results=10,
100+
order_by="average desc",
101+
filter="ShardId eq '0'",
102+
metric_namespace="Microsoft.Cache/Redis",
103+
)
104+
105+
# Process resource metrics query response
106+
for metric in response.metrics:
107+
print(f"Metric Name: {metric.name}")
108+
for timeseries in metric.timeseries:
109+
for data in timeseries.data:
110+
print(f"Timestamp: {data.timestamp}, Average: {data.average}")
111+
```
112+
113+
***With `azure-mgmt-monitor`:***
114+
115+
```python
116+
import os
117+
118+
from azure.identity import DefaultAzureCredential
119+
from azure.mgmt.monitor import MonitorManagementClient
120+
from azure.mgmt.monitor.models import AggregationType
121+
122+
resource_uri = os.environ["METRICS_RESOURCE_URI"]
123+
124+
# If only using non-subscription scoped operations like the ones provided by MetricsQueryClient,
125+
# you can pass in an arbitrary placeholder subscription ID.
126+
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
127+
128+
credential = DefaultAzureCredential()
129+
client = MonitorManagementClient(credential, subscription_id)
130+
131+
# Query metrics for a specific resource
132+
response = client.metrics.list(
133+
resource_uri,
134+
metricnames="cacheWrite",
135+
timespan="2025-07-20T09:00:00Z/2025-07-20T14:00:00Z", # <ISO 8601 Start Time>/<ISO 8601 End Time>
136+
interval="PT5M", # ISO 8601 duration format
137+
aggregation=AggregationType.AVERAGE,
138+
top=10,
139+
orderby="average desc",
140+
filter="ShardId eq '0'",
141+
metricnamespace="Microsoft.Cache/Redis",
142+
)
143+
144+
# Process resource metrics query response
145+
for metric in response.value:
146+
print(f"Metric Name: {metric.name.value}")
147+
for timeseries in metric.timeseries:
148+
for data in timeseries.data:
149+
print(f"Timestamp: {data.time_stamp}, Average: {data.average}")
150+
```
151+
152+
**Parameter changes**:
153+
- `metric_names` becomes `metricnames`
154+
- `timespan` is now an ISO 8601 duration string (e.g., `"PT2H"` for past 2 hours) or a time range (e.g., `"2025-07-20T09:00:00Z/2025-07-20T14:00:00Z"`)
155+
- For guide on converting `timedelta` to ISO 8601, see [Converting datetime and timedelta objects](#converting-datetime-and-timedelta-objects).
156+
- `granularity` is replaced with `interval`, which is also an ISO 8601 duration string
157+
- `aggregations` is replaced with `aggregation`, which is a comma-separated string of aggregation types (e.g., `"Average"`)
158+
- `max_results` is replaced with `top`, which specifies the maximum number of results to return
159+
- `order_by` is replaced with `orderby`, which specifies the order of results
160+
- `metric_namespace` becomes `metricnamespace`, which specifies the namespace of the metrics in string format
161+
162+
**Response structure comparison**:
163+
164+
The response structure has a few minor differences. Below is a comparison of the key attributes in the response.
165+
166+
[comment]: # ( cspell:ignore thead )
167+
168+
<div style="overflow-x: auto; border: 1px solid #ccc; border-radius: 8px; padding: 10px;">
169+
<table style="width: 100%; border-collapse: collapse; min-width: 300px;">
170+
<thead>
171+
<tr>
172+
<th style="padding: 12px; text-align: left; border-bottom: 2px solid #ddd; font-family: 'Inter', sans-serif; border-top-left-radius: 4px; border-top-right-radius: 4px;">MetricsQueryResult (azure-monitor-query)</th>
173+
<th style="padding: 12px; text-align: left; border-bottom: 2px solid #ddd; font-family: 'Inter', sans-serif;">Response (azure-mgmt-monitor)</th>
174+
</tr>
175+
</thead>
176+
<tbody>
177+
<tr>
178+
<td style="padding: 12px; border-bottom: 1px solid #eee; vertical-align:top;">
179+
<pre>
180+
MetricsQueryResult
181+
|---timespan: str
182+
|---granularity: timedelta
183+
|---cost: int
184+
|---namespace: str
185+
|---resource_region: str
186+
|---metrics: List[Metric]
187+
|---id: str
188+
|---type: str
189+
|---name: str
190+
|---unit: str
191+
|---display_description: str
192+
|---timeseries: List[TimeSeriesElement]
193+
|---metadata_values: dict
194+
|---data: List[MetricValue]
195+
|---timestamp: datetime
196+
|---average: float
197+
|---maximum: float
198+
|---minimum: float
199+
|---total: float
200+
|---count: float
201+
</pre>
202+
</td>
203+
<td style="padding: 12px; border-bottom: 1px solid #eee; vertical-align:top;">
204+
<pre>
205+
Response
206+
|---timespan: str
207+
|---interval: str
208+
|---cost: int
209+
|---namespace: str
210+
|---resourceregion: str
211+
|---metrics List[Metric]
212+
|---id: str
213+
|---type: str
214+
|---name: LocalizableString
215+
| |---value: str
216+
|---unit: str | MetricUnit
217+
|---display_description: str
218+
|---timeseries: List[TimeSeriesElement]
219+
|---metadata_values: List[MetadataValue]
220+
| |---name: LocalizableString
221+
| |---value: str
222+
| |---value: str
223+
|---data: List[MetricValue]
224+
|---time_stamp: datetime
225+
|---average: float
226+
|---maximum: float
227+
|---minimum: float
228+
|---total: float
229+
|---count: float
230+
</pre>
231+
</td>
232+
</tr>
233+
</tbody>
234+
</table>
235+
</div>
236+
237+
#### Listing metric definitions
238+
239+
**Migration**: Use `client.metric_definitions.list()` instead of `client.list_metric_definitions()`.
240+
241+
***With `azure-monitor-query 1.x`:***
242+
243+
```python
244+
# Query metric definitions for a specific resource
245+
metric_definitions = client.list_metric_definitions(
246+
resource_uri, namespace="Microsoft.Cache/Redis"
247+
)
248+
249+
for definition in metric_definitions:
250+
print(f"Metric Definition: {definition.name}")
251+
if definition.metric_availabilities:
252+
for availability in definition.metric_availabilities:
253+
print(f"Granularity: {availability.granularity}, Retention: {availability.retention}")
254+
```
255+
256+
***With `azure-mgmt-monitor`:***
257+
258+
```python
259+
# Query metric definitions for a specific resource
260+
metric_definitions = client.metric_definitions.list(resource_uri, metricnamespace="Microsoft.Cache/Redis")
261+
262+
for definition in metric_definitions:
263+
print(f"Metric Definition: {definition.name.value}")
264+
if definition.metric_availabilities:
265+
for availability in definition.metric_availabilities:
266+
print(f"Granularity: {availability.time_grain}, Retention: {availability.retention}")
267+
```
268+
269+
**Parameter changes**:
270+
- `namespace` becomes `metricnamespace`
271+
272+
#### Listing metric namespaces
273+
274+
**Migration**: Use `client.metric_namespaces.list()` instead of `client.list_metric_namespaces()`.
275+
276+
***With `azure-monitor-query 1.x`:***
277+
278+
```python
279+
# Query metric namespaces for a specific resource
280+
metric_namespaces = client.list_metric_namespaces(resource_uri)
281+
282+
for namespace in metric_namespaces:
283+
print(f"Metric Namespace: {namespace.name}")
284+
print(f"Type: {namespace.type}")
285+
print(f"Classification: {namespace.namespace_classification}")
286+
```
287+
288+
***With `azure-mgmt-monitor`:***
289+
290+
```python
291+
# Query metric namespaces for a specific resource
292+
metric_namespaces = client.metric_namespaces.list(resource_uri)
293+
294+
for namespace in metric_namespaces:
295+
print(f"Metric Namespace: {namespace.name}")
296+
print(f"Type: {namespace.type}")
297+
print(f"Classification: {namespace.classification}")
298+
```
299+
300+
## Common migration tasks
301+
302+
### Converting datetime and timedelta objects
303+
304+
When migrating from `MetricsQueryClient` to `MonitorManagementClient`, you'll need to convert Python datetime objects to ISO 8601 strings:
305+
306+
```python
307+
from datetime import datetime, timedelta
308+
309+
# Converting timedelta to ISO 8601 duration
310+
old_timespan = timedelta(hours=2)
311+
new_timespan = f"PT{int(old_timespan.total_seconds()//3600)}H" # "PT2H"
312+
313+
old_granularity = timedelta(minutes=5)
314+
new_interval = f"PT{int(old_granularity.total_seconds()//60)}M" # "PT5M"
315+
316+
# Converting datetime range to ISO 8601 timespan
317+
end_time = datetime.now()
318+
start_time = end_time - timedelta(hours=2)
319+
new_timespan = f"{start_time.isoformat()}/{end_time.isoformat()}"
320+
321+
# For more complex conversions, consider using the isodate package:
322+
# pip install isodate
323+
# import isodate
324+
# new_interval = isodate.duration_isoformat(old_granularity)
325+
```
326+
327+
### Getting help
328+
329+
- **Package documentation**:
330+
- [azure-monitor-query](https://pypi.org/project/azure-monitor-query/)
331+
- [azure-monitor-querymetrics](https://pypi.org/project/azure-monitor-querymetrics/)
332+
- [azure-mgmt-monitor](https://pypi.org/project/azure-mgmt-monitor/)
333+
- **GitHub issues**: [azure-sdk-for-python](https://github.com/Azure/azure-sdk-for-python/issues)

0 commit comments

Comments
 (0)