diff --git a/sdk/monitor/azure-monitor-query/CHANGELOG.md b/sdk/monitor/azure-monitor-query/CHANGELOG.md index 6589176e48db..94a92b8cc700 100644 --- a/sdk/monitor/azure-monitor-query/CHANGELOG.md +++ b/sdk/monitor/azure-monitor-query/CHANGELOG.md @@ -4,6 +4,8 @@ ### Features Added +- Added additional `display_description` attribute to the `Metric` type. + ### Breaking Changes - Rename `batch_query` to `query_batch`. @@ -15,7 +17,8 @@ - `top` is renamed to `max_results` in the metric's `query` API. - `metric_namespace_name` is renamed to `fully_qualified_namespace` - `is_dimension_required` is renamed to `dimension_required` -- `time_grain` is renamed to `granularity` +- `interval` and `time_grain` are renamed to `granularity` +- `orderby` is renamed to `order_by` - `LogsQueryResult` now returns `datetime` objects for a time values. ### Bugs Fixed diff --git a/sdk/monitor/azure-monitor-query/README.md b/sdk/monitor/azure-monitor-query/README.md index 336a887da4e5..a87aa1ae263d 100644 --- a/sdk/monitor/azure-monitor-query/README.md +++ b/sdk/monitor/azure-monitor-query/README.md @@ -289,11 +289,11 @@ for metric in response.metrics: ### Handle metrics response -The metrics query API returns a `MetricsResult` object. The `MetricsResult` object contains properties such as a list of `Metric`-typed objects, `interval`, `namespace`, and `timespan`. The `Metric` objects list can be accessed using the `metrics` param. Each `Metric` object in this list contains a list of `TimeSeriesElement` objects. Each `TimeSeriesElement` contains `data` and `metadata_values` properties. In visual form, the object hierarchy of the response resembles the following structure: +The metrics query API returns a `MetricsResult` object. The `MetricsResult` object contains properties such as a list of `Metric`-typed objects, `granularity`, `namespace`, and `timespan`. The `Metric` objects list can be accessed using the `metrics` param. Each `Metric` object in this list contains a list of `TimeSeriesElement` objects. Each `TimeSeriesElement` contains `data` and `metadata_values` properties. In visual form, the object hierarchy of the response resembles the following structure: ``` MetricsResult -|---interval +|---granularity |---timespan |---cost |---namespace 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 0b45d1bc10b3..e63e04832b21 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 @@ -68,8 +68,8 @@ def query(self, resource_uri, metric_names, **kwargs): a timedelta and a start datetime, or a start datetime/end datetime. :paramtype timespan: ~datetime.timedelta or tuple[~datetime.datetime, ~datetime.timedelta] or tuple[~datetime.datetime, ~datetime.datetime] - :keyword interval: The interval (i.e. timegrain) of the query. - :paramtype interval: ~datetime.timedelta + :keyword granularity: The granularity (i.e. timegrain) of the query. + :paramtype granularity: ~datetime.timedelta :keyword aggregations: The list of aggregation types to retrieve. Use `azure.monitor.query.AggregationType` enum to get each aggregation type. :paramtype aggregations: list[str] @@ -77,10 +77,10 @@ def query(self, resource_uri, metric_names, **kwargs): Valid only if $filter is specified. Defaults to 10. :paramtype max_results: int - :keyword orderby: The aggregation to use for sorting results and the direction of the sort. + :keyword order_by: The aggregation to use for sorting results and the direction of the sort. Only one order can be specified. Examples: sum asc. - :paramtype orderby: str + :paramtype order_by: str :keyword filter: The **$filter** is used to reduce the set of metric data returned.:code:`
`Example::code:`
`Metric contains metadata A, B and C.:code:`
`- Return all time series of C where A = a1 and B = b1 or b2:code:`
`\ **$filter=A eq ‘a1’ and @@ -117,6 +117,8 @@ def query(self, resource_uri, metric_names, **kwargs): kwargs.setdefault("metricnames", ",".join(metric_names)) kwargs.setdefault("timespan", timespan) kwargs.setdefault("top", kwargs.pop("max_results", None)) + kwargs.setdefault("interval", kwargs.pop("granularity", None)) + kwargs.setdefault("orderby", kwargs.pop("order_by", None)) generated = self._metrics_op.list(resource_uri, connection_verify=False, **kwargs) return MetricsResult._from_generated(generated) # pylint: disable=protected-access 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 fcc22a6ba687..ebdb22a614f2 100644 --- a/sdk/monitor/azure-monitor-query/azure/monitor/query/_models.py +++ b/sdk/monitor/azure-monitor-query/azure/monitor/query/_models.py @@ -115,10 +115,10 @@ class MetricsResult(object): two datetimes concatenated, separated by '/'. This may be adjusted in the future and returned back from what was originally requested. :vartype timespan: str - :ivar interval: The interval (window size) for which the metric data was returned in. This + :ivar granularity: The granularity (window size) for which the metric data was returned in. This may be adjusted in the future and returned back from what was originally requested. This is not present if a metadata request was made. - :vartype interval: ~datetime.timedelta + :vartype granularity: ~datetime.timedelta :ivar namespace: The namespace of the metrics that has been queried. :vartype namespace: str :ivar resource_region: The region of the resource that has been queried for metrics. @@ -130,7 +130,7 @@ def __init__(self, **kwargs): # type: (Any) -> None self.cost = kwargs.get("cost", None) self.timespan = kwargs["timespan"] - self.interval = kwargs.get("interval", None) + self.granularity = kwargs.get("granularity", None) self.namespace = kwargs.get("namespace", None) self.resource_region = kwargs.get("resource_region", None) self.metrics = kwargs["metrics"] @@ -142,7 +142,7 @@ def _from_generated(cls, generated): return cls( cost=generated.cost, timespan=generated.timespan, - interval=generated.interval, + granularity=generated.interval, namespace=generated.namespace, resource_region=generated.resourceregion, metrics=[Metric._from_generated(m) for m in generated.value] # pylint: disable=protected-access @@ -459,6 +459,8 @@ class Metric(object): :vartype unit: str :ivar timeseries: Required. The time series returned when a data query is performed. :vartype timeseries: list[~monitor_query_client.models.TimeSeriesElement] + :ivar display_description: Detailed description of this metric. + :vartype display_description: str """ def __init__( self, @@ -470,6 +472,7 @@ def __init__( self.name = kwargs['name'] self.unit = kwargs['unit'] self.timeseries = kwargs['timeseries'] + self.display_description = kwargs['display_description'] @classmethod def _from_generated(cls, generated): @@ -482,7 +485,8 @@ def _from_generated(cls, generated): unit=generated.unit, timeseries=[ TimeSeriesElement._from_generated(t) for t in generated.timeseries # pylint: disable=protected-access - ] + ], + display_description=generated.display_description, ) 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 69da6544cb8c..f1a772c1df7d 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 @@ -62,8 +62,8 @@ async def query( a timedelta and a start datetime, or a start datetime/end datetime. :paramtype timespan: ~datetime.timedelta or tuple[~datetime.datetime, ~datetime.timedelta] or tuple[~datetime.datetime, ~datetime.datetime] - :keyword interval: The interval (i.e. timegrain) of the query. - :paramtype interval: ~datetime.timedelta + :keyword granularity: The interval (i.e. timegrain) of the query. + :paramtype granularity: ~datetime.timedelta :keyword aggregations: The list of aggregation types to retrieve. Use `azure.monitor.query.AggregationType` enum to get each aggregation type. :paramtype aggregations: list[str] @@ -71,10 +71,10 @@ async def query( Valid only if $filter is specified. Defaults to 10. :paramtype max_results: int - :keyword orderby: The aggregation to use for sorting results and the direction of the sort. + :keyword order_by: The aggregation to use for sorting results and the direction of the sort. Only one order can be specified. Examples: sum asc. - :paramtype orderby: str + :paramtype order_by: str :keyword filter: The **$filter** is used to reduce the set of metric data returned.:code:`
`Example::code:`
`Metric contains metadata A, B and C.:code:`
`- Return all time series of C where A = a1 and B = b1 or b2:code:`
`\ **$filter=A eq ‘a1’ and @@ -98,6 +98,8 @@ async def query( kwargs.setdefault("metricnames", ",".join(metric_names)) kwargs.setdefault("timespan", timespan) kwargs.setdefault("top", kwargs.pop("max_results", None)) + kwargs.setdefault("interval", kwargs.pop("granularity", None)) + kwargs.setdefault("orderby", kwargs.pop("order_by", None)) aggregations = kwargs.pop("aggregations", None) if aggregations: kwargs.setdefault("aggregation", ",".join(aggregations)) 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 d9457b6d4b66..fd2d13a4b891 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 @@ -20,18 +20,26 @@ query = """AppRequests | summarize avgRequestDuration=avg(DurationMs) by bin(TimeGenerated, 10m), _ResourceId""" +query = """ +AppRequests +| where TimeGenerated > ago(1h) +| fork + ( summarize avgRequestDuration=avg(DurationMs) by bin(TimeGenerated, 10m), _ResourceId ) +""" + # returns LogsQueryResult response = client.query(os.environ['LOG_WORKSPACE_ID'], query, timespan=timedelta(days=1)) if not response.tables: print("No results for the query") -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) +for table in response.tables: + try: + print ([col.name for col in table.columns]) + df = pd.DataFrame(table.rows, columns=[col.name for col in table.columns]) + print(df) + except TypeError: + print(response.error) # [END send_logs_query] """ TimeGenerated _ResourceId avgRequestDuration 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 f5f32ce73996..78b997d0fa7f 100644 --- a/sdk/monitor/azure-monitor-query/samples/sample_metric_namespaces.py +++ b/sdk/monitor/azure-monitor-query/samples/sample_metric_namespaces.py @@ -13,5 +13,5 @@ response = client.list_metric_namespaces(metrics_uri) for item in response: - print(item.metric_namespace_name) + print(item.fully_qualified_namespace) print(item.type) 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 index 7bca1ab1aa24..15c6dcbdf157 100644 --- a/sdk/monitor/azure-monitor-query/samples/sample_metrics_query_client.py +++ b/sdk/monitor/azure-monitor-query/samples/sample_metrics_query_client.py @@ -19,9 +19,8 @@ metrics_uri = os.environ['METRICS_RESOURCE_URI'] response = client.query( metrics_uri, - metric_names=["MatchedEventCount"], - start_time=datetime(2021, 6, 21), - duration=timedelta(days=1), + metric_names=["MatchedEventCount", "DeliverySuccesssCount"], + timespan=timedelta(days=1), aggregations=[AggregationType.COUNT] ) diff --git a/sdk/monitor/azure-monitor-query/tests/async/test_metrics_client_async.py b/sdk/monitor/azure-monitor-query/tests/async/test_metrics_client_async.py index fb76a4f4d7ea..ab796d7d0924 100644 --- a/sdk/monitor/azure-monitor-query/tests/async/test_metrics_client_async.py +++ b/sdk/monitor/azure-monitor-query/tests/async/test_metrics_client_async.py @@ -14,6 +14,7 @@ def _credential(): return credential @pytest.mark.live_test_only +@pytest.mark.asyncio async def test_metrics_auth(): credential = _credential() client = MetricsQueryClient(credential) @@ -26,6 +27,21 @@ async def test_metrics_auth(): assert response assert response.metrics +@pytest.mark.live_test_only +@pytest.mark.asyncio +async def test_metrics_granularity(): + credential = _credential() + client = MetricsQueryClient(credential) + response = await client.query( + os.environ['METRICS_RESOURCE_URI'], + metric_names=["MatchedEventCount"], + timespan=timedelta(days=1), + granularity=timedelta(minutes=5), + aggregations=[AggregationType.COUNT] + ) + assert response + assert response.granularity == timedelta(minutes=5) + @pytest.mark.live_test_only async def test_metrics_namespaces(): client = MetricsQueryClient(_credential()) diff --git a/sdk/monitor/azure-monitor-query/tests/test_metrics_client.py b/sdk/monitor/azure-monitor-query/tests/test_metrics_client.py index 95ee209b6775..082da65c4385 100644 --- a/sdk/monitor/azure-monitor-query/tests/test_metrics_client.py +++ b/sdk/monitor/azure-monitor-query/tests/test_metrics_client.py @@ -25,6 +25,20 @@ def test_metrics_auth(): assert response assert response.metrics +@pytest.mark.live_test_only +def test_metrics_granularity(): + credential = _credential() + client = MetricsQueryClient(credential) + response = client.query( + os.environ['METRICS_RESOURCE_URI'], + metric_names=["MatchedEventCount"], + timespan=timedelta(days=1), + granularity=timedelta(minutes=5), + aggregations=[AggregationType.COUNT] + ) + assert response + assert response.granularity == timedelta(minutes=5) + @pytest.mark.live_test_only def test_metrics_namespaces(): client = MetricsQueryClient(_credential())