From 1d1b87c28ea9bc6b2ad50cdb421e46f1a548a8c3 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Mon, 27 Sep 2021 10:14:42 -0700 Subject: [PATCH] Query - samples + README + docstrings (#20869) * Samples fix * README * docstrings * mypy * lint * test fix * lint --- sdk/monitor/azure-monitor-query/README.md | 153 ++++++++++++------ .../azure/monitor/query/_exceptions.py | 2 - .../azure/monitor/query/_helpers.py | 3 +- .../azure/monitor/query/_logs_query_client.py | 29 ++-- .../monitor/query/_metrics_query_client.py | 17 +- .../azure/monitor/query/_models.py | 45 ++---- .../query/aio/_logs_query_client_async.py | 27 ++-- .../query/aio/_metrics_query_client_async.py | 10 +- .../azure-monitor-query/samples/README.md | 58 +++++-- .../async_samples/sample_log_query_async.py | 56 +++++++ .../sample_log_query_client_async.py | 70 -------- .../sample_metric_definitions_async.py | 16 +- .../sample_metric_namespaces_async.py | 14 ++ ...async.py => sample_metrics_query_async.py} | 21 ++- .../samples/sample_batch_query.py | 33 +++- .../samples/sample_batch_query_serialized.py | 50 ------ .../sample_log_query_client_without_pandas.py | 46 ------ .../sample_log_query_multiple_workspaces.py | 56 ++++--- .../sample_logs_query_key_value_form.py | 73 ++++----- ..._client.py => sample_logs_single_query.py} | 27 +++- ...sample_logs_single_query_partial_result.py | 60 +++++++ .../samples/sample_metric_definitions.py | 22 ++- .../samples/sample_metric_namespaces.py | 14 ++ .../samples/sample_metrics_query.py | 52 ++++++ .../samples/sample_metrics_query_client.py | 36 ----- .../samples/sample_server_timeout.py | 50 ++++-- .../sample_single_log_query_without_pandas.py | 49 ++++++ .../tests/test_logs_client.py | 9 +- 28 files changed, 671 insertions(+), 427 deletions(-) create mode 100644 sdk/monitor/azure-monitor-query/samples/async_samples/sample_log_query_async.py delete mode 100644 sdk/monitor/azure-monitor-query/samples/async_samples/sample_log_query_client_async.py rename sdk/monitor/azure-monitor-query/samples/async_samples/{sample_metrics_query_client_async.py => sample_metrics_query_async.py} (53%) delete mode 100644 sdk/monitor/azure-monitor-query/samples/sample_batch_query_serialized.py delete mode 100644 sdk/monitor/azure-monitor-query/samples/sample_log_query_client_without_pandas.py rename sdk/monitor/azure-monitor-query/samples/{sample_log_query_client.py => sample_logs_single_query.py} (56%) create mode 100644 sdk/monitor/azure-monitor-query/samples/sample_logs_single_query_partial_result.py create mode 100644 sdk/monitor/azure-monitor-query/samples/sample_metrics_query.py delete mode 100644 sdk/monitor/azure-monitor-query/samples/sample_metrics_query_client.py create mode 100644 sdk/monitor/azure-monitor-query/samples/sample_single_log_query_without_pandas.py diff --git a/sdk/monitor/azure-monitor-query/README.md b/sdk/monitor/azure-monitor-query/README.md index 800f960ac7eb..8e6ec07f0d0d 100644 --- a/sdk/monitor/azure-monitor-query/README.md +++ b/sdk/monitor/azure-monitor-query/README.md @@ -106,68 +106,83 @@ The `timespan` parameter specifies the time duration for which to query the data ```python import os import pandas as pd -from datetime import datetime +from datetime import datetime, timezone from azure.monitor.query import LogsQueryClient from azure.identity import DefaultAzureCredential credential = DefaultAzureCredential() client = LogsQueryClient(credential) -# Response time trend -# request duration over the last 12 hours -query = """AppRequests | -summarize avgRequestDuration=avg(DurationMs) by bin(TimeGenerated, 10m), _ResourceId""" - -start_time=datetime(2021, 7, 2) -end_time=datetime.now() - -# returns LogsQueryResult -response = client.query_workspace( - os.environ['LOG_WORKSPACE_ID'], - query, - timespan=(start_time, end_time) - ) - -if not response.tables: - print("No results for the query") - -for table in response.tables: - df = pd.DataFrame(table.rows, columns=[col.name for col in table.columns]) - print(df) +query = """AppRequests | take 5""" + +start_time=datetime(2021, 7, 2, tzinfo=timezone.utc) +end_time=datetime(2021, 7, 4, tzinfo=timezone.utc) + +try: + response = client.query_workspace( + workspace_id=os.environ['LOG_WORKSPACE_ID'], + query=query, + timespan=(start_time, end_time) + ) + if response.status == LogsQueryStatus.PARTIAL: + error = response.partial_error + data = response.partial_data + print(error.message) + elif response.status == LogsQueryStatus.SUCCESS: + data = response.tables + for table in data: + df = pd.DataFrame(data=table.rows, columns=table.columns) + print(df) +except HttpResponseError as err: + print("something fatal happened") + print (err) ``` #### Handle logs query response -The `query` API returns the `LogsQueryResult` while the `batch_query` API returns list of `LogsQueryResult`. Here's a hierarchy of the response: +The `query` API returns a union of `LogsQueryResult` and `LogsQueryPartialResult` while the `batch_query` API returns list of `LogsQueryResult`, `LogsQueryPartialResult` and `LogsQueryError` objects. Here's a hierarchy of the response: ``` LogsQueryResult |---statistics |---visualization -|---error |---tables (list of `LogsTable` objects) |---name |---rows - |---columns (list of `LogsTableColumn` objects) - |---name - |---type + |---columns + |---column_types + + +LogsQueryPartialResult +|---statistics +|---visualization +|---partial_error (a `LogsQueryError` object) +|---partial_data (list of `LogsTable` objects) + |---name + |---rows + |---columns + |---column_types ``` +The `LogsQueryResult` directly iterates over the table as a convinience. For example, to handle a logs query response with tables and display it using pandas: ```python -table = response.tables[0] -df = pd.DataFrame(table.rows, columns=[col.name for col in table.columns]) +response = client.query(...) +for table in response: + df = pd.DataFrame(table.rows, columns=[col.name for col in table.columns]) ``` -A full sample can be found [here](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_log_query_client.py). +A full sample can be found [here](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_logs_single_query.py). In a similar fashion, to handle a batch logs query response: ```python for result in response: - table = result.tables[0] - df = pd.DataFrame(table.rows, columns=[col.name for col in table.columns]) + if result.status == LogsQueryStatus.SUCCESS: + for table in result: + df = pd.DataFrame(table.rows, columns=table.columns) + print(df) ``` A full sample can be found [here](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_batch_query.py). @@ -178,41 +193,51 @@ The following example demonstrates sending multiple queries at the same time usi ```python import os -from datetime import timedelta +from datetime import timedelta, datetime, timezone import pandas as pd -from azure.monitor.query import LogsQueryClient, LogsQueryRequest +from azure.monitor.query import LogsQueryClient, LogsBatchQuery, LogsQueryStatus from azure.identity import DefaultAzureCredential credential = DefaultAzureCredential() client = LogsQueryClient(credential) - requests = [ LogsBatchQuery( query="AzureActivity | summarize count()", timespan=timedelta(hours=1), - workspace_id=os.environ['LOG_WORKSPACE_ID'] + workspace_id= os.environ['LOG_WORKSPACE_ID'] ), LogsBatchQuery( - query= """AppRequests | take 10 | - summarize avgRequestDuration=avg(DurationMs) by bin(TimeGenerated, 10m), _ResourceId""", - timespan=(datetime(2021, 6, 2), timedelta(hours=1)), - workspace_id=os.environ['LOG_WORKSPACE_ID'] + query= """bad query""", + timespan=timedelta(days=1), + workspace_id= os.environ['LOG_WORKSPACE_ID'] ), LogsBatchQuery( - query= "AppRequests | take 2", - workspace_id=os.environ['LOG_WORKSPACE_ID'] + query= """let Weight = 92233720368547758; + range x from 1 to 3 step 1 + | summarize percentilesw(x, Weight * 100, 50)""", + workspace_id= os.environ['LOG_WORKSPACE_ID'], + timespan=(datetime(2021, 6, 2, tzinfo=timezone.utc), datetime(2021, 6, 5, tzinfo=timezone.utc)), # (start, end) + include_statistics=True ), ] -response = client.query_batch(requests) - -for rsp in response: - body = rsp.body - if not body.tables: - print("Something is wrong") - else: - for table in body.tables: - df = pd.DataFrame(table.rows, columns=[col.name for col in table.columns]) +results = client.query_batch(requests) + +for res in results: + if res.status == LogsQueryStatus.FAILURE: + # this will be a LogsQueryError + print(res.message) + elif res.status == LogsQueryStatus.PARTIAL: + ## this will be a LogsQueryPartialResult + print(res.partial_error.message) + for table in res.partial_data: + df = pd.DataFrame(table.rows, columns=table.columns) print(df) + elif res.status == LogsQueryStatus.SUCCESS: + ## this will be a LogsQueryResult + table = res.tables[0] + df = pd.DataFrame(table.rows, columns=table.columns) + print(df) + ``` ### Advanced logs query scenarios @@ -233,6 +258,7 @@ client = LogsQueryClient(credential) response = client.query_workspace( os.environ['LOG_WORKSPACE_ID'], "range x from 1 to 10000000000 step 1 | count", + timespan=None, server_timeout=1, ) ``` @@ -271,9 +297,11 @@ To find the resource URI: 2. From the **Overview** blade, select the **JSON View** link. 3. In the resulting JSON, copy the value of the `id` property. +**NOTE**: The metrics are returned in the order of the metric_names sent. + ```python import os -from datetime import timedelta +from datetime import timedelta, datetime from azure.monitor.query import MetricsQueryClient from azure.identity import DefaultAzureCredential @@ -367,6 +395,27 @@ Optional keyword arguments can be passed in at the client and per-operation leve To learn more about Azure Monitor, see the [Azure Monitor service documentation][azure_monitor_overview]. +### Samples +These code samples show common champion scenario operations with the Azure Monitor Query client library. + +* Send a single query with LogsQueryClient and handle the response as a table: [sample_logs_single_query.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_logs_single_query.py) ([async_sample](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/async_samples/sample_log_query_async.py)) + +* Send a single query with LogsQueryClient and handle the response in key value form: [sample_logs_query_key_value_form.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_logs_query_key_value_form.py) + +* Send a single query with LogsQueryClient without pandas: [sample_single_log_query_without_pandas.py.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_single_log_query_without_pandas.py) + +* Send a single query with LogsQueryClient across multiple workspaces: [sample_logs_query_multiple_workspaces.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_log_query_multiple_workspaces.py) + +* Send multiple queries with LogsQueryClient: [sample_batch_query.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_batch_query.py) + +* Send a single query with LogsQueryClient using server timeout: [sample_server_timeout.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_server_timeout.py) + +* Send a query using MetricsQueryClient: [sample_metrics_query.py](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)) + +* Get a list of metric namespaces: [sample_metric_namespaces.py](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: [sample_metric_definitions.py](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)) + ## Contributing This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit [cla.microsoft.com][cla]. diff --git a/sdk/monitor/azure-monitor-query/azure/monitor/query/_exceptions.py b/sdk/monitor/azure-monitor-query/azure/monitor/query/_exceptions.py index 658df77d7261..d4600665a750 100644 --- a/sdk/monitor/azure-monitor-query/azure/monitor/query/_exceptions.py +++ b/sdk/monitor/azure-monitor-query/azure/monitor/query/_exceptions.py @@ -10,8 +10,6 @@ class LogsQueryError(object): """The code and message for an error. - All required parameters must be populated in order to send to Azure. - :ivar code: A machine readable error code. :vartype code: str :ivar message: A human readable error message. 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 dc65b9e48967..4fb0563fd3da 100644 --- a/sdk/monitor/azure-monitor-query/azure/monitor/query/_helpers.py +++ b/sdk/monitor/azure-monitor-query/azure/monitor/query/_helpers.py @@ -5,7 +5,7 @@ # license information. # -------------------------------------------------------------------------- from datetime import datetime, timedelta -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, List, Dict, Any from msrest import Serializer, Deserializer from azure.core.exceptions import HttpResponseError from azure.core.pipeline.policies import BearerTokenCredentialPolicy @@ -47,6 +47,7 @@ def get_metrics_authentication_policy( def order_results(request_order, mapping, **kwargs): + # type: (List, Dict, Any) -> List ordered = [mapping[id] for id in request_order] results = [] for item in ordered: diff --git a/sdk/monitor/azure-monitor-query/azure/monitor/query/_logs_query_client.py b/sdk/monitor/azure-monitor-query/azure/monitor/query/_logs_query_client.py index 913e9988b518..be46a88dfe36 100644 --- a/sdk/monitor/azure-monitor-query/azure/monitor/query/_logs_query_client.py +++ b/sdk/monitor/azure-monitor-query/azure/monitor/query/_logs_query_client.py @@ -28,11 +28,17 @@ class LogsQueryClient(object): - """LogsQueryClient + """LogsQueryClient. Use this client to collect and organize 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. + + The various data types can be analyzed together using the + [Kusto Query Language](https://docs.microsoft.com/azure/data-explorer/kusto/query/) .. admonition:: Example: - .. literalinclude:: ../samples/sample_log_query_client.py + .. literalinclude:: ../samples/sample_single_logs_query.py :start-after: [START client_auth_with_token_cred] :end-before: [END client_auth_with_token_cred] :language: python @@ -83,13 +89,13 @@ def query_workspace(self, workspace_id, query, **kwargs): :keyword additional_workspaces: A list of workspaces that are included in the query. These can be qualified workspace names, workspace Ids, or Azure resource Ids. :paramtype additional_workspaces: list[str] - :return: LogsQueryResult, or the result of cls(response) + :return: LogsQueryResult if there is a success or LogsQueryPartialResult when there is a partial success. :rtype: Union[~azure.monitor.query.LogsQueryResult, ~azure.monitor.query.LogsQueryPartialResult] :raises: ~azure.core.exceptions.HttpResponseError .. admonition:: Example: - .. literalinclude:: ../samples/sample_log_query_client.py + .. literalinclude:: ../samples/sample_single_logs_query.py :start-after: [START send_logs_query] :end-before: [END send_logs_query] :language: python @@ -131,7 +137,7 @@ def query_workspace(self, workspace_id, query, **kwargs): response = LogsQueryPartialResult._from_generated( # pylint: disable=protected-access generated_response, LogsQueryError ) - return response + return cast(Union[LogsQueryResult, LogsQueryPartialResult], response) @distributed_trace def query_batch( @@ -140,14 +146,17 @@ def query_batch( **kwargs # type: Any ): # type: (...) -> List[Union[LogsQueryResult, LogsQueryPartialResult, LogsQueryError]] - """Execute a list of analytics queries. Each request can be either a LogQueryRequest + """Execute a list of analytics queries. Each request can be either a LogsBatchQuery object or an equivalent serialized model. - The response is returned in the same order as that of the requests sent. + **NOTE**: The response is returned in the same order as that of the requests sent. :param queries: The list of Kusto queries to execute. :type queries: list[dict] or list[~azure.monitor.query.LogsBatchQuery] - :return: List of LogsQueryResult, or the result of cls(response) + :return: List of LogsQueryResult, LogsQueryPartialResult and LogsQueryError. + For a given query, a LogsQueryResult is returned if the response is a success, LogsQueryPartialResult + is returned when there is a partial success and a LogsQueryError is returned when there is a failure. + The status of each response can be checked using `LogsQueryStatus` enum. :rtype: list[Union[~azure.monitor.query.LogsQueryResult, ~azure.monitor.query.LogsQueryPartialResult, ~azure.monitor.query.LogsQueryError] :raises: ~azure.core.exceptions.HttpResponseError @@ -162,7 +171,7 @@ def query_batch( :caption: Get a response for multiple Log Queries. """ try: - queries = [LogsBatchQuery(**q) for q in queries] + queries = [LogsBatchQuery(**cast(Dict, q)) for q in queries] except (KeyError, TypeError): pass queries = [ @@ -174,7 +183,7 @@ def query_batch( request_order = [req["id"] for req in queries] batch = BatchRequest(requests=queries) generated = self._query_op.batch(batch, **kwargs) - mapping = {item.id: item for item in generated.responses} + mapping = {item.id: item for item in generated.responses} # type: ignore return order_results( request_order, mapping, 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 eec3ef245342..171d0b495a3c 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 @@ -7,7 +7,7 @@ # pylint: disable=anomalous-backslash-in-string -from typing import TYPE_CHECKING, Any, Optional +from typing import TYPE_CHECKING, Any, List from msrest.serialization import Serializer from azure.core.tracing.decorator import distributed_trace @@ -25,11 +25,15 @@ class MetricsQueryClient(object): - """MetricsQueryClient + """MetricsQueryClient should be used to collect numeric data from monitored resources into a + time series database. Metrics are numerical values that are collected at regular intervals and + describe some aspect of a system at a particular time. Metrics are lightweight and capable of + supporting near real-time scenarios, making them particularly useful for alerting and + fast detection of issues. .. admonition:: Example: - .. literalinclude:: ../samples/sample_metrics_query_client.py + .. literalinclude:: ../samples/sample_metrics_query.py :start-after: [START metrics_client_auth_with_token_cred] :end-before: [END metrics_client_auth_with_token_cred] :language: python @@ -57,7 +61,7 @@ def __init__(self, credential, **kwargs): @distributed_trace def query_resource(self, resource_uri, metric_names, **kwargs): - # type: (str, list, Optional[timedelta], Any) -> MetricsResult + # type: (str, List[str], Any) -> MetricsResult """Lists the metric values for a resource. :param resource_uri: The identifier of the resource. @@ -90,10 +94,11 @@ def query_resource(self, resource_uri, metric_names, **kwargs): series where A = a1, B = b1 and C = c1::code:`
`\ **$filter=A eq ‘a1’ and B eq ‘b1’ and C eq ‘c1’**\ :code:`
`- Return all time series where A = a1:code:`
`\ **$filter=A eq ‘a1’ and B eq ‘\ *’ and C eq ‘*\ ’**. + To use the split feature, set the value to * - for example, like "City eq '*'" :paramtype filter: str :keyword metric_namespace: Metric namespace to query metric definitions for. :paramtype metric_namespace: str - :return: Response, or the result of cls(response) + :return: A MetricsResult object. :rtype: ~azure.monitor.query.MetricsResult :raises: ~azure.core.exceptions.HttpResponseError @@ -162,7 +167,7 @@ def list_metric_definitions(self, resource_uri, **kwargs): :type resource_uri: str :keyword namespace: Metric namespace to query metric definitions for. :paramtype namespace: str - :return: An iterator like instance of either MetricDefinitionCollection or the result of cls(response) + :return: An iterator like instance of either MetricDefinition or the result of cls(response) :rtype: ~azure.core.paging.ItemPaged[~azure.monitor.query.MetricDefinition] :raises: ~azure.core.exceptions.HttpResponseError """ 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 8aa3cdd867bf..a16a258f40d2 100644 --- a/sdk/monitor/azure-monitor-query/azure/monitor/query/_models.py +++ b/sdk/monitor/azure-monitor-query/azure/monitor/query/_models.py @@ -59,6 +59,7 @@ def _from_generated(cls, generated): class LogsTableRow(list): """Represents a single row in logs table. + This type is gettable by both column name and column index. :ivar int index: The index of the row in the table """ @@ -85,7 +86,7 @@ def __repr__(self): def __getitem__(self, column): """This type must be subscriptable directly to row. - Must be gettableby both column name and row index + Must be gettable by both column name and row index :param column: The name of the column or the index of the element in a row. :type column: str or int @@ -99,8 +100,6 @@ def __getitem__(self, column): class MetricsResult(object): """The response to a metrics query. - All required parameters must be populated in order to send to Azure. - :ivar cost: The integer value representing the cost of the query, for data case. :vartype cost: int :ivar timespan: Required. The timespan for which the data was retrieved. Its value consists of @@ -168,9 +167,7 @@ def __getitem__(self, metric): class LogsBatchQuery(object): - """A single request in a batch. - - Variables are only populated by the server, and will be ignored when sending a request. + """A single request in a batch. The batch query API accepts a list of these objects. :param workspace_id: Workspace Id to be included in the query. :type workspace_id: str @@ -234,7 +231,7 @@ def _to_generated(self): class LogsQueryResult(object): - """The LogsQueryResult. + """The LogsQueryResult type is returned when the response of a query is a success. :ivar tables: The list of tables, columns and rows. :vartype tables: list[~azure.monitor.query.LogsTable] @@ -419,9 +416,7 @@ def _from_generated(cls, generated): class MetricValue(object): """Represents a metric value. - All required parameters must be populated in order to send to Azure. - - :ivar timestamp: Required. The timestamp for the metric value in ISO 8601 format. + :ivar timestamp: The timestamp for the metric value. :vartype timestamp: ~datetime.datetime :ivar average: The average value in the time range. :vartype average: float @@ -460,21 +455,20 @@ def _from_generated(cls, generated): class Metric(object): - """The result data of a query. + """The result data of a single metric name. - All required parameters must be populated in order to send to Azure. - - :ivar id: Required. The metric Id. + :ivar id: The metric Id. :vartype id: str - :ivar type: Required. The resource type of the metric resource. + :ivar type: The resource type of the metric resource. :vartype type: str - :ivar name: Required. The name of the metric. + :ivar name: The name of the metric. :vartype name: str - :ivar unit: Required. The unit of the metric. Possible values include: "Count", "Bytes", + :ivar unit: The unit of the metric. To access these values, use the MetricUnit enum. + Possible values include: "Count", "Bytes", "Seconds", "CountPerSecond", "BytesPerSecond", "Percent", "MilliSeconds", "ByteSeconds", "Unspecified", "Cores", "MilliCores", "NanoCores", "BitsPerSecond". :vartype unit: str - :ivar timeseries: Required. The time series returned when a data query is performed. + :ivar timeseries: The time series returned when a data query is performed. :vartype timeseries: list[~azure.monitor.query.TimeSeriesElement] :ivar display_description: Detailed description of this metric. :vartype display_description: str @@ -515,12 +509,6 @@ class TimeSeriesElement(object): a result type of data is specified. :vartype data: list[~azure.monitor.query.MetricValue] """ - - _attribute_map = { - "metadata_values": {"key": "metadata_values", "type": "[MetadataValue]"}, - "data": {"key": "data", "type": "[MetricValue]"}, - } - def __init__(self, **kwargs): # type: (Any) -> None self.metadata_values = kwargs.get("metadatavalues", None) @@ -544,11 +532,9 @@ class MetricAvailability(object): """Metric availability specifies the time grain (aggregation interval or frequency) and the retention period for that time grain. - :ivar granularity: the time grain specifies the aggregation interval for the metric. Expressed - as a duration 'PT1M', 'P1D', etc. + :ivar granularity: the time grain specifies the aggregation interval for the metric. :vartype granularity: ~datetime.timedelta - :ivar retention: the retention period for the metric at the specified timegrain. Expressed as - a duration 'PT1M', 'P1D', etc. + :ivar retention: the retention period for the metric at the specified timegrain. :vartype retention: ~datetime.timedelta """ @@ -594,7 +580,8 @@ class MetricUnit(str, Enum): class LogsQueryPartialResult(object): - """The LogsQueryPartialResult. + """The LogsQueryPartialResult type is returned when the response of a query is a + partial success (or partial failure). :ivar partial_data: The list of tables, columns and rows. :vartype partial_data: list[~azure.monitor.query.LogsTable] diff --git a/sdk/monitor/azure-monitor-query/azure/monitor/query/aio/_logs_query_client_async.py b/sdk/monitor/azure-monitor-query/azure/monitor/query/aio/_logs_query_client_async.py index 4698bf1c7ee5..92379c5d6442 100644 --- a/sdk/monitor/azure-monitor-query/azure/monitor/query/aio/_logs_query_client_async.py +++ b/sdk/monitor/azure-monitor-query/azure/monitor/query/aio/_logs_query_client_async.py @@ -23,7 +23,13 @@ class LogsQueryClient(object): - """LogsQueryClient + """LogsQueryClient. Use this client to collect and organize 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. + + The various data types can be analyzed together using the + [Kusto Query Language](https://docs.microsoft.com/azure/data-explorer/kusto/query/) :param credential: The credential to authenticate the client :type credential: ~azure.core.credentials_async.AsyncTokenCredential @@ -62,20 +68,20 @@ async def query_workspace( :param query: The Kusto query. Learn more about the `Kusto query syntax `_. :type query: str - :param timespan: Required. The timespan for which to query the data. This can be a timedelta, + :keyword timespan: Required. 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. - :type timespan: ~datetime.timedelta or tuple[~datetime.datetime, ~datetime.timedelta] + :paramtype timespan: ~datetime.timedelta or tuple[~datetime.datetime, ~datetime.timedelta] or tuple[~datetime.datetime, ~datetime.datetime] - :keyword int server_timeout: the server timeout. The default timeout is 3 minutes, + :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. :keyword bool include_visualization: In the query language, it is possible to specify different visualization options. By default, the API does not return information regarding the type of visualization to show. If your client requires this information, specify the preference :keyword additional_workspaces: A list of workspaces that are included in the query. - These can be qualified workspace names, workspace Ids or Azure resource Ids. + These can be qualified workspace names, workspace Ids, or Azure resource Ids. :paramtype additional_workspaces: list[str] - :return: QueryResults, or the result of cls(response) + :return: LogsQueryResult if there is a success or LogsQueryPartialResult when there is a partial success. :rtype: ~azure.monitor.query.LogsQueryResult or ~azure.monitor.query.LogsQueryPartialResult :raises: ~azure.core.exceptions.HttpResponseError """ @@ -116,14 +122,17 @@ async def query_workspace( async def query_batch( self, queries: Union[Sequence[Dict], Sequence[LogsBatchQuery]], **kwargs: Any ) -> List[Union[LogsQueryResult, LogsQueryError, LogsQueryPartialResult]]: - """Execute a list of analytics queries. Each request can be either a LogQueryRequest + """Execute a list of analytics queries. Each request can be either a LogsBatchQuery object or an equivalent serialized model. - The response is returned in the same order as that of the requests sent. + **NOTE**: The response is returned in the same order as that of the requests sent. :param queries: The list of Kusto queries to execute. :type queries: list[dict] or list[~azure.monitor.query.LogsBatchQuery] - :return: list of LogsQueryResult objects, or the result of cls(response) + :return: List of LogsQueryResult, LogsQueryPartialResult and LogsQueryError. + For a given query, a LogsQueryResult is returned if the response is a success, LogsQueryPartialResult + is returned when there is a partial success and a LogsQueryError is returned when there is a failure. + The status of each response can be checked using `LogsQueryStatus` enum. :rtype: list[~azure.monitor.query.LogsQueryResult or ~azure.monitor.query.LogsQueryPartialResult or ~azure.monitor.query.LogsQueryError] :raises: ~azure.core.exceptions.HttpResponseError 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 67d2eb06bfec..e9345743d686 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 @@ -7,8 +7,7 @@ # pylint: disable=anomalous-backslash-in-string -from datetime import timedelta -from typing import TYPE_CHECKING, Any, List, Optional +from typing import TYPE_CHECKING, Any, List from msrest.serialization import Serializer from azure.core.async_paging import AsyncItemPaged @@ -49,7 +48,7 @@ def __init__(self, credential: "AsyncTokenCredential", **kwargs: Any) -> None: @distributed_trace_async async def query_resource( - self, resource_uri: str, metric_names: List, **kwargs: Any + self, resource_uri: str, metric_names: List[str], **kwargs: Any ) -> MetricsResult: """Lists the metric values for a resource. @@ -86,10 +85,11 @@ async def query_resource( series where A = a1, B = b1 and C = c1::code:`
`\ **$filter=A eq ‘a1’ and B eq ‘b1’ and C eq ‘c1’**\ :code:`
`- Return all time series where A = a1:code:`
`\ **$filter=A eq ‘a1’ and B eq ‘\ *’ and C eq ‘*\ ’**. + To use the split feature, set the value to * - for example, like "City eq '*'" :paramtype filter: str :keyword metric_namespace: Metric namespace to query metric definitions for. :paramtype metric_namespace: str - :return: Response, or the result of cls(response) + :return: A MetricsResult object. :rtype: ~azure.monitor.query.MetricsResult :raises: ~azure.core.exceptions.HttpResponseError """ @@ -150,7 +150,7 @@ def list_metric_definitions( :type resource_uri: str :keyword namespace: Metric namespace to query metric definitions for. :paramtype namespace: str - :return: An iterator like instance of either MetricDefinitionCollection or the result of cls(response) + :return: An iterator like instance of either MetricDefinition or the result of cls(response) :rtype: ~azure.core.paging.AsyncItemPaged[:class: `~azure.monitor.query.MetricDefinition`] :raises: ~azure.core.exceptions.HttpResponseError """ diff --git a/sdk/monitor/azure-monitor-query/samples/README.md b/sdk/monitor/azure-monitor-query/samples/README.md index 4c92a3ad33b2..423fce93f453 100644 --- a/sdk/monitor/azure-monitor-query/samples/README.md +++ b/sdk/monitor/azure-monitor-query/samples/README.md @@ -10,30 +10,62 @@ urlFragment: query-azuremonitor-samples # Azure Monitor Query Client Library Python Samples -## Sync samples +## Samples These code samples show common champion scenario operations with the Azure Monitor Query client library. -* Send a single query with LogsQueryClient: [sample_log_query_client.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_log_query_client.py) +* Send a single query with LogsQueryClient and handle the response as a table: [sample_logs_single_query.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_logs_single_query.py) ([async_sample](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/async_samples/sample_log_query_async.py)) -* Send multiple queries with LogsQueryClient: [sample_batch_query.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_batch_query.py) +* Send a single query with LogsQueryClient and handle the response in key value form: [sample_logs_query_key_value_form.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_logs_query_key_value_form.py) + +* Send a single query with LogsQueryClient without pandas: [sample_single_log_query_without_pandas.py.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_single_log_query_without_pandas.py) + +* Send a single query with LogsQueryClient across multiple workspaces: [sample_logs_query_multiple_workspaces.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_log_query_multiple_workspaces.py) -* Send multiple queries with LogsQueryClient as a dictionary: [sample_batch_query_serialized.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_batch_query_serialized.py) +* Send multiple queries with LogsQueryClient: [sample_batch_query.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_batch_query.py) * Send a single query with LogsQueryClient using server timeout: [sample_server_timeout.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_server_timeout.py) -* Send a query using MetricsQueryClient: [sample_metrics_query_client.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_metrics_query_client.py) +* Send a query using MetricsQueryClient: [sample_metrics_query.py](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)) + +* Get a list of metric namespaces: [sample_metric_namespaces.py](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: [sample_metric_definitions.py](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 2.7, or 3.6 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.). + +## Setup + +1. Install the latest beta version of Azure monitor query that the samples use: + +```bash +pip install azure-monitor-query +``` + +2. Clone or download this sample repository. +3. Open the sample folder in Visual Studio Code or your IDE of choice. +4. To run most of this samples, you need azure-identity and pandas although they are optional can be replaced. -* Get a list of metric namespaces: [sample_metric_namespaces.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_metric_namespaces.py) +```bash +pip install azure-identity pandas +``` -* Get a list of metric definitions: [sample_metric_definitions.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_metric_definitions.py) +5. Finally, to run the async samples, you would need an async http framework like aiohttp -## Async samples -These code samples show common champion scenario operations with the Azure Monitor Query client library using the async client. +```bash +pip install aiohttp +``` -* Send a single query with LogsQueryClient: [sample_log_query_client_async.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/async_samples/sample_log_query_client_async.py) +## Running the samples -* Send a query using MetricsQueryClient: [sample_metrics_query_client_async.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metrics_query_client_async.py) +1. Open a terminal window and `cd` to the directory that the samples are saved in. +2. Set the environment variables specified in the sample file you wish to run. +3. Follow the usage described in the file, e.g. `python sample_logs_single_query.py` -* Get a list of metric namespaces: [sample_metric_namespaces_async.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metric_namespaces_async.py) +## Next steps -* Get a list of metric definitions: [sample_metric_definitions_async.py](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metric_definitions_async.py) \ No newline at end of file +To learn more about Azure Monitor, see the [Azure Monitor service documentation](https://docs.microsoft.com/azure/azure-monitor/). \ No newline at end of file diff --git a/sdk/monitor/azure-monitor-query/samples/async_samples/sample_log_query_async.py b/sdk/monitor/azure-monitor-query/samples/async_samples/sample_log_query_async.py new file mode 100644 index 000000000000..b2ef2090b2f6 --- /dev/null +++ b/sdk/monitor/azure-monitor-query/samples/async_samples/sample_log_query_async.py @@ -0,0 +1,56 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +""" +FILE: sample_logs_single_query_async.py +DESCRIPTION: + This sample demonstrates authenticating the LogsQueryClient and querying a single query. +USAGE: + python sample_logs_single_query_async.py + Set the environment variables with your own values before running the sample: + 1) LOGS_WORKSPACE_ID - The first (primary) workspace ID. + + In order to use the DefaultAzureCredential, the following environment variables must be set: + 1) AZURE_CLIENT_ID - The client ID of a user-assigned managed identity. + 2) AZURE_TENANT_ID - Tenant ID to use when authenticating a user. + 3) AZURE_CLIENT_ID - The client secret to be used for authentication. + +**Note** - Although this example uses pandas to prin the response, it is totally optional and is +not a required package for querying. Alternatively, native python can be used as well. +""" +import asyncio +import os +import pandas as pd +from azure.monitor.query.aio import LogsQueryClient +from azure.monitor.query import LogsQueryStatus +from azure.core.exceptions import HttpResponseError +from azure.identity.aio import DefaultAzureCredential + +async def logs_query(): + credential = DefaultAzureCredential( + client_id = os.environ['AZURE_CLIENT_ID'], + client_secret = os.environ['AZURE_CLIENT_SECRET'], + tenant_id = os.environ['AZURE_TENANT_ID'] + ) + + client = LogsQueryClient(credential) + + query= """AppRequests | take 5""" + + try: + response = await client.query_workspace(os.environ['LOG_WORKSPACE_ID'], query, timespan=timedelta(days=1)) + if response.status == LogsQueryStatus.PARTIAL: + error = response.partial_error + data = response.partial_data + print(error.message) + elif response.status == LogsQueryStatus.SUCCESS: + data = response.tables + for table in data: + df = pd.DataFrame(data=table.rows, columns=table.columns) + print(df) + except HttpResponseError as err: + print("something fatal happened") + print (err) + +if __name__ == '__main__': + loop = asyncio.get_event_loop() + loop.run_until_complete(logs_query()) \ No newline at end of file diff --git a/sdk/monitor/azure-monitor-query/samples/async_samples/sample_log_query_client_async.py b/sdk/monitor/azure-monitor-query/samples/async_samples/sample_log_query_client_async.py deleted file mode 100644 index 6e9822bb2cec..000000000000 --- a/sdk/monitor/azure-monitor-query/samples/async_samples/sample_log_query_client_async.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. - -import asyncio -import os -import pandas as pd -from azure.monitor.query.aio import LogsQueryClient -from azure.identity.aio import DefaultAzureCredential - -async def logs_query(): - credential = DefaultAzureCredential( - client_id = os.environ['AZURE_CLIENT_ID'], - client_secret = os.environ['AZURE_CLIENT_SECRET'], - tenant_id = os.environ['AZURE_TENANT_ID'] - ) - - client = LogsQueryClient(credential) - - # Response time trend - # request duration over the last 12 hours. - query = """AppRequests | - where TimeGenerated > ago(12h) | - summarize avgRequestDuration=avg(DurationMs) by bin(TimeGenerated, 10m), _ResourceId""" - - # returns LogsQueryResult - async with client: - response = await client.query_workspace(os.environ['LOG_WORKSPACE_ID'], query, timespan=None) - - if not response.tables: - print("No results for the query") - - for table in response.tables: - df = pd.DataFrame(table.rows, columns=[col.name for col in table.columns]) - print(df) - - """ - TimeGenerated _ResourceId avgRequestDuration - 0 2021-05-27T08:40:00Z /subscriptions/faa080af-c1d8-40ad-9cce-e1a450c... 27.307699999999997 - 1 2021-05-27T08:50:00Z /subscriptions/faa080af-c1d8-40ad-9cce-e1a450c... 18.11655 - 2 2021-05-27T09:00:00Z /subscriptions/faa080af-c1d8-40ad-9cce-e1a450c... 24.5271 - """ - - # if you dont want to use pandas - here's how you can process it. - - #response.tables is a LogsTable - for table in response.tables: - for col in table.columns: #LogsQueryResultColumn - print(col.name + "/"+ col.type + " | ", end="") - print("\n") - for row in table.rows: - for item in row: - print(item + " | ", end="") - print("\n") - - - """ - TimeGenerated/datetime | _ResourceId/string | avgRequestDuration/real | - - 2021-05-11T08:20:00Z | /subscriptions//resourcegroups/cobey-azuresdkshinydashboardgrp/providers/microsoft.insights/components/cobey-willthisbestatic | 10.8915 | - - 2021-05-11T08:30:00Z | /subscriptions//resourcegroups/cobey-azuresdkshinydashboardgrp/providers/microsoft.insights/components/cobey-willthisbestatic | 33.23276666666667 | - - 2021-05-11T08:40:00Z | /subscriptions//resourcegroups/cobey-azuresdkshinydashboardgrp/providers/microsoft.insights/components/cobey-willthisbestatic | 21.83535 | - - 2021-05-11T08:50:00Z | /subscriptions//resourcegroups/cobey-azuresdkshinydashboardgrp/providers/microsoft.insights/components/cobey-willthisbestatic | 11.028649999999999 | - """ - -if __name__ == '__main__': - loop = asyncio.get_event_loop() - loop.run_until_complete(logs_query()) \ No newline at end of file diff --git a/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metric_definitions_async.py b/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metric_definitions_async.py index 0184a48bd59d..dc2aeab0f6dc 100644 --- a/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metric_definitions_async.py +++ b/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metric_definitions_async.py @@ -1,6 +1,20 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. +""" +FILE: sample_metric_definitions_async.py +DESCRIPTION: + This sample demonstrates listing all the metric definitions of a resource. +USAGE: + python sample_metric_definitions_async.py + Set the environment variables with your own values before running the sample: + 1) METRICS_RESOURCE_URI - The resource uri of the resource for which the metrics are being queried. + In this example, an eventgrid account resource URI is taken. + In order to use the DefaultAzureCredential, the following environment variables must be set: + 1) AZURE_CLIENT_ID - The client ID of a user-assigned managed identity. + 2) AZURE_TENANT_ID - Tenant ID to use when authenticating a user. + 3) AZURE_CLIENT_ID - The client secret to be used for authentication. +""" import os import asyncio from azure.monitor.query.aio import MetricsQueryClient @@ -17,7 +31,7 @@ async def list_definitions(self): response = client.list_metric_definitions(metrics_uri) async for item in response: - print(item.namespace) + print(item.name) for availability in item.metric_availabilities: print(availability.granularity) diff --git a/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metric_namespaces_async.py b/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metric_namespaces_async.py index 0991b3927b78..7418414eb0df 100644 --- a/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metric_namespaces_async.py +++ b/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metric_namespaces_async.py @@ -1,6 +1,20 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. +""" +FILE: sample_metric_namespaces_async.py +DESCRIPTION: + This sample demonstrates listing all the metric namespaces of a resource. +USAGE: + python sample_metric_namespaces_async.py + Set the environment variables with your own values before running the sample: + 1) METRICS_RESOURCE_URI - The resource uri of the resource for which the metrics are being queried. + In this example, a storage account resource URI is taken. + In order to use the DefaultAzureCredential, the following environment variables must be set: + 1) AZURE_CLIENT_ID - The client ID of a user-assigned managed identity. + 2) AZURE_TENANT_ID - Tenant ID to use when authenticating a user. + 3) AZURE_CLIENT_ID - The client secret to be used for authentication. +""" import os import asyncio from azure.monitor.query.aio import MetricsQueryClient diff --git a/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metrics_query_client_async.py b/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metrics_query_async.py similarity index 53% rename from sdk/monitor/azure-monitor-query/samples/async_samples/sample_metrics_query_client_async.py rename to sdk/monitor/azure-monitor-query/samples/async_samples/sample_metrics_query_async.py index 978e60338922..78cad14ff6b9 100644 --- a/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metrics_query_client_async.py +++ b/sdk/monitor/azure-monitor-query/samples/async_samples/sample_metrics_query_async.py @@ -1,17 +1,30 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. +""" +FILE: sample_metrics_query_async.py +DESCRIPTION: + This sample demonstrates authenticating the LogsQueryClient and querying a single query + on multiple workspaces using the additional_workspaces param. +USAGE: + python sample_metrics_query_async.py + Set the environment variables with your own values before running the sample: + 1) METRICS_RESOURCE_URI - The resource uri of the resource for which the metrics are being queried. + In this example, a storage account resource URI is taken. + In order to use the DefaultAzureCredential, the following environment variables must be set: + 1) AZURE_CLIENT_ID - The client ID of a user-assigned managed identity. + 2) AZURE_TENANT_ID - Tenant ID to use when authenticating a user. + 3) AZURE_CLIENT_ID - The client secret to be used for authentication. +""" import os import asyncio -from datetime import datetime, timedelta +from datetime import timedelta from azure.monitor.query.aio import MetricsQueryClient from azure.monitor.query import MetricAggregationType from azure.identity.aio import DefaultAzureCredential async def query_metrics(): - credential = DefaultAzureCredential( - - ) + credential = DefaultAzureCredential() client = MetricsQueryClient(credential) 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 ce956d7c27fb..95d6f9ac9efe 100644 --- a/sdk/monitor/azure-monitor-query/samples/sample_batch_query.py +++ b/sdk/monitor/azure-monitor-query/samples/sample_batch_query.py @@ -1,10 +1,27 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. +""" +FILE: sample_batch_query.py +DESCRIPTION: + This sample demonstrates querying multiple queries in a batch. +USAGE: + python sample_batch_query.py + Set the environment variables with your own values before running the sample: + 1) LOGS_WORKSPACE_ID - The The first (primary) workspace ID. -from datetime import datetime, timedelta + In order to use the DefaultAzureCredential, the following environment variables must be set: + 1) AZURE_CLIENT_ID - The client ID of a user-assigned managed identity. + 2) AZURE_TENANT_ID - Tenant ID to use when authenticating a user. + 3) AZURE_CLIENT_ID - The client secret to be used for authentication. + +**Note** - Although this example uses pandas to prin the response, it is totally optional and is +not a required package for querying. Alternatively, native python can be used as well. +""" + +from datetime import datetime, timedelta, timezone import os import pandas as pd -from azure.monitor.query import LogsQueryClient, LogsBatchQuery, LogsQueryStatus, LogsQueryPartialResult +from azure.monitor.query import LogsQueryClient, LogsBatchQuery, LogsQueryStatus from azure.identity import DefaultAzureCredential @@ -20,8 +37,8 @@ workspace_id= os.environ['LOG_WORKSPACE_ID'] ), LogsBatchQuery( - query= """AppRequestsss | take 10""", - timespan=(datetime(2021, 6, 2), timedelta(days=1)), + query= """bad query""", + timespan=timedelta(days=1), workspace_id= os.environ['LOG_WORKSPACE_ID'] ), LogsBatchQuery( @@ -29,7 +46,7 @@ range x from 1 to 3 step 1 | summarize percentilesw(x, Weight * 100, 50)""", workspace_id= os.environ['LOG_WORKSPACE_ID'], - timespan=(datetime(2021, 6, 2), datetime(2021, 6, 3)), + timespan=(datetime(2021, 6, 2, tzinfo=timezone.utc), datetime(2021, 6, 5, tzinfo=timezone.utc)), # (start, end) include_statistics=True ), ] @@ -42,9 +59,9 @@ elif res.status == LogsQueryStatus.PARTIAL: ## this will be a LogsQueryPartialResult print(res.partial_error.message) - table = res.tables[0] - df = pd.DataFrame(table.rows, columns=table.columns) - print(df) + for table in res.partial_data: + df = pd.DataFrame(table.rows, columns=table.columns) + print(df) elif res.status == LogsQueryStatus.SUCCESS: ## this will be a LogsQueryResult table = res.tables[0] diff --git a/sdk/monitor/azure-monitor-query/samples/sample_batch_query_serialized.py b/sdk/monitor/azure-monitor-query/samples/sample_batch_query_serialized.py deleted file mode 100644 index 6c06b03d34b3..000000000000 --- a/sdk/monitor/azure-monitor-query/samples/sample_batch_query_serialized.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. - -import os -import pandas as pd -from azure.monitor.query import LogsQueryClient -from azure.identity import DefaultAzureCredential - - -credential = DefaultAzureCredential() - -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'] - } -] -responses = client.query_batch(requests) - -for response in responses: - try: - table = response.tables[0] - df = pd.DataFrame(table.rows, columns=[col.name for col in table.columns]) - print(df) - except TypeError: - print(response.error) \ No newline at end of file diff --git a/sdk/monitor/azure-monitor-query/samples/sample_log_query_client_without_pandas.py b/sdk/monitor/azure-monitor-query/samples/sample_log_query_client_without_pandas.py deleted file mode 100644 index 6285562580a2..000000000000 --- a/sdk/monitor/azure-monitor-query/samples/sample_log_query_client_without_pandas.py +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. - -import os -from datetime import datetime, timedelta -from msrest.serialization import UTC -from azure.monitor.query import LogsQueryClient -from azure.identity import DefaultAzureCredential - -credential = DefaultAzureCredential() - -client = LogsQueryClient(credential) - -# Response time trend -# request duration over the last 12 hours. -query = """AppRequests | -summarize avgRequestDuration=avg(DurationMs) by bin(TimeGenerated, 10m), _ResourceId""" - -# returns LogsQueryResult -response = client.query_workspace(os.environ['LOG_WORKSPACE_ID'], query, timespan=timedelta(hours=1)) - -if not response.tables: - print("No results for the query") - -#response.tables is a LogsTable -for table in response.tables: - for col in table.columns: #LogsQueryResultColumn - print(col.name + "/"+ col.type + " | ", end="") - print("\n") - for row in table.rows: - for item in row: - print(item + " | ", end="") - print("\n") - - -""" -TimeGenerated/datetime | _ResourceId/string | avgRequestDuration/real | - -2021-05-11T08:20:00Z | /subscriptions//resourcegroups/cobey-azuresdkshinydashboardgrp/providers/microsoft.insights/components/cobey-willthisbestatic | 10.8915 | - -2021-05-11T08:30:00Z | /subscriptions//resourcegroups/cobey-azuresdkshinydashboardgrp/providers/microsoft.insights/components/cobey-willthisbestatic | 33.23276666666667 | - -2021-05-11T08:40:00Z | /subscriptions//resourcegroups/cobey-azuresdkshinydashboardgrp/providers/microsoft.insights/components/cobey-willthisbestatic | 21.83535 | - -2021-05-11T08:50:00Z | /subscriptions//resourcegroups/cobey-azuresdkshinydashboardgrp/providers/microsoft.insights/components/cobey-willthisbestatic | 11.028649999999999 | -""" \ No newline at end of file diff --git a/sdk/monitor/azure-monitor-query/samples/sample_log_query_multiple_workspaces.py b/sdk/monitor/azure-monitor-query/samples/sample_log_query_multiple_workspaces.py index 556127a133da..2a4b86674561 100644 --- a/sdk/monitor/azure-monitor-query/samples/sample_log_query_multiple_workspaces.py +++ b/sdk/monitor/azure-monitor-query/samples/sample_log_query_multiple_workspaces.py @@ -1,35 +1,47 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. - +""" +FILE: sample_logs_query_multiple_workspaces.py +DESCRIPTION: + This sample demonstrates authenticating the LogsQueryClient and querying a single query + on multiple workspaces using the additional_workspaces param. +USAGE: + python sample_logs_query_multiple_workspaces.py + Set the environment variables with your own values before running the sample: + 1) LOGS_WORKSPACE_ID - The first (primary) workspace ID. + 2) SECONDARY_WORKSPACE_ID - An additional workspace. + + In order to use the DefaultAzureCredential, the following environment variables must be set: + 1) AZURE_CLIENT_ID - The client ID of a user-assigned managed identity. + 2) AZURE_TENANT_ID - Tenant ID to use when authenticating a user. + 3) AZURE_CLIENT_ID - The client secret to be used for authentication. + +**Note** - Although this example uses pandas to prin the response, it is totally optional and is +not a required package for querying. Alternatively, native python can be used as well. +""" import os import pandas as pd -from datetime import datetime -from msrest.serialization import UTC +from datetime import timedelta from azure.monitor.query import LogsQueryClient +from azure.core.exceptions import HttpResponseError from azure.identity import DefaultAzureCredential credential = DefaultAzureCredential() client = LogsQueryClient(credential) -# Response time trend -# request duration over the last 12 hours. -query = "union * | where TimeGenerated > ago(100d) | project TenantId | summarize count() by TenantId" - -end_time = datetime.now(UTC()) - -# returns LogsQueryResult -response = client.query_workspace( - os.environ['LOG_WORKSPACE_ID'], - query, - additional_workspaces=[os.environ["SECONDARY_WORKSPACE_ID"]], - ) +query= """AppRequests | take 5""" try: - table = response.tables[0] - df = pd.DataFrame(table.rows, columns=[col.name for col in table.columns]) - print(df) -except TypeError: - print(response.error) - - + response = client.query_workspace( + os.environ['LOG_WORKSPACE_ID'], + query, + timespan=timedelta(days=1), + additional_workspaces=[os.environ['SECONDARY_WORKSPACE_ID']] + ) + for table in response: + df = pd.DataFrame(data=table.rows, columns=table.columns) + print(df) +except HttpResponseError as err: + print("something fatal happened") + print (err) diff --git a/sdk/monitor/azure-monitor-query/samples/sample_logs_query_key_value_form.py b/sdk/monitor/azure-monitor-query/samples/sample_logs_query_key_value_form.py index f08b2dd03316..22ec67a6a096 100644 --- a/sdk/monitor/azure-monitor-query/samples/sample_logs_query_key_value_form.py +++ b/sdk/monitor/azure-monitor-query/samples/sample_logs_query_key_value_form.py @@ -1,48 +1,49 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. +""" +FILE: sample_logs_query_key_value_form.py +DESCRIPTION: + This sample demonstrates authenticating the LogsQueryClient and querying a single query + and printing the response in a key value form. +USAGE: + python sample_logs_query_key_value_form.py + Set the environment variables with your own values before running the sample: + 1) LOGS_WORKSPACE_ID - The first (primary) workspace ID. + + In order to use the DefaultAzureCredential, the following environment variables must be set: + 1) AZURE_CLIENT_ID - The client ID of a user-assigned managed identity. + 2) AZURE_TENANT_ID - Tenant ID to use when authenticating a user. + 3) AZURE_CLIENT_ID - The client secret to be used for authentication. +**Note** - Although this example uses pandas to prin the response, it is totally optional and is +not a required package for querying. Alternatively, native python can be used as well. +""" import os import pandas as pd -from datetime import datetime, timedelta -from msrest.serialization import UTC -from azure.monitor.query import LogsQueryClient +from pprint import pprint +from datetime import timedelta +from azure.monitor.query import LogsQueryClient, LogsQueryStatus +from azure.core.exceptions import HttpResponseError from azure.identity import DefaultAzureCredential credential = DefaultAzureCredential() -client = LogsQueryClient(credential) -# Response time trend -# request duration over the last 12 hours. -query = """AppRequests | -summarize avgRequestDuration=avg(DurationMs) by bin(TimeGenerated, 10m), _ResourceId""" +client = LogsQueryClient(credential) -# returns LogsQueryResult -response = client.query_workspace(os.environ['LOG_WORKSPACE_ID'], query, timespan=timedelta(days=1)) +query= """AppRequests | take 5""" try: - table = response.tables[0] - df = pd.DataFrame(table.rows, columns=[col.name for col in table.columns]) - key_value = df.to_dict(orient='records') - print(key_value) -except TypeError: - print(response.error) - -""" -[ - { - 'TimeGenerated': '2021-07-21T04:40:00Z', - '_ResourceId': '/subscriptions/faa080af....', - 'avgRequestDuration': 19.7987 - }, - { - 'TimeGenerated': '2021-07-21T04:50:00Z', - '_ResourceId': '/subscriptions/faa08....', - 'avgRequestDuration': 33.9654 - }, - { - 'TimeGenerated': '2021-07-21T05:00:00Z', - '_ResourceId': '/subscriptions/faa080....', - 'avgRequestDuration': 44.13115 - } -] -""" + response = client.query_workspace(os.environ['LOG_WORKSPACE_ID'], query, timespan=timedelta(days=1)) + if response.status == LogsQueryStatus.PARTIAL: + error = response.partial_error + data = response.partial_data + print(error.message) + elif response.status == LogsQueryStatus.SUCCESS: + data = response.tables + for table in data: + df = pd.DataFrame(data=table.rows, columns=table.columns) + key_value = df.to_dict(orient='records') + pprint(key_value) +except HttpResponseError as err: + print("something fatal happened") + print (err) diff --git a/sdk/monitor/azure-monitor-query/samples/sample_log_query_client.py b/sdk/monitor/azure-monitor-query/samples/sample_logs_single_query.py similarity index 56% rename from sdk/monitor/azure-monitor-query/samples/sample_log_query_client.py rename to sdk/monitor/azure-monitor-query/samples/sample_logs_single_query.py index 3b2ea6179d3c..0e163ea06f78 100644 --- a/sdk/monitor/azure-monitor-query/samples/sample_log_query_client.py +++ b/sdk/monitor/azure-monitor-query/samples/sample_logs_single_query.py @@ -1,6 +1,22 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. +""" +FILE: sample_logs_single_query.py +DESCRIPTION: + This sample demonstrates authenticating the LogsQueryClient and querying a single query. +USAGE: + python sample_logs_single_query.py + Set the environment variables with your own values before running the sample: + 1) LOGS_WORKSPACE_ID - The first (primary) workspace ID. + + In order to use the DefaultAzureCredential, the following environment variables must be set: + 1) AZURE_CLIENT_ID - The client ID of a user-assigned managed identity. + 2) AZURE_TENANT_ID - Tenant ID to use when authenticating a user. + 3) AZURE_CLIENT_ID - The client secret to be used for authentication. +**Note** - Although this example uses pandas to prin the response, it is totally optional and is +not a required package for querying. Alternatively, native python can be used as well. +""" import os import pandas as pd from datetime import timedelta @@ -14,19 +30,18 @@ client = LogsQueryClient(credential) # [END client_auth_with_token_cred] -# Response time trend -# request duration over the last 12 hours. # [START send_logs_query] -query = """AppRadfequests | take 5""" +query= """AppRequests | take 5""" -# returns LogsQueryResult try: response = client.query_workspace(os.environ['LOG_WORKSPACE_ID'], query, timespan=timedelta(days=1)) if response.status == LogsQueryStatus.PARTIAL: - # handle error here error = response.partial_error + data = response.partial_data print(error.message) - for table in response: + elif response.status == LogsQueryStatus.SUCCESS: + data = response.tables + for table in data: df = pd.DataFrame(data=table.rows, columns=table.columns) print(df) except HttpResponseError as err: diff --git a/sdk/monitor/azure-monitor-query/samples/sample_logs_single_query_partial_result.py b/sdk/monitor/azure-monitor-query/samples/sample_logs_single_query_partial_result.py new file mode 100644 index 000000000000..6c0d41a575a7 --- /dev/null +++ b/sdk/monitor/azure-monitor-query/samples/sample_logs_single_query_partial_result.py @@ -0,0 +1,60 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +""" +FILE: sample_logs_single_query_partial_result.py +DESCRIPTION: + This sample demonstrates authenticating the LogsQueryClient and querying a single query + and handling a partial query response. +USAGE: + python sample_logs_single_query_partial_result.py + Set the environment variables with your own values before running the sample: + 1) LOGS_WORKSPACE_ID - The first (primary) workspace ID. + + In order to use the DefaultAzureCredential, the following environment variables must be set: + 1) AZURE_CLIENT_ID - The client ID of a user-assigned managed identity. + 2) AZURE_TENANT_ID - Tenant ID to use when authenticating a user. + 3) AZURE_CLIENT_ID - The client secret to be used for authentication. + +**Note** - Although this example uses pandas to prin the response, it is totally optional and is +not a required package for querying. Alternatively, native python can be used as well. +""" +import os +import pandas as pd +from datetime import timedelta +from azure.monitor.query import LogsQueryClient, LogsQueryStatus +from azure.core.exceptions import HttpResponseError +from azure.identity import DefaultAzureCredential + +credential = DefaultAzureCredential() + +client = LogsQueryClient(credential) + +query= """let Weight = 92233720368547758; + range x from 1 to 3 step 1 + | summarize percentilesw(x, Weight * 100, 50)""" + + +# this block of code is exactly the same whether the expected result is a success, a failure or a +# partial success +try: + response = client.query_workspace(os.environ['LOG_WORKSPACE_ID'], query, timespan=timedelta(days=1)) + if response.status == LogsQueryStatus.PARTIAL: + # handle error here + error = response.partial_error + data = response.partial_data + print(error.message) + elif response.status == LogsQueryStatus.SUCCESS: + data = response.tables + for table in data: + df = pd.DataFrame(data=table.rows, columns=table.columns) + print(df) +except HttpResponseError as err: + print("something fatal happened") + print (err) + +""" + TimeGenerated _ResourceId avgRequestDuration +0 2021-05-27T08:40:00Z /subscriptions/faa080af-c1d8-40ad-9cce-e1a450c... 27.307699999999997 +1 2021-05-27T08:50:00Z /subscriptions/faa080af-c1d8-40ad-9cce-e1a450c... 18.11655 +2 2021-05-27T09:00:00Z /subscriptions/faa080af-c1d8-40ad-9cce-e1a450c... 24.5271 +""" diff --git a/sdk/monitor/azure-monitor-query/samples/sample_metric_definitions.py b/sdk/monitor/azure-monitor-query/samples/sample_metric_definitions.py index f8694b559e05..8ab1778a2c85 100644 --- a/sdk/monitor/azure-monitor-query/samples/sample_metric_definitions.py +++ b/sdk/monitor/azure-monitor-query/samples/sample_metric_definitions.py @@ -1,6 +1,20 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. +""" +FILE: sample_metric_definitions.py +DESCRIPTION: + This sample demonstrates listing all the metric definitions of a resource. +USAGE: + python sample_metric_definitions.py + Set the environment variables with your own values before running the sample: + 1) METRICS_RESOURCE_URI - The resource uri of the resource for which the metrics are being queried. + In this example, an eventgrid account resource URI is taken. + In order to use the DefaultAzureCredential, the following environment variables must be set: + 1) AZURE_CLIENT_ID - The client ID of a user-assigned managed identity. + 2) AZURE_TENANT_ID - Tenant ID to use when authenticating a user. + 3) AZURE_CLIENT_ID - The client secret to be used for authentication. +""" import os from azure.monitor.query import MetricsQueryClient from azure.identity import DefaultAzureCredential @@ -9,10 +23,10 @@ client = MetricsQueryClient(credential) -metrics_uri = os.environ['METRICS_RESOURCE_URI'] -response = client.list_metric_definitions(metrics_uri, metric_namespace='microsoft.eventgrid/topics') +metrics_uri = os.environ.get('METRICS_RESOURCE_URI') +response = client.list_metric_definitions(metrics_uri, namespace='microsoft.eventgrid/topics') for item in response: - print(item) + print(item.name) for availability in item.metric_availabilities: - print(availability.time_grain) + print(availability.granularity) diff --git a/sdk/monitor/azure-monitor-query/samples/sample_metric_namespaces.py b/sdk/monitor/azure-monitor-query/samples/sample_metric_namespaces.py index 78b997d0fa7f..ccc51bbf0fb6 100644 --- a/sdk/monitor/azure-monitor-query/samples/sample_metric_namespaces.py +++ b/sdk/monitor/azure-monitor-query/samples/sample_metric_namespaces.py @@ -1,6 +1,20 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. +""" +FILE: sample_metric_namespaces.py +DESCRIPTION: + This sample demonstrates listing all the metric namespaces of a resource. +USAGE: + python sample_metric_namespaces.py + Set the environment variables with your own values before running the sample: + 1) METRICS_RESOURCE_URI - The resource uri of the resource for which the metrics are being queried. + In this example, a storage account resource URI is taken. + In order to use the DefaultAzureCredential, the following environment variables must be set: + 1) AZURE_CLIENT_ID - The client ID of a user-assigned managed identity. + 2) AZURE_TENANT_ID - Tenant ID to use when authenticating a user. + 3) AZURE_CLIENT_ID - The client secret to be used for authentication. +""" import os from azure.monitor.query import MetricsQueryClient from azure.identity import DefaultAzureCredential diff --git a/sdk/monitor/azure-monitor-query/samples/sample_metrics_query.py b/sdk/monitor/azure-monitor-query/samples/sample_metrics_query.py new file mode 100644 index 000000000000..0c1844b59792 --- /dev/null +++ b/sdk/monitor/azure-monitor-query/samples/sample_metrics_query.py @@ -0,0 +1,52 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +""" +FILE: sample_metrics_query.py +DESCRIPTION: + This sample demonstrates authenticating the LogsQueryClient and querying a single query + on multiple workspaces using the additional_workspaces param. +USAGE: + python sample_metrics_query.py + Set the environment variables with your own values before running the sample: + 1) METRICS_RESOURCE_URI - The resource uri of the resource for which the metrics are being queried. + In this example, a storage account resource URI is taken. + + In order to use the DefaultAzureCredential, the following environment variables must be set: + 1) AZURE_CLIENT_ID - The client ID of a user-assigned managed identity. + 2) AZURE_TENANT_ID - Tenant ID to use when authenticating a user. + 3) AZURE_CLIENT_ID - The client secret to be used for authentication. +""" +import os +from datetime import timedelta +import urllib3 +from azure.monitor.query import MetricsQueryClient, MetricAggregationType +from azure.identity import DefaultAzureCredential + +# provide a cert or disable warnings to run this sample +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + +# [START metrics_client_auth_with_token_cred] +credential = DefaultAzureCredential() + +client = MetricsQueryClient(credential) +# [END metrics_client_auth_with_token_cred] + +# [START send_metrics_query] +metrics_uri = os.environ.get('METRICS_RESOURCE_URI') +response = client.query_resource( + metrics_uri, + metric_names=["Ingress"], + timespan=timedelta(hours=2), + granularity=timedelta(minutes=5), + aggregations=[MetricAggregationType.AVERAGE], + ) + +for metric in response.metrics: + print(metric.name + ' -- ' + metric.display_description) + for time_series_element in metric.timeseries: + for metric_value in time_series_element.data: + print('The ingress at {} is {}'.format( + metric_value.timestamp, + metric_value.average + )) +# [END send_metrics_query] diff --git a/sdk/monitor/azure-monitor-query/samples/sample_metrics_query_client.py b/sdk/monitor/azure-monitor-query/samples/sample_metrics_query_client.py deleted file mode 100644 index 3052ddda826f..000000000000 --- a/sdk/monitor/azure-monitor-query/samples/sample_metrics_query_client.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. - -import os -from datetime import datetime, timedelta -import urllib3 -from azure.monitor.query import MetricsQueryClient, MetricAggregationType -from azure.identity import DefaultAzureCredential - -# urllib3.disable_warnings() - -# [START metrics_client_auth_with_token_cred] -credential = DefaultAzureCredential() - -client = MetricsQueryClient(credential) -# [END metrics_client_auth_with_token_cred] - -# [START send_metrics_query] -metrics_uri = os.environ['METRICS_RESOURCE_URI'] -response = client.query_resource( - metrics_uri, - metric_names=["Ingress"], - timespan=timedelta(hours=2), - granularity=timedelta(minutes=5), - aggregations=[MetricAggregationType.AVERAGE], - ) - -for metric in response.metrics: - print(metric.name + ' -- ' + metric.display_description) - for time_series_element in metric.timeseries: - for metric_value in time_series_element.data: - print('The ingress at {} is {}'.format( - metric_value.timestamp, - metric_value.average - )) -# [END send_metrics_query] diff --git a/sdk/monitor/azure-monitor-query/samples/sample_server_timeout.py b/sdk/monitor/azure-monitor-query/samples/sample_server_timeout.py index b350adf60cb7..812091440925 100644 --- a/sdk/monitor/azure-monitor-query/samples/sample_server_timeout.py +++ b/sdk/monitor/azure-monitor-query/samples/sample_server_timeout.py @@ -1,25 +1,51 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. +""" +FILE: sample_server_timeout.py +DESCRIPTION: + This sample demostrates how to update a server timeout for a long running query. +USAGE: + python sample_server_timeout.py + Set the environment variables with your own values before running the sample: + 1) LOGS_WORKSPACE_ID - The first (primary) workspace ID. + In order to use the DefaultAzureCredential, the following environment variables must be set: + 1) AZURE_CLIENT_ID - The client ID of a user-assigned managed identity. + 2) AZURE_TENANT_ID - Tenant ID to use when authenticating a user. + 3) AZURE_CLIENT_ID - The client secret to be used for authentication. + +**Note** - Although this example uses pandas to prin the response, it is totally optional and is +not a required package for querying. Alternatively, native python can be used as well. +""" import os import pandas as pd -from azure.monitor.query import LogsQueryClient +from datetime import timedelta +from azure.monitor.query import LogsQueryClient, LogsQueryStatus +from azure.core.exceptions import HttpResponseError from azure.identity import DefaultAzureCredential - credential = DefaultAzureCredential() client = LogsQueryClient(credential) -response = client.query_workspace( - os.environ['LOG_WORKSPACE_ID'], - "range x from 1 to 10000000000 step 1 | count", - server_timeout=1, - ) +query= "range x from 1 to 10000000000 step 1 | count" try: - table = response.tables[0] - df = pd.DataFrame(table.rows, columns=[col.name for col in table.columns]) - print(df) -except TypeError: - print(response.error) + response = client.query_workspace( + os.environ['LOG_WORKSPACE_ID'], + query, + timespan=timedelta(days=1), + server_timeout=3 + ) + if response.status == LogsQueryStatus.PARTIAL: + error = response.partial_error + data = response.partial_data + print(error.message) + elif response.status == LogsQueryStatus.SUCCESS: + data = response.tables + for table in data: + df = pd.DataFrame(data=table.rows, columns=table.columns) + print(df) +except HttpResponseError as err: + print("something fatal happened") + print (err) diff --git a/sdk/monitor/azure-monitor-query/samples/sample_single_log_query_without_pandas.py b/sdk/monitor/azure-monitor-query/samples/sample_single_log_query_without_pandas.py new file mode 100644 index 000000000000..5f8a9f09fafd --- /dev/null +++ b/sdk/monitor/azure-monitor-query/samples/sample_single_log_query_without_pandas.py @@ -0,0 +1,49 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +""" +FILE: sample_single_log_query_without_pandas.py +DESCRIPTION: + This sample demonstrates authenticating the LogsQueryClient and querying a single query + and handling a query response without using pandas. +USAGE: + python sample_single_log_query_without_pandas.py + Set the environment variables with your own values before running the sample: + 1) LOGS_WORKSPACE_ID - The first (primary) workspace ID. + + In order to use the DefaultAzureCredential, the following environment variables must be set: + 1) AZURE_CLIENT_ID - The client ID of a user-assigned managed identity. + 2) AZURE_TENANT_ID - Tenant ID to use when authenticating a user. + 3) AZURE_CLIENT_ID - The client secret to be used for authentication. +""" +import os +from datetime import timedelta +from azure.monitor.query import LogsQueryClient, LogsQueryStatus +from azure.core.exceptions import HttpResponseError +from azure.identity import DefaultAzureCredential + +credential = DefaultAzureCredential() + +client = LogsQueryClient(credential) + +query= """AppRequests | take 5""" + + +try: + response = client.query_workspace(os.environ['LOG_WORKSPACE_ID'], query, timespan=timedelta(days=1)) + if response.status == LogsQueryStatus.PARTIAL: + # handle error here + error = response.partial_error + data = response.partial_data + print(error.message) + elif response.status == LogsQueryStatus.SUCCESS: + data = response.tables + for table in data: + for col in table.columns: + print(col + " ", end="") + for row in table.rows: + for item in row: + print(item, end="") + print('\n') +except HttpResponseError as err: + print("something fatal happened") + print (err) diff --git a/sdk/monitor/azure-monitor-query/tests/test_logs_client.py b/sdk/monitor/azure-monitor-query/tests/test_logs_client.py index 51ef4e644086..903151418791 100644 --- a/sdk/monitor/azure-monitor-query/tests/test_logs_client.py +++ b/sdk/monitor/azure-monitor-query/tests/test_logs_client.py @@ -177,7 +177,6 @@ def test_logs_query_batch_with_statistics_in_some(): assert response[0].statistics is None assert response[2].statistics is not None -@pytest.mark.skip('https://github.com/Azure/azure-sdk-for-python/issues/19382') @pytest.mark.live_test_only def test_logs_single_query_additional_workspaces(): credential = _credential() @@ -196,27 +195,27 @@ def test_logs_single_query_additional_workspaces(): assert len(response.tables[0].rows) == 2 @pytest.mark.live_test_only -@pytest.mark.skip('https://github.com/Azure/azure-sdk-for-python/issues/19382') def test_logs_query_batch_additional_workspaces(): client = LogsQueryClient(_credential()) query = "union * | where TimeGenerated > ago(100d) | project TenantId | summarize count() by TenantId" requests = [ LogsBatchQuery( + os.environ['LOG_WORKSPACE_ID'], query, timespan=timedelta(hours=1), - workspace_id= os.environ['LOG_WORKSPACE_ID'], additional_workspaces=[os.environ['SECONDARY_WORKSPACE_ID']] ), LogsBatchQuery( + os.environ['LOG_WORKSPACE_ID'], query, timespan=timedelta(hours=1), - workspace_id= os.environ['LOG_WORKSPACE_ID'], additional_workspaces=[os.environ['SECONDARY_WORKSPACE_ID']] ), LogsBatchQuery( + os.environ['LOG_WORKSPACE_ID'], query, - workspace_id= os.environ['LOG_WORKSPACE_ID'], + timespan=timedelta(hours=1), additional_workspaces=[os.environ['SECONDARY_WORKSPACE_ID']] ), ]