Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Azure Monitor Query SDK for Python. Use for querying Log Analytics workspaces and Azure Monitor metrics.
.claude/skills/azure-monitor-query-py/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-05 | ✗→✓ | ▲ Improved | — | — |
| case-04 | ✗→✓ | ▲ Improved | — | — |
| case-16 | ✗→✓ | ▲ Improved | — | — |
| case-01 | ✗→✓ | ▲ Improved | — | — |
| case-11 | ✗→✓ | ▲ Improved | — | — |
Query logs and metrics from Azure Monitor and Log Analytics workspaces.
bashpip install azure-monitor-query
bash# Log Analytics AZURE_LOG_ANALYTICS_WORKSPACE_ID=<workspace-id> # Metrics AZURE_METRICS_RESOURCE_URI=/subscriptions/<sub>/resourceGroups/<rg>/providers/<provider>/<type>/<name>
pythonfrom azure.identity import DefaultAzureCredential credential = DefaultAzureCredential()
pythonfrom azure.monitor.query import LogsQueryClient from datetime import timedelta client = LogsQueryClient(credential) query = """ AppRequests | where TimeGenerated > ago(1h) | summarize count() by bin(TimeGenerated, 5m), ResultCode | order by TimeGenerated desc """ response = client.query_workspace( workspace_id=os.environ["AZURE_LOG_ANALYTICS_WORKSPACE_ID"], query=query, timespan=timedelta(hours=1) ) for table in response.tables: for row in table.rows: print(row)
pythonfrom datetime import datetime, timezone response = client.query_workspace( workspace_id=workspace_id, query="AppRequests | take 10", timespan=( datetime(2024, 1, 1, tzinfo=timezone.utc), datetime(2024, 1, 2, tzinfo=timezone.utc) ) )
pythonimport pandas as pd response = client.query_workspace(workspace_id, query, timespan=timedelta(hours=1)) if response.tables: table = response.tables[0] df = pd.DataFrame(data=table.rows, columns=[col.name for col in table.columns]) print(df.head())
pythonfrom azure.monitor.query import LogsBatchQuery queries = [ LogsBatchQuery(workspace_id=workspace_id, query="AppRequests | take 5", timespan=timedelta(hours=1)), LogsBatchQuery(workspace_id=workspace_id, query="AppExceptions | take 5", timespan=timedelta(hours=1)) ] responses = client.query_batch(queries) for response in responses: if response.tables: print(f"Rows: {len(response.tables[0].rows)}")
pythonfrom azure.monitor.query import LogsQueryStatus response = client.query_workspace(workspace_id, query, timespan=timedelta(hours=24)) if response.status == LogsQueryStatus.PARTIAL: print(f"Partial results: {response.partial_error}") elif response.status == LogsQueryStatus.FAILURE: print(f"Query failed: {response.partial_error}")
pythonfrom azure.monitor.query import MetricsQueryClient from datetime import timedelta metrics_client = MetricsQueryClient(credential) response = metrics_client.query_resource( resource_uri=os.environ["AZURE_METRICS_RESOURCE_URI"], metric_names=["Percentage CPU", "Network In Total"], timespan=timedelta(hours=1), granularity=timedelta(minutes=5) ) for metric in response.metrics: print(f"{metric.name}:") for time_series in metric.timeseries: for data in time_series.data: print(f" {data.timestamp}: {data.average}")
pythonfrom azure.monitor.query import MetricAggregationType response = metrics_client.query_resource( resource_uri=resource_uri, metric_names=["Requests"], timespan=timedelta(hours=1), aggregations=[ MetricAggregationType.AVERAGE, MetricAggregationType.MAXIMUM, MetricAggregationType.MINIMUM, MetricAggregationType.COUNT ] )
pythonresponse = metrics_client.query_resource( resource_uri=resource_uri, metric_names=["Requests"], timespan=timedelta(hours=1), filter="ApiName eq 'GetBlob'" )
pythondefinitions = metrics_client.list_metric_definitions(resource_uri) for definition in definitions: print(f"{definition.name}: {definition.unit}")
pythonnamespaces = metrics_client.list_metric_namespaces(resource_uri) for ns in namespaces: print(ns.fully_qualified_namespace)
pythonfrom azure.monitor.query.aio import LogsQueryClient, MetricsQueryClient from azure.identity.aio import DefaultAzureCredential async def query_logs(): credential = DefaultAzureCredential() client = LogsQueryClient(credential) response = await client.query_workspace( workspace_id=workspace_id, query="AppRequests | take 10", timespan=timedelta(hours=1) ) await client.close() await credential.close() return response
kusto// Requests by status code AppRequests | summarize count() by ResultCode | order by count_ desc // Exceptions over time AppExceptions | summarize count() by bin(TimeGenerated, 1h) // Slow requests AppRequests | where DurationMs > 1000 | project TimeGenerated, Name, DurationMs | order by DurationMs desc // Top errors AppExceptions | summarize count() by ExceptionType | top 10 by count_
| Client | Purpose | |--------|---------| | LogsQueryClient | Query Log Analytics workspaces | | MetricsQueryClient | Query Azure Monitor metrics |
This skill is applicable to execute the workflow or actions described in the overview.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +55 percentage points is the difference between those two pass rates over the 22 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.