Skip to content
Get Started for Free

Scheduled Query Rules

Azure Monitor Scheduled Query Rules (SQR) evaluate KQL log queries stored in a Log Analytics Workspace on a defined schedule. When query results meet a configured condition, an alert is fired and routed through an Action Group. Scheduled Query Rules are commonly used to detect patterns in application logs, audit events, and custom metrics that cannot be captured by standard metric alerts. For more information, see Log alerts in Azure Monitor.

LocalStack for Azure provides a local environment for building and testing applications that make use of Azure Monitor Scheduled Query Rules. The supported APIs are available on our API Coverage section, which provides information on the extent of Scheduled Query Rules’ integration with LocalStack.

This guide walks you through creating a Scheduled Query Rule that targets a Log Analytics workspace.

Launch LocalStack using your preferred method. For more information, see Introduction to LocalStack for Azure. Once the container is running, enable Azure CLI interception by running:

Terminal window
azlocal start-interception

This command points the az CLI away from the public Azure management REST API and toward the LocalStack for Azure emulator API. To revert this configuration, run:

Terminal window
azlocal stop-interception

This reconfigures the az CLI to send commands to the official Azure management REST API.

Create a resource group to hold all resources created in this guide:

Terminal window
az group create --name rg-sqr-demo --location westeurope
Output
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-sqr-demo",
"location": "westeurope",
"name": "rg-sqr-demo",
"properties": { "provisioningState": "Succeeded" },
"type": "Microsoft.Resources/resourceGroups"
}

Create a Log Analytics workspace to use as the scheduled query target:

Terminal window
az monitor log-analytics workspace create \
--name my-workspace \
--resource-group rg-sqr-demo \
--location westeurope
Output
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-sqr-demo/providers/Microsoft.OperationalInsights/workspaces/my-workspace",
"location": "westeurope",
"name": "my-workspace",
"provisioningState": "Succeeded",
"resourceGroup": "rg-sqr-demo",
"sku": { "name": "PerGB2018" },
"type": "Microsoft.OperationalInsights/workspaces"
}

Create an action group to serve as the notification target when the alert fires:

Terminal window
az monitor action-group create \
--name my-ag \
--resource-group rg-sqr-demo \
--short-name myag \
--action email admin admin@example.com
Output
{
"emailReceivers": [
{ "emailAddress": "admin@example.com", "name": "admin", "useCommonAlertSchema": false }
],
"enabled": true,
"groupShortName": "myag",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-sqr-demo/providers/microsoft.insights/actionGroups/my-ag",
"location": "Global",
"name": "my-ag",
"resourceGroup": "rg-sqr-demo",
"type": "Microsoft.Insights/ActionGroups"
}

Retrieve the workspace and action group resource IDs, then create a scheduled query rule that fires when the error count exceeds the threshold:

Terminal window
WORKSPACE_ID=$(az monitor log-analytics workspace show \
--workspace-name my-workspace \
--resource-group rg-sqr-demo \
--query id \
--output tsv)
AG_ID=$(az monitor action-group show \
--name my-ag \
--resource-group rg-sqr-demo \
--query id \
--output tsv)
az monitor scheduled-query create \
--name my-sqr \
--resource-group rg-sqr-demo \
--scopes "$WORKSPACE_ID" \
--condition "count 'Placeholder_1' > 5" \
--condition-query "Placeholder_1=Heartbeat | where TimeGenerated > ago(5m)" \
--description "Alert on Heartbeat count" \
--action-groups "$AG_ID" \
--evaluation-frequency 5m \
--window-size 5m \
--severity 2
Output
{
"actions": {
"actionGroups": [
"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-sqr-demo/providers/microsoft.insights/actionGroups/my-ag"
]
},
"criteria": {
"allOf": [
{
"operator": "GreaterThan",
"query": "Heartbeat | where TimeGenerated > ago(5m)",
"threshold": 5.0,
"timeAggregation": "Count"
}
]
},
"description": "Alert on Heartbeat count",
"enabled": true,
"evaluationFrequency": "0:05:00",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-sqr-demo/providers/microsoft.insights/scheduledqueryrules/my-sqr",
"location": "westeurope",
"name": "my-sqr",
"resourceGroup": "rg-sqr-demo",
"scopes": [
"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-sqr-demo/providers/Microsoft.OperationalInsights/workspaces/my-workspace"
],
"severity": 2,
"type": "Microsoft.Insights/scheduledQueryRules",
"windowSize": "0:05:00"
}

Retrieve the details of the scheduled query rule and list all rules in the resource group:

Terminal window
az monitor scheduled-query show \
--name my-sqr \
--resource-group rg-sqr-demo
Output
{
"actions": {
"actionGroups": [
"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-sqr-demo/providers/microsoft.insights/actionGroups/my-ag"
]
},
"criteria": {
"allOf": [
{
"operator": "GreaterThan",
"query": "Heartbeat | where TimeGenerated > ago(5m)",
"threshold": 5.0,
"timeAggregation": "Count"
}
]
},
"description": "Alert on Heartbeat count",
"enabled": true,
"evaluationFrequency": "0:05:00",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-sqr-demo/providers/microsoft.insights/scheduledqueryrules/my-sqr",
"location": "westeurope",
"name": "my-sqr",
"resourceGroup": "rg-sqr-demo",
"severity": 2,
"type": "Microsoft.Insights/scheduledQueryRules",
"windowSize": "0:05:00"
}

Then list all scheduled query rules in the resource group:

Terminal window
az monitor scheduled-query list \
--resource-group rg-sqr-demo
Output
[
{
"actions": {
"actionGroups": [
"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-sqr-demo/providers/microsoft.insights/actionGroups/my-ag"
]
},
"criteria": {
"allOf": [
{
"operator": "GreaterThan",
"query": "Heartbeat | where TimeGenerated > ago(5m)",
"threshold": 5.0,
"timeAggregation": "Count"
}
]
},
"enabled": true,
"evaluationFrequency": "0:05:00",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-sqr-demo/providers/microsoft.insights/scheduledqueryrules/my-sqr",
"location": "westeurope",
"name": "my-sqr",
"resourceGroup": "rg-sqr-demo",
"severity": 2,
"type": "Microsoft.Insights/scheduledQueryRules",
"windowSize": "0:05:00"
}
]

Delete the resource and confirm it no longer appears in the list:

Terminal window
az monitor scheduled-query delete \
--name my-sqr \
--resource-group rg-sqr-demo \
--yes

Then list all scheduled query rules to confirm the resource group is now empty:

Terminal window
az monitor scheduled-query list --resource-group rg-sqr-demo
Output
[]
  • Scheduled Query Rule lifecycle: Create, read, list, update, and delete SQR resources.
  • KQL query storage: Store the KQL query definition within the rule (not executed).
  • Condition configuration: Define threshold, operator, time aggregation, and evaluation period.
  • Action group references: Associate one or more action groups with a query rule.
  • Severity levels: Set alert severity from 0 (Critical) to 4 (Verbose).
  • Evaluation frequency: Configure how often the rule is evaluated via ISO 8601 duration.
  • Cross-resource queries: Define rules targeting multiple scopes.
  • No KQL execution: The query defined in the rule is never run against Log Analytics data.
  • No alert firing: Alert thresholds are never evaluated and no alerts are triggered.
  • No notifications dispatched: Action group notifications are not sent even when the rule fires.
  • No alert history: Alert instance history and state transitions are not recorded.

Explore end-to-end examples in the LocalStack for Azure Samples repository.

OperationImplemented
Page 1 of 0
Was this page helpful?