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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions sdk/monitor/azure-monitor-query/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

- Added enum `AggregationType` which can be used to specify aggregations in the query API.
- Added `LogsBatchQueryResult` model that is returned for a logs batch query.
- Added `error` attribute to `LogsQueryResult`.

### Breaking Changes

Expand All @@ -15,6 +16,7 @@
- `LogsBatchResults` model is now removed.
- `LogsQueryRequest` is renamed to `LogsBatchQueryRequest`
- `LogsQueryResults` is now renamed to `LogsQueryResult`
- `LogsBatchQueryResult` now has 4 additional attributes - `tables`, `error`, `statistics` and `render` instead of `body` attribute.

### Bugs Fixed

Expand Down
37 changes: 30 additions & 7 deletions sdk/monitor/azure-monitor-query/azure/monitor/query/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,15 @@ class LogsQueryResult(object):
:paramtype statistics: object
:keyword render: Any object.
:paramtype render: object
:keyword error: Any object.
:paramtype error: object
Copy link
Contributor

Choose a reason for hiding this comment

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

is this more of a result object or would a user create this in code? I ask because I think it would make more sense to document these as ivars if it's just a result object (edit: same for the type below)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fair enough - updating

"""
def __init__(self, **kwargs):
# type: (Any) -> None
self.tables = kwargs.get("tables", None)
self.statistics = kwargs.get("statistics", None)
self.render = kwargs.get("render", None)
self.error = kwargs.get("error", None)

@classmethod
def _from_generated(cls, generated):
Expand All @@ -94,7 +97,8 @@ def _from_generated(cls, generated):
return cls(
tables=tables,
statistics=generated.statistics,
render=generated.render
render=generated.render,
error=generated.error
)


Expand Down Expand Up @@ -209,29 +213,48 @@ def __init__(self, query, workspace_id, duration=None, **kwargs): #pylint: disab
class LogsBatchQueryResult(object):
"""The LogsBatchQueryResult.

:param id:
:param id: the request id of the request that was sent.
:type id: str
:param status:
:param status: status code of the response.
:type status: int
:param body: Contains the tables, columns & rows resulting from a query.
:type body: ~azure.monitor.query.LogsQueryResult
:keyword tables: The list of tables, columns and rows.
:paramtype tables: list[~azure.monitor.query.LogsQueryResultTable]
:keyword statistics: Any object.
:paramtype statistics: object
:keyword render: Any object.
:paramtype render: object
:keyword error: Any object.
:paramtype error: object
"""
def __init__(
self,
**kwargs
):
self.id = kwargs.get('id', None)
self.status = kwargs.get('status', None)
self.body = kwargs.get('body', None)
self.tables = kwargs.get('tables', None)
self.error = kwargs.get('error', None)
self.statistics = kwargs.get('statistics', None)
self.render = kwargs.get('render', None)

@classmethod
def _from_generated(cls, generated):
if not generated:
return cls()
tables = None
if generated.body.tables is not None:
tables = [
LogsQueryResultTable._from_generated( # pylint: disable=protected-access
table
) for table in generated.body.tables
]
return cls(
id=generated.id,
status=generated.status,
body=LogsQueryResult._from_generated(generated.body) # pylint: disable=protected-access
tables=tables,
statistics=generated.body.statistics,
render=generated.body.render,
error=generated.body.error
)


Expand Down
16 changes: 7 additions & 9 deletions sdk/monitor/azure-monitor-query/samples/sample_batch_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,19 @@
workspace_id= os.environ['LOG_WORKSPACE_ID']
),
LogsBatchQueryRequest(
query= "AppRequests | take 5",
query= "AppRequestss | take 5",
Copy link
Contributor

Choose a reason for hiding this comment

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

intentional change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep - to show how to process an error

workspace_id= os.environ['LOG_WORKSPACE_ID'],
include_statistics=True
),
]
responses = client.batch_query(requests)

for response in responses:
body = response.body
print(response.id)
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])
print(df)
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)

# [END send_batch_query]
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,12 @@
"workspace": os.environ['LOG_WORKSPACE_ID']
}
]
response = client.batch_query(requests)
responses = client.batch_query(requests)

for response in response.responses:
body = response.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])
print(df)
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)
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@
if not response.tables:
print("No results for the query")

for table in response.tables:
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)
# [END send_logs_query]
"""
TimeGenerated _ResourceId avgRequestDuration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@
additional_workspaces=[os.environ["SECONDARY_WORKSPACE_ID"]],
)

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

for table in response.tables:
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)


Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@
# returns LogsQueryResult
response = client.query(os.environ['LOG_WORKSPACE_ID'], query, duration=timedelta(days=1), end_time=end_time)

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

for table in response.tables:
pd.json_normalize
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)

"""
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
server_timeout=1,
)

for table in response.tables:
try:
table = response.tables[0]
df = pd.DataFrame(table.rows, columns=[col.name for col in table.columns])
print(df)
print(df)
except TypeError:
print(response.error)
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,4 @@ async def test_logs_batch_query_additional_workspaces():
assert len(response) == 3

for resp in response:
assert len(resp.body.tables[0].rows) == 2
assert len(resp.tables[0].rows) == 2
6 changes: 3 additions & 3 deletions sdk/monitor/azure-monitor-query/tests/test_logs_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ def test_logs_batch_query_with_statistics_in_some():
response = client.batch_query(requests)

assert len(response) == 3
assert response[0].body.statistics is None
assert response[2].body.statistics is not None
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
Expand Down Expand Up @@ -171,4 +171,4 @@ def test_logs_batch_query_additional_workspaces():
response = client.batch_query(requests)

for resp in response:
assert len(resp.body.tables[0].rows) == 2
assert len(resp.tables[0].rows) == 2