Skip to content
Merged

Lint #19120

Show file tree
Hide file tree
Changes from all 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
8 changes: 7 additions & 1 deletion sdk/monitor/azure-monitor-query/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# Release History

## 1.0.0b1 (Unreleased)
## 1.0.0b1 (Unreleased)

**Features**
- Version (1.0.0b1) is the first preview of our efforts to create a user-friendly and Pythonic client library for Azure Monitor Query.
For more information about this, and preview releases of other Azure SDK libraries, please visit https://azure.github.io/azure-sdk/releases/latest/python.html.
- Added `LogsQueryClient` to query log analytics.
- Implements the `MetricsQueryClient` for querying metrics, listing namespaces and metric definitions.
10 changes: 6 additions & 4 deletions sdk/monitor/azure-monitor-query/azure/monitor/query/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,19 @@ def order_results(request_order, responses):
return ordered

def construct_iso8601(start=None, end=None, duration=None):
iso_str = None
if start is not None:
start = Serializer.serialize_iso(start)
if end is not None:
end = Serializer.serialize_iso(end)
return start + '/' + end
iso_str = start + '/' + end
elif duration is not None:
return start + '/' + duration
iso_str = start + '/' + duration
else:
raise ValueError("Start time must be provided aling with duration or end time.")
elif end is not None:
end = Serializer.serialize_iso(end)
return duration + '/' + end
iso_str = duration + '/' + end
else:
return duration
iso_str = duration
return iso_str
Original file line number Diff line number Diff line change
Expand Up @@ -39,25 +39,28 @@ def __init__(self, credential, **kwargs):
)
self._query_op = self._client.query

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

Executes an Analytics query for data.

**Note**: Although the start_time, end_time, duration are optional parameters, it is highly
recommended to specify the timespan. If not, the entire dataset is queried.

:param workspace_id: ID of the workspace. This is Workspace ID from the Properties blade in the
Azure portal.
:type workspace_id: str
: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
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'.
: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
with either start_time or duration.
:keyword str 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'.
:keyword int server_timeout: the server timeout in seconds. The default timeout is 3 minutes,
and the maximum timeout is 10 minutes.
:keyword bool include_statistics: To get information about query statistics.
Expand All @@ -78,7 +81,6 @@ def query(self, workspace_id, query, **kwargs):
"""
start = kwargs.pop('start_time', None)
end = kwargs.pop('end_time', None)
duration = kwargs.pop('duration', None)
timespan = construct_iso8601(start, end, duration)
include_statistics = kwargs.pop("include_statistics", False)
include_render = kwargs.pop("include_render", False)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,24 @@ def __init__(self, credential, **kwargs):
self._namespace_op = self._client.metric_namespaces
self._definitions_op = self._client.metric_definitions

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

**Note**: Although the start_time, end_time, duration are optional parameters, it is highly
recommended to specify the timespan. If not, the entire dataset is queried.

:param resource_uri: The identifier of the resource.
: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
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'.
: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
with either start_time or duration.
:keyword str 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'.
:keyword interval: The interval (i.e. timegrain) of the query.
:paramtype interval: ~datetime.timedelta
:keyword aggregation: The list of aggregation types (comma separated) to retrieve.
Expand Down Expand Up @@ -91,7 +94,6 @@ def query(self, resource_uri, metric_names, **kwargs):
"""
start = kwargs.pop('start_time', None)
end = kwargs.pop('end_time', None)
duration = kwargs.pop('duration', None)
timespan = construct_iso8601(start, end, duration)
kwargs.setdefault("metricnames", ",".join(metric_names))
kwargs.setdefault("timespan", timespan)
Expand Down
17 changes: 12 additions & 5 deletions sdk/monitor/azure-monitor-query/azure/monitor/query/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import uuid
from typing import Any, Optional, List

