diff --git a/sdk/monitor/azure-monitor-query/CHANGELOG.md b/sdk/monitor/azure-monitor-query/CHANGELOG.md
index 73082cae16b5..c4860b306f48 100644
--- a/sdk/monitor/azure-monitor-query/CHANGELOG.md
+++ b/sdk/monitor/azure-monitor-query/CHANGELOG.md
@@ -1,3 +1,9 @@
# Release History
-## 1.0.0b1 (Unreleased)
\ No newline at end of file
+## 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.
diff --git a/sdk/monitor/azure-monitor-query/azure/monitor/query/_helpers.py b/sdk/monitor/azure-monitor-query/azure/monitor/query/_helpers.py
index 8dc7dec0c88a..7ee12be0a0be 100644
--- a/sdk/monitor/azure-monitor-query/azure/monitor/query/_helpers.py
+++ b/sdk/monitor/azure-monitor-query/azure/monitor/query/_helpers.py
@@ -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
diff --git a/sdk/monitor/azure-monitor-query/azure/monitor/query/_log_query_client.py b/sdk/monitor/azure-monitor-query/azure/monitor/query/_log_query_client.py
index 024d3afdfcfa..90995516a64b 100644
--- a/sdk/monitor/azure-monitor-query/azure/monitor/query/_log_query_client.py
+++ b/sdk/monitor/azure-monitor-query/azure/monitor/query/_log_query_client.py
@@ -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
`_.
: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.
@@ -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)
diff --git a/sdk/monitor/azure-monitor-query/azure/monitor/query/_metrics_query_client.py b/sdk/monitor/azure-monitor-query/azure/monitor/query/_metrics_query_client.py
index c2ea123955f6..d2560264714e 100644
--- a/sdk/monitor/azure-monitor-query/azure/monitor/query/_metrics_query_client.py
+++ b/sdk/monitor/azure-monitor-query/azure/monitor/query/_metrics_query_client.py
@@ -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.
@@ -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)
diff --git a/sdk/monitor/azure-monitor-query/azure/monitor/query/_models.py b/sdk/monitor/azure-monitor-query/azure/monitor/query/_models.py
index f84a258d2119..cf1e1a90af9c 100644
--- a/sdk/monitor/azure-monitor-query/azure/monitor/query/_models.py
+++ b/sdk/monitor/azure-monitor-query/azure/monitor/query/_models.py
@@ -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,
@@ -154,9 +154,13 @@ class LogsQueryRequest(InternalLogQueryRequest):
:param query: The Analytics query. Learn more about the `Analytics query syntax
`_.
: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.
@@ -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 = {
diff --git a/sdk/monitor/azure-monitor-query/azure/monitor/query/aio/_helpers_asyc.py b/sdk/monitor/azure-monitor-query/azure/monitor/query/aio/_helpers_asyc.py
index cb0769376e61..0dc26a8903a4 100644
--- a/sdk/monitor/azure-monitor-query/azure/monitor/query/aio/_helpers_asyc.py
+++ b/sdk/monitor/azure-monitor-query/azure/monitor/query/aio/_helpers_asyc.py
@@ -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")
\ No newline at end of file
+ raise TypeError("Unsupported credential")
diff --git a/sdk/monitor/azure-monitor-query/azure/monitor/query/aio/_log_query_client_async.py b/sdk/monitor/azure-monitor-query/azure/monitor/query/aio/_log_query_client_async.py
index 1eb4cc5229c3..cc743a7f8f5c 100644
--- a/sdk/monitor/azure-monitor-query/azure/monitor/query/aio/_log_query_client_async.py
+++ b/sdk/monitor/azure-monitor-query/azure/monitor/query/aio/_log_query_client_async.py
@@ -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
`_.
: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.
@@ -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)
diff --git a/sdk/monitor/azure-monitor-query/azure/monitor/query/aio/_metrics_query_client_async.py b/sdk/monitor/azure-monitor-query/azure/monitor/query/aio/_metrics_query_client_async.py
index 2189385f4dff..462e66a72ce8 100644
--- a/sdk/monitor/azure-monitor-query/azure/monitor/query/aio/_metrics_query_client_async.py
+++ b/sdk/monitor/azure-monitor-query/azure/monitor/query/aio/_metrics_query_client_async.py
@@ -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.
@@ -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)
diff --git a/sdk/monitor/azure-monitor-query/samples/sample_batch_query.py b/sdk/monitor/azure-monitor-query/samples/sample_batch_query.py
index a0ec5658a5a8..fc2f63d68aae 100644
--- a/sdk/monitor/azure-monitor-query/samples/sample_batch_query.py
+++ b/sdk/monitor/azure-monitor-query/samples/sample_batch_query.py
@@ -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
@@ -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:
diff --git a/sdk/monitor/azure-monitor-query/samples/sample_batch_query_build.py b/sdk/monitor/azure-monitor-query/samples/sample_batch_query_serialized.py
similarity index 51%
rename from sdk/monitor/azure-monitor-query/samples/sample_batch_query_build.py
rename to sdk/monitor/azure-monitor-query/samples/sample_batch_query_serialized.py
index 4c9a3e6f24c2..a0ec5658a5a8 100644
--- a/sdk/monitor/azure-monitor-query/samples/sample_batch_query_build.py
+++ b/sdk/monitor/azure-monitor-query/samples/sample_batch_query_serialized.py
@@ -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
@@ -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:
diff --git a/sdk/monitor/azure-monitor-query/samples/sample_log_query_client.py b/sdk/monitor/azure-monitor-query/samples/sample_log_query_client.py
index 4e34fa83f327..3e20c82ce773 100644
--- a/sdk/monitor/azure-monitor-query/samples/sample_log_query_client.py
+++ b/sdk/monitor/azure-monitor-query/samples/sample_log_query_client.py
@@ -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")