Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sdk/monitor/azure-monitor-query/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- `workspaces`, `workspace_ids`, `qualified_names` and `azure_resource_ids` are now merged into a single `additional_workspaces` list in the query API.
- The `LogQueryRequest` object now takes in a `workspace_id` and `additional_workspaces` instead of `workspace`.
- `aggregation` param is now a list instead of a string in the `query` method.
- `duration` must now be provided as a timedelta instead of a string.

### Key Bugs Fixed

Expand Down
8 changes: 5 additions & 3 deletions sdk/monitor/azure-monitor-query/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ This sample shows sending multiple queries at the same time using batch query AP

```Python
import os
from datetime import timedelta
import pandas as pd
from azure.monitor.query import LogsQueryClient, LogsQueryRequest
from azure.identity import ClientSecretCredential
Expand All @@ -169,13 +170,13 @@ client = LogsQueryClient(credential)
requests = [
LogsQueryRequest(
query="AzureActivity | summarize count()",
duration="PT1H",
duration=timedelta(hours=1),
workspace= os.environ['LOG_WORKSPACE_ID']
),
LogsQueryRequest(
query= """AppRequests | take 10 |
summarize avgRequestDuration=avg(DurationMs) by bin(TimeGenerated, 10m), _ResourceId""",
duration="PT1H",
duration=timedelta(hours=1),
start_time=datetime(2021, 6, 2),
workspace= os.environ['LOG_WORKSPACE_ID']
),
Expand Down Expand Up @@ -228,6 +229,7 @@ This example shows getting the metrics for an EventGrid subscription. The resour

```Python
import os
from datetime import timedelta
from azure.monitor.query import MetricsQueryClient
from azure.identity import ClientSecretCredential

Expand All @@ -245,7 +247,7 @@ response = client.query(
metrics_uri,
metric_names=["PublishSuccessCount"],
start_time=datetime(2021, 5, 25),
duration='P1D'
duration=timedelta(days=1),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indent?

)

for metric in response.metrics:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ def order_results(request_order, responses):
return ordered

def construct_iso8601(start=None, end=None, duration=None):
if duration is not None:
duration = 'PT{}S'.format(duration.total_seconds())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use isinstance?

If user uses a class that has total_seconds property, is it valid?

Copy link
Member

@xiangyan99 xiangyan99 Jun 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if duration is None in line 69 & 71?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed to if duration is not None

  • for the second question - it's okay to be None

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to confirm, you mean

end = Serializer.serialize_iso(end)
iso_str = None + '/' + end

is valid?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops - line 69-71 got changed when i made the changes :)
nope = iso_str = None + '/' + end is not a valid format - although end must be provided with a duration

  • it's worth improving the message :)

iso_str = None
if start is not None:
start = Serializer.serialize_iso(start)
Expand All @@ -61,6 +63,8 @@ def construct_iso8601(start=None, end=None, duration=None):
else:
raise ValueError("Start time must be provided aling with duration or end time.")
elif end is not None:
if not duration:
raise ValueError("End time must be provided aling with duration or start time.")
end = Serializer.serialize_iso(end)
iso_str = duration + '/' + end
else:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# license information.
# --------------------------------------------------------------------------

from typing import TYPE_CHECKING, Any, Union, Sequence, Dict
from typing import TYPE_CHECKING, Any, Union, Sequence, Dict, Optional
from azure.core.exceptions import HttpResponseError

from ._generated._monitor_query_client import MonitorQueryClient
Expand All @@ -16,6 +16,7 @@

if TYPE_CHECKING:
from azure.core.credentials import TokenCredential
from datetime import timedelta


class LogsQueryClient(object):
Expand Down Expand Up @@ -49,7 +50,7 @@ def __init__(self, credential, **kwargs):
self._query_op = self._client.query

