Skip to content
Get Started for Free

Scheduled Query Rules

Azure Monitor Scheduled Query Rules (SQR) run KQL log queries on a defined schedule against data in one or more scopes (for example a Log Analytics workspace). 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 with a count-based condition on the Heartbeat table (in Azure, the rule would evaluate this KQL on the schedule you set and fire when the condition is met):

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": "PT5M",
"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": "PT5M"
}

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": "PT5M",
"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": "PT5M"
}

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": "PT5M",
"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": "PT5M"
}
]

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), consistent with Azure CLI az monitor scheduled-query.
  • Evaluation frequency and window size: Set how often the rule runs and the aggregation window (5m-style values in the CLI; the API represents these as ISO 8601 durations such as PT5M). See the REST API property reference for scheduledQueryRules.
  • Multiple scopes: Provide several scope resource IDs when your scenario requires it (the CLI documents constraints on 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 (unlike Azure, where a firing rule invokes the configured action groups).
  • 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?