Creating Alerts in Azure Monitor
An alert that never fires is useless. An alert that fires constantly is noise that trains your team to ignore it. Getting alerting right is one of the most valuable investments you can make in your monitoring setup — and Azure Monitor gives you four distinct alert types, dynamic baselines, and flexible routing to help you build a signal worth paying attention to.
The four alert types
Azure Monitor supports four categories of alert rules, each suited to different data sources and detection scenarios:
| Alert Type | Data Source | Detection Latency | Best For |
|---|---|---|---|
| Metric alert | Azure Monitor metrics | 1–5 minutes | Real-time performance, CPU, memory, error rates |
| Log search alert | Log Analytics workspace (KQL) | 5–15 minutes | Complex error patterns, business events, log-derived conditions |
| Activity log alert | Azure Activity Log | ~5 minutes | Resource changes, role assignments, service health events |
| Smart detection | Application Insights telemetry | 24 hours (learning period) | Anomaly detection without manual thresholds |
Action groups: route alerts where they matter
Before creating an alert rule, create the action group it will use. An action group defines what happens when an alert fires. You can reuse one action group across many alert rules.
# Create an action group with email and webhook notification
az monitor action-group create \
--resource-group myRG \
--name "OnCallTeam" \
--short-name "oncall" \
--email-receiver name="TechLead" email-address="techlead@mycompany.com" \
--webhook-receiver name="PagerDuty" service-uri="https://events.pagerduty.com/integration/<key>/enqueue" use-common-alert-schema true
# Add an SMS receiver to an existing action group
az monitor action-group receiver sms add \
--resource-group myRG \
--action-group "OnCallTeam" \
--name "PhoneAlerts" \
--country-code "1" \
--phone-number "5551234567"Enable the “common alert schema” on all webhook receivers. It standardizes the alert payload format across all alert types, so your webhook handler only needs to parse one format regardless of whether the alert came from a metric rule or a log search rule.
Creating a metric alert: real scenario
Scenario: You want to alert when the HTTP 5xx error rate on your App Service exceeds 10 errors per minute for two consecutive evaluation periods. This reduces false positives from transient single-minute spikes.
# Create a metric alert for HTTP 5xx errors
az monitor metrics alert create \
--name "High5xxErrors" \
--resource-group myRG \
--scopes /subscriptions/<sub-id>/resourceGroups/myRG/providers/Microsoft.Web/sites/myapp \
--condition "total Http5xx > 10" \
--window-size 5m \
--evaluation-frequency 1m \
--severity 2 \
--action /subscriptions/<sub-id>/resourceGroups/myRG/providers/microsoft.insights/actionGroups/OnCallTeam \
--description "HTTP 5xx errors exceeded 10 per 5-minute window" \
--auto-mitigate true
# Add a second condition to the same alert (multi-condition)
# Alert only when BOTH conditions are true: high errors AND high response time
az monitor metrics alert create \
--name "HighErrorsWithSlowResponse" \
--resource-group myRG \
--scopes /subscriptions/<sub-id>/resourceGroups/myRG/providers/Microsoft.Web/sites/myapp \
--condition "total Http5xx > 5" \
--add-action-group /subscriptions/<sub-id>/resourceGroups/myRG/providers/microsoft.insights/actionGroups/OnCallTeam \
--severity 1 \
--window-size 5m \
--evaluation-frequency 1mCreating a log search alert
Log search alerts run a KQL query on a schedule and fire when the result meets a condition. This is powerful for situations where the signal lives in log data rather than metrics — for example, detecting a specific exception type, a failed background job, or a security event.
Scenario: Alert when more than 5 database connection timeout exceptions occur within any 10-minute window.
# Create a log search alert rule using a KQL query
az monitor scheduled-query create \
--name "DatabaseConnectionTimeouts" \
--resource-group myRG \
--scopes /subscriptions/<sub-id>/resourceGroups/myRG/providers/Microsoft.OperationalInsights/workspaces/myWorkspace \
--condition-query "AppExceptions | where ExceptionType == 'SqlException' and OuterMessage contains 'connection timeout' | summarize Count = count() by bin(TimeGenerated, 10m)" \
--condition-column "Count" \
--condition-operator "GreaterThan" \
--condition-threshold 5 \
--condition-time-aggregation "Total" \
--evaluation-frequency PT10M \
--window-duration PT10M \
--severity 2 \
--action-groups /subscriptions/<sub-id>/resourceGroups/myRG/providers/microsoft.insights/actionGroups/OnCallTeam \
--description "More than 5 SQL connection timeout exceptions in 10 minutes"Dynamic thresholds: alerting without guessing
Static thresholds require you to know what “normal” looks like. For a new application or a metric with weekly patterns (higher traffic on weekdays), picking the right static threshold is genuinely hard. Dynamic thresholds solve this by learning the historical pattern of a metric and alerting when the current value deviates significantly from the expected range.
Dynamic threshold alerts work well for:
- Request rates on applications with daily or weekly traffic patterns
- Response times that vary by time of day
- Queue depths that naturally fluctuate with workload
- Any metric where you have been collecting data for at least 7 days
They work poorly for metrics that are expected to be constant (a heartbeat endpoint that should always return 200) or metrics with very little historical data.
# Create a dynamic threshold metric alert
az monitor metrics alert create \
--name "AnomalousResponseTime" \
--resource-group myRG \
--scopes /subscriptions/<sub-id>/resourceGroups/myRG/providers/Microsoft.Web/sites/myapp \
--condition "avg HttpResponseTime dynamic(high, 2, 2, PT2H, 4)" \
--window-size 5m \
--evaluation-frequency 1m \
--severity 3 \
--action /subscriptions/<sub-id>/resourceGroups/myRG/providers/microsoft.insights/actionGroups/OnCallTeam \
--description "Response time deviating significantly from historical baseline"The dynamic condition syntax dynamic(high, 2, 2, PT2H, 4) means: alert on high deviations, with sensitivity 2 (medium), evaluate 2 failed periods, ignore data points in the last 2 hours for baseline calculation, and require at least 4 aggregation intervals for the baseline.
Activity log alerts: watch for control-plane changes
Activity log alerts are essential for security and governance. They notify you when someone or something modifies your Azure environment — not application behavior, but infrastructure changes.
# Alert when any resource is deleted in the subscription
az monitor activity-log alert create \
--name "ResourceDeletion" \
--resource-group myRG \
--condition category=Administrative and operationName=*/delete and status=Succeeded \
--action-group /subscriptions/<sub-id>/resourceGroups/myRG/providers/microsoft.insights/actionGroups/OnCallTeam \
--description "A resource was deleted in the subscription"
# Alert on Azure service health advisories
az monitor activity-log alert create \
--name "ServiceHealthAlert" \
--resource-group myRG \
--condition category=ServiceHealth \
--action-group /subscriptions/<sub-id>/resourceGroups/myRG/providers/microsoft.insights/actionGroups/OnCallTeam \
--description "Azure service health advisory or incident"Alert processing rules: maintenance and suppression
Alert processing rules (formerly “action rules”) let you modify how alerts are handled at scale — without changing individual alert rules. Use cases:
- Suppression during maintenance — Schedule a window when no notifications are sent (alerts still fire and record, but the on-call team is not paged).
- Add action groups globally — Route all Critical-severity alerts to the incident management system, regardless of which individual alert rule fired.
- Remove action groups — During a known infrastructure incident, suppress downstream alerts that are symptoms of the root cause.
Common mistakes
- Alert fatigue from too many severity-1 alerts. If everything is Critical, nothing is Critical. Reserve Severity 0 and 1 for alerts that require immediate human intervention. Use Severity 3 and 4 for informational alerts that might warrant investigation but not a 3 AM wake-up call.
- Not setting auto-resolve (auto-mitigate). By default, metric alerts resolve automatically when the condition is no longer met. Make sure this is enabled so your alerting system accurately reflects the current health state and does not show resolved incidents as still firing.
- Log search alerts with very short evaluation windows. Log ingestion has a delay of 2–5 minutes. If your log search alert evaluates every 1 minute over a 1-minute window, it will frequently find zero results simply because logs have not arrived yet, leading to flapping or missed detections.
- One action group per alert rule. Creating a new action group for every alert rule means your on-call contact list is scattered across dozens of action groups. Maintain 3–5 action groups by severity level, and share them across all alert rules.
Summary
- Azure Monitor offers four alert types: metric, log search, activity log, and smart detection — each suited to different signal sources.
- Action groups are reusable routing configurations; share them across many alert rules rather than creating one per rule.
- Dynamic thresholds learn the historical pattern of a metric and alert on deviations, eliminating the need to guess static thresholds for variable workloads.
- Activity log alerts are essential for detecting infrastructure changes and service health events.
- Alert processing rules handle maintenance suppression and global routing modifications without touching individual alert rules.
Frequently asked questions
What is an action group?
An action group is a reusable collection of notification recipients and automation actions. When an alert fires, it invokes the action group, which can send email, SMS, call a webhook, trigger an Azure Function, or open an ITSM ticket.
What is a dynamic threshold alert?
Dynamic threshold alerts use machine learning to automatically determine what "normal" looks like for a metric, then alert when behavior deviates significantly from that baseline. This avoids the need to manually set static thresholds.
How do I suppress alerts during maintenance windows?
Use alert processing rules (formerly called action rule suppression rules) to suppress notifications during scheduled maintenance. The alert still fires and records in the alert history, but notifications are held until the window ends.