def query(self, workspace_id, query, duration=None, **kwargs):
# type: (str, str, str, Any) -> LogsQueryResults
# type: (str, str, Optional[timedelta], Any) -> LogsQueryResults
"""Execute an Analytics query.

Executes an Analytics query for data.
Expand All @@ -63,9 +64,9 @@ def query(self, workspace_id, query, duration=None, **kwargs):
:param query: The Analytics query. Learn more about the `Analytics query syntax
<https://azure.microsoft.com/documentation/articles/app-insights-analytics-reference/>`_.
:type query: str
:param str duration: The duration for which to query the data. This can also be accompanied
:param ~datetime.timedelta duration: The duration for which to query the data. This can also be accompanied
with either start_time or end_time. If start_time or end_time is not provided, the current time is
taken as the end time. This should be provided in a ISO8601 string format like 'PT1H', 'P1Y2M10DT2H30M'.
taken as the end time.
:keyword datetime start_time: The start time from which to query the data. This should be accompanied
with either end_time or duration.
:keyword datetime end_time: The end time till which to query the data. This should be accompanied
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

# pylint: disable=anomalous-backslash-in-string

from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING, Any, Optional

from ._generated._monitor_query_client import (
MonitorQueryClient,
Expand All @@ -17,6 +17,7 @@
from ._helpers import get_metrics_authentication_policy, construct_iso8601

if TYPE_CHECKING:
from datetime import timedelta
from azure.core.credentials import TokenCredential
from azure.core.paging import ItemPaged

Expand Down Expand Up @@ -53,7 +54,7 @@ def __init__(self, credential, **kwargs):
self._definitions_op = self._client.metric_definitions

def query(self, resource_uri, metric_names, duration=None, **kwargs):
# type: (str, list, str, Any) -> MetricsResult
# type: (str, list, Optional[timedelta], Any) -> MetricsResult
"""Lists the metric values for a resource.

**Note**: Although the start_time, end_time, duration are optional parameters, it is highly
Expand All @@ -63,9 +64,9 @@ def query(self, resource_uri, metric_names, duration=None, **kwargs):
:type resource_uri: str
:param metric_names: The names of the metrics to retrieve.
:type metric_names: list[str]
:param str duration: The duration for which to query the data. This can also be accompanied
:param ~datetime.timedelta duration: The duration for which to query the data. This can also be accompanied
with either start_time or end_time. If start_time or end_time is not provided, the current time is
taken as the end time. This should be provided in a ISO8601 string format like 'PT1H', 'P1Y2M10DT2H30M'.
taken as the end time.
:keyword datetime start_time: The start time from which to query the data. This should be accompanied
with either end_time or duration.
:keyword datetime end_time: The end time till which to query the data. This should be accompanied
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ class LogsQueryRequest(InternalLogQueryRequest):
:param query: The Analytics query. Learn more about the `Analytics query syntax
<https://azure.microsoft.com/documentation/articles/app-insights-analytics-reference/>`_.
:type query: str
:param str duration: The duration for which to query the data. This can also be accompanied
:param ~datetime.timedelta duration: The duration for which to query the data. This can also be accompanied
with either start_time or end_time. If start_time or end_time is not provided, the current time is
taken as the end time. This should be provided in a ISO8601 string format like 'PT1H', 'P1Y2M10DT2H30M'.
taken as the end time.
:keyword datetime start_time: The start time from which to query the data. This should be accompanied
with either end_time or duration.
:keyword datetime end_time: The end time till which to query the data. This should be accompanied
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
# license information.
# --------------------------------------------------------------------------

from typing import Any, Union, Sequence, Dict, TYPE_CHECKING
from datetime import timedelta
from typing import Any, Union, Sequence, Dict, Optional, TYPE_CHECKING
from azure.core.exceptions import HttpResponseError
from .._generated.aio._monitor_query_client import MonitorQueryClient

Expand Down Expand Up @@ -41,7 +42,7 @@ async def query(
self,
workspace_id: str,
query: str,
duration: str = None,
duration: Optional[timedelta] = None,
**kwargs: Any) -> LogsQueryResults:
"""Execute an Analytics query.

Expand All @@ -56,9 +57,9 @@ async def query(
:param query: The Analytics query. Learn more about the `Analytics query syntax
<https://azure.microsoft.com/documentation/articles/app-insights-analytics-reference/>`_.
:type query: str
:param str duration: The duration for which to query the data. This can also be accompanied
:param ~datetime.timedelta duration: The duration for which to query the data. This can also be accompanied
with either start_time or end_time. If start_time or end_time is not provided, the current time is
taken as the end time. This should be provided in a ISO8601 string format like 'PT1H', 'P1Y2M10DT2H30M'.
taken as the end time.
:keyword datetime start_time: The start time from which to query the data. This should be accompanied
with either end_time or duration.
:keyword datetime end_time: The end time till which to query the data. This should be accompanied
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

# pylint: disable=anomalous-backslash-in-string

from typing import TYPE_CHECKING, Any, List
from datetime import timedelta
from typing import TYPE_CHECKING, Any, List, Optional

from azure.core.async_paging import AsyncItemPaged

Expand Down Expand Up @@ -42,7 +43,13 @@ def __init__(self, credential: "AsyncTokenCredential", **kwargs: Any) -> None:
self._namespace_op = self._client.metric_namespaces
self._definitions_op = self._client.metric_definitions

async def query(self, resource_uri: str, metric_names: List, duration: str = None, **kwargs: Any) -> MetricsResult:
async def query(
self,
resource_uri: str,
metric_names: List,
duration: Optional[timedelta] = None,
**kwargs: Any
) -> MetricsResult:
"""Lists the metric values for a resource.