from ._helpers import order_results
from ._helpers import order_results, construct_iso8601
from ._generated.models import (
Column as InternalColumn,
QueryBody as InternalQueryBody,
Expand Down Expand Up @@ -154,9 +154,13 @@ 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 timespan: The timespan (in ISO8601 duration format) in which to run the query.
If this parameter is not specified, the query will run over all data.
:type timespan: str
:param str 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'.
: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
with either start_time or duration.
:param workspace: Workspace Id to be included in the query.
:type workspace: str
:keyword request_id: The error details.
Expand All @@ -165,9 +169,12 @@ class LogsQueryRequest(InternalLogQueryRequest):
:paramtype headers: dict[str, str]
"""

def __init__(self, query, workspace, timespan=None, **kwargs):
def __init__(self, query, workspace, duration=None, **kwargs):
# type: (str, str, Optional[str], Any) -> None
super(LogsQueryRequest, self).__init__(**kwargs)
start = kwargs.pop('start_time', None)
end = kwargs.pop('end_time', None)
timespan = construct_iso8601(start, end, duration)
self.id = kwargs.get("request_id", str(uuid.uuid4()))
self.headers = kwargs.get("headers", None)
self.body = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ def get_metrics_authentication_policy(
if hasattr(credential, "get_token"):
return AsyncBearerTokenCredentialPolicy(credential, "https://management.azure.com/.default")

raise TypeError("Unsupported credential")
raise TypeError("Unsupported credential")
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,32 @@ def __init__(self, credential: "AsyncTokenCredential", **kwargs: Any) -> None:
)
self._query_op = self._client.query

async def query(self, workspace_id: str, query: str, **kwargs: Any) -> LogsQueryResults:
async def query(
self,
workspace_id: str,
query: str,
duration: str = None,
**kwargs: Any) -> LogsQueryResults:
"""Execute an Analytics query.

Executes an Analytics query for data.

**Note**: Although the start_time, end_time, duration are optional parameters, it is highly
recommended to specify the timespan. If not, the entire dataset is queried.

:param workspace_id: ID of the workspace. This is Workspace ID from the Properties blade in the
Azure portal.
:type workspace_id: str
: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
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'.
: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
with either start_time or duration.
:keyword str 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'.
:keyword int server_timeout: the server timeout. The default timeout is 3 minutes,
and the maximum timeout is 10 minutes.
:keyword bool include_statistics: To get information about query statistics.
Expand All @@ -75,7 +83,6 @@ async def query(self, workspace_id: str, query: str, **kwargs: Any) -> LogsQuery
"""
start = kwargs.pop('start_time', None)
end = kwargs.pop('end_time', None)
duration = kwargs.pop('duration', None)
timespan = construct_iso8601(start, end, duration)
include_statistics = kwargs.pop("include_statistics", False)
include_render = kwargs.pop("include_render", False)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,23 @@ 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, **kwargs: Any) -> MetricsResult:
async def query(self, resource_uri: str, metric_names: List, duration: str = 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
recommended to specify the timespan. If not, the entire dataset is queried.

:param resource_uri: The identifier of the resource.
: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
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'.
: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
with either start_time or duration.
:keyword str 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'.
:keyword interval: The interval (i.e. timegrain) of the query.
:paramtype interval: ~datetime.timedelta
:keyword aggregation: The list of aggregation types (comma separated) to retrieve.
Expand Down Expand Up @@ -89,7 +92,6 @@ async def query(self, resource_uri: str, metric_names: List, **kwargs: Any) -> M
"""
start = kwargs.pop('start_time', None)
end = kwargs.pop('end_time', None)
duration = kwargs.pop('duration', None)
timespan = construct_iso8601(start, end, duration)
kwargs.setdefault("metricnames", ",".join(metric_names))
kwargs.setdefault("timespan", timespan)
Expand Down
46 changes: 19 additions & 27 deletions sdk/monitor/azure-monitor-query/samples/sample_batch_query.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

from datetime import datetime
import os
import pandas as pd
from azure.monitor.query import LogsQueryClient
from azure.monitor.query import LogsQueryClient, LogsQueryRequest
from azure.identity import ClientSecretCredential


Expand All @@ -16,37 +17,28 @@
client = LogsQueryClient(credential)

requests = [
{
"id": "1",
"headers": {
"Content-Type": "application/json"
},
"body": {
"query": "AzureActivity | summarize count()",
"timespan": "PT1H"
},
"method": "POST",
"path": "/query",
"workspace": os.environ['LOG_WORKSPACE_ID']
},
{
"id": "2",
"headers": {
"Content-Type": "application/json"
},
"body": {
"query": "AzureActivity | summarize count()",
"timespan": "PT1H"
},
"method": "POST",
"path": "/fakePath",
"workspace": os.environ['LOG_WORKSPACE_ID']
}
LogsQueryRequest(
query="AzureActivity | summarize count()",
duration="PT1H",
workspace= os.environ['LOG_WORKSPACE_ID']
),
LogsQueryRequest(
query= """AppRequests | take 10 |
summarize avgRequestDuration=avg(DurationMs) by bin(TimeGenerated, 10m), _ResourceId""",
duration="PT1H",
start_time=datetime(2021, 6, 2),
workspace= os.environ['LOG_WORKSPACE_ID']
),
LogsQueryRequest(
query= "AppRequests | take 2",
workspace= os.environ['LOG_WORKSPACE_ID']
),
]
response = client.batch_query(requests)

for response in response.responses:
body = response.body
print(response.id)
if not body.tables:
print("Something is wrong")
else:
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 azure.monitor.query import LogsQueryClient, LogsQueryRequest
from azure.monitor.query import LogsQueryClient
from azure.identity import ClientSecretCredential


Expand All @@ -16,27 +16,37 @@
client = LogsQueryClient(credential)

requests = [
LogsQueryRequest(
query="AzureActivity | summarize count()",
timespan="PT1H",
workspace= os.environ['LOG_WORKSPACE_ID']
),
LogsQueryRequest(
query= """AppRequests | take 10 |
summarize avgRequestDuration=avg(DurationMs) by bin(TimeGenerated, 10m), _ResourceId""",
timespan="PT1H",
workspace= os.environ['LOG_WORKSPACE_ID']
),
LogsQueryRequest(
query= "AppRequests | take 2",
workspace= os.environ['LOG_WORKSPACE_ID']
),
{
"id": "1",
"headers": {
"Content-Type": "application/json"
},
"body": {
"query": "AzureActivity | summarize count()",
"timespan": "PT1H"
},
"method": "POST",
"path": "/query",
"workspace": os.environ['LOG_WORKSPACE_ID']
},
{
"id": "2",
"headers": {
"Content-Type": "application/json"
},
"body": {
"query": "AzureActivity | summarize count()",
"timespan": "PT1H"
},
"method": "POST",
"path": "/fakePath",
"workspace": os.environ['LOG_WORKSPACE_ID']
}
]
response = client.batch_query(requests)

for response in response.responses:
body = response.body
print(response.id)
if not body.tables:
print("Something is wrong")
else:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
summarize avgRequestDuration=avg(DurationMs) by bin(TimeGenerated, 10m), _ResourceId"""

# returns LogsQueryResults
response = client.query(os.environ['LOG_WORKSPACE_ID'], query)
response = client.query(os.environ['LOG_WORKSPACE_ID'], query, start_time=datetime(2021, 6, 2), end_time=datetime.now())

if not response.tables:
print("No results for the query")
Expand Down