**Note**: Although the start_time, end_time, duration are optional parameters, it is highly
Expand All @@ -52,9 +59,9 @@ async def query(self, resource_uri: str, metric_names: List, duration: str = Non
:type resource_uri: str
:param metric_names: The names of the metrics to retrieve.
:type metric_names: list
:param str duration: The duration for which to query the data. This can also be accompanied
:param ~datetime.timedelta duration: The duration for which to query the data. This can also be accompanied
with either start_time or end_time. If start_time or end_time is not provided, the current time is
taken as the end time. This should be provided in a ISO8601 string format like 'PT1H', 'P1Y2M10DT2H30M'.
taken as the end time.
:keyword datetime start_time: The start time from which to query the data. This should be accompanied
with either end_time or duration.
:keyword datetime end_time: The end time till which to query the data. This should be accompanied
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import os
import asyncio
from datetime import datetime
from datetime import datetime, timedelta
import urllib3
from azure.monitor.query.aio import MetricsQueryClient
from azure.identity.aio import ClientSecretCredential
Expand All @@ -25,7 +25,7 @@ async def query_metrics():
metrics_uri,
metric_names=["PublishSuccessCount"],
start_time=datetime(2021, 5, 25),
duration='P1D'
duration=timedelta(days=1)
)

for metric in response.metrics:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

from datetime import datetime
from datetime import datetime, timedelta
import os
import pandas as pd
from azure.monitor.query import LogsQueryClient, LogsQueryRequest
Expand All @@ -20,13 +20,13 @@
requests = [
LogsQueryRequest(
query="AzureActivity | summarize count()",
duration="PT1H",
duration=timedelta(hours=1),
workspace_id= os.environ['LOG_WORKSPACE_ID']
),
LogsQueryRequest(
query= """AppRequests | take 10 |
summarize avgRequestDuration=avg(DurationMs) by bin(TimeGenerated, 10m), _ResourceId""",
duration="PT1H",
duration=timedelta(hours=1),
start_time=datetime(2021, 6, 2),
workspace_id= os.environ['LOG_WORKSPACE_ID']
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import os
import pandas as pd
from datetime import datetime
from datetime import datetime, timedelta
from msrest.serialization import UTC
from azure.monitor.query import LogsQueryClient
from azure.identity import ClientSecretCredential
Expand All @@ -27,7 +27,7 @@
end_time = datetime.now(UTC())

# returns LogsQueryResults
response = client.query(os.environ['LOG_WORKSPACE_ID'], query, duration='PT1H', end_time=end_time)
response = client.query(os.environ['LOG_WORKSPACE_ID'], query, duration=timedelta(days=1), end_time=end_time)

if not response.tables:
print("No results for the query")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Licensed under the MIT License.

import os
from datetime import datetime
from datetime import datetime, timedelta
from msrest.serialization import UTC
from azure.monitor.query import LogsQueryClient
from azure.identity import ClientSecretCredential
Expand All @@ -23,7 +23,7 @@
end_time = datetime.now(UTC())

# returns LogsQueryResults
response = client.query(os.environ['LOG_WORKSPACE_ID'], query, duration='PT1H', end_time=end_time)
response = client.query(os.environ['LOG_WORKSPACE_ID'], query, duration=timedelta(hours=1), end_time=end_time)

if not response.tables:
print("No results for the query")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
metrics_uri,
metric_names=["MatchedEventCount"],
start_time=datetime(2021, 6, 21),
duration='P1D',
duration=timedelta(days=1),
aggregation=['Count']
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, time, timedelta
import pytest
import os
from azure.identity.aio import ClientSecretCredential
Expand All @@ -20,7 +20,7 @@ async def test_metrics_auth():
os.environ['METRICS_RESOURCE_URI'],
metric_names=["MatchedEventCount"],
start_time=datetime(2021, 6, 21),
duration='P1D',
duration=timedelta(days=1),
aggregation=['Count']
)
assert response
Expand Down
Loading