Azure Monitor: metrics, Activity log, alerts
-
Phase 0: Before you start
-
Phase 1: The foundation
-
Phase 2: Day-to-day operations
-
Phase 3: Enterprise architecture
-
Phase 4: Troubleshooting step by step
-
Phase 5: Final project and career
Azure Monitor alerts tell you something is wrong before your users do. They watch metrics like CPU, events like “VM deallocated”, and logs, and send an email, SMS or webhook through an action group.
Azure Monitor collects a lot by default: platform metrics for every resource, and the Activity log for every change. Most teams under-use both, then discover an outage from a customer phone call.
In the lab you read metrics and the Activity log, build a CPU alert and make it fire, then fix the two alert gaps that cause the most missed incidents.
| Time | You need | Cost | By the end you can |
|---|---|---|---|
| About 50 minutes | web01, an email address you can read, the CLI | A few US cents: one metric alert rule for an hour; Activity log alerts and the first 1,000 emails a month have no charge | Read metrics and the Activity log, create action groups and alerts, and close common alert gaps |
What it is, in one line
Azure Monitor alerts watch metrics, events and logs, and notify you through action groups when a rule matches.
In Simple Words
The fire alarm and the visitor book
A school has a thermometer in every room: those are metrics, numbers measured every minute. It also has a visitor book at the gate that records who came in and what they did: that’s the Activity log.
An alert is the rule “if any room is hotter than 50 degrees for five minutes, ring the alarm”. The action group is the list of people the alarm calls.
But if a room’s thermometer is switched off, it never reads hot, and the alarm never rings. That gap is the first break in today’s lab.
Engineer's View
Signals, rules and action groups
- Platform metrics: collected automatically every minute for most resources and kept 93 days. For VMs: Percentage CPU, Network In/Out, Disk read/write, Available Memory Bytes and more, measured from the host.
- Activity log: every control-plane operation (create, update, delete, start, deallocate) with caller, time and status, kept 90 days. Export it to Log Analytics to keep it longer and query it.
- Alert types: metric alerts (threshold or dynamic), log search alerts (KQL, Lesson 34), Activity log alerts (operations, Service Health, Resource Health) and smart detection.
- Metric alert pieces: scope, condition (aggregation, metric, operator, threshold), window size, evaluation frequency, severity 0 to 4, and action groups. Alerts are stateful: they fire once, then resolve when the condition clears.
- Action groups: reusable lists of notifications (email, SMS, push, voice) and actions (webhook, Logic App, Function, ITSM, Automation runbook). Email has rate limits, around 100 messages an hour per address.
- Alert processing rules suppress notifications during planned maintenance or add action groups at scale.
How it works, step by step
What happens when web01’s CPU goes above 80%:
- The host records Percentage CPU for web01 every minute.
- Every minute, the rule al-web01-cpu checks the average over the last 5 minutes.
- When the average is above 80, the alert fires with severity 2.
- The action group ag-saat-email sends the email. The alert shows in Azure Monitor, Alerts.
- When the average drops below 80, the alert resolves and you get a “Resolved” email.
In Azure Monitor alerts, a metric rule can only judge data it receives. If the VM stops, the metric stops, and a threshold rule has nothing to compare.
Good alerting pairs “it’s unhealthy” rules (metrics, logs) with “it’s gone” rules (Activity log, Resource Health, availability).
Hands-on lab: Azure Monitor alerts for web01
Set your email address and load IDs:
$mail = 'you@example.com' # use your own address
$sub = az account show --query id -o tsv
$web01 = az vm show --resource-group rg-saat-vms --name web01 --query id -o tsv
az vm start --resource-group rg-saat-vms --name web011Create an action group
Run this:
az monitor action-group create --resource-group rg-saat-core --name ag-saat-email --short-name saatmail --action email admin $mail --tags course=saatvedha-azure lesson=31 keep=true -o none
$ag = az monitor action-group show --resource-group rg-saat-core --name ag-saat-email --query id -o tsv
az monitor action-group show --resource-group rg-saat-core --name ag-saat-email --query "emailReceivers[].{name:name, email:emailAddress, status:status}" -o tableYou should see something like this:
Name Email Status
------ --------------- --------
admin you@example.com EnabledYou’ll also get an email saying you were added to the action group. This group stays for the next lessons.
2Read web01’s metrics
Run this:
az monitor metrics list --resource $web01 --metric "Percentage CPU" --interval PT5M --aggregation Average --offset 1h --query "value[0].timeseries[0].data[-3:].{time:timeStamp, avg:average}" -o tableYou should see something like this:
Time Avg
------------------------- ------
2026-10-20T17:35:00+00:00 1.62
2026-10-20T17:40:00+00:00 0.88
2026-10-20T17:45:00+00:00 0.913Read the Activity log
See what changed on your VMs in the last two hours, and who did it:
az monitor activity-log list --resource-group rg-saat-vms --offset 2h --query "[?status.value=='Succeeded'].{time:eventTimestamp, operation:operationName.value, caller:caller}" -o tableYou should see something like this:
Time Operation Caller
-------------------------------- ---------------------------------------------- ----------------
2026-10-20T17:31:12.4400000Z Microsoft.Compute/virtualMachines/start/action you@example.comWrite down the exact operation name format; you’ll need it in Break It.
4Create a CPU alert and make it fire
Create the rule, then load both vCPUs for 8 minutes:
az monitor metrics alert create --resource-group rg-saat-vms --name al-web01-cpu --scopes $web01 --condition "avg Percentage CPU > 80" --window-size 5m --evaluation-frequency 1m --severity 2 --action $ag --description "web01 CPU above 80 percent" -o none
az vm run-command invoke --resource-group rg-saat-vms --name web01 --command-id RunShellScript --scripts 'for i in 1 2; do nohup timeout 480 yes >/dev/null 2>&1 & done; echo started' --query "value[0].message" -o tsvWait about 7 minutes, then check the metric:
az monitor metrics list --resource $web01 --metric "Percentage CPU" --interval PT1M --aggregation Average --offset 10m --query "value[0].timeseries[0].data[-2:].{time:timeStamp, avg:average}" -o tableYou should see something like this, and an email:
Time Avg
------------------------- ------
2026-10-20T17:58:00+00:00 99.71
2026-10-20T17:59:00+00:00 99.68The email’s subject starts with “Fired:Sev2 Azure Monitor Alert al-web01-cpu”. About 5 minutes after the load stops, a “Resolved” email follows.


✅ Checkpoint: ag-saat-email exists, you read metrics and the Activity log, and al-web01-cpu fired and then resolved.
Break It, Then Fix It
Both of these Azure Monitor alerts gaps are silent: no error, just no email when you need one.
1Break it: the server is down and nobody hears
Deallocate web01, as an accident or a rogue script might, and wait 10 minutes:
az vm deallocate --resource-group rg-saat-vms --name web01
az monitor metrics list --resource $web01 --metric "Percentage CPU" --interval PT1M --aggregation Average --offset 10m --query "value[0].timeseries[0].data[-2:].{time:timeStamp, avg:average}" -o tableYou should see something like this:
Time Avg
------------------------- -----
2026-10-20T18:20:00+00:00
2026-10-20T18:21:00+00:00No values, so the CPU rule has nothing to compare and stays quiet. Your only CPU alert can’t tell “idle” from “gone”.
Fix it: add an Activity log alert for deallocation, then test it:
az monitor activity-log alert create --resource-group rg-saat-core --name al-vm-deallocate --scope "/subscriptions/$sub/resourceGroups/rg-saat-vms" --condition "category=Administrative and operationName=Microsoft.Compute/virtualMachines/deallocate/action" --action-group $ag --description "web01 or win01 deallocated" -o none
az vm start --resource-group rg-saat-vms --name web01
az vm deallocate --resource-group rg-saat-vms --name web01Within a few minutes you get an email for al-vm-deallocate, naming the VM and who did it. Resource Health alerts and the VM availability metric cover crashes that aren’t user actions.
2Break it: the Activity log alert that never fires
Add an alert for restarts, copying the operation name from memory, then restart win01:
az monitor activity-log alert create --resource-group rg-saat-core --name al-vm-restart --scope "/subscriptions/$sub/resourceGroups/rg-saat-vms" --condition "category=Administrative and operationName=Microsoft.Compute/virtualMachines/restart" --action-group $ag --description "web01 or win01 restarted" -o none
az vm start --resource-group rg-saat-vms --name win01
az vm restart --resource-group rg-saat-vms --name win01Wait 10 minutes: no email. The rule was created without complaint, but the real operation name ends in /action, so the condition never matches.
Fix it: copy the name from a real event, then correct the rule:
az monitor activity-log list --resource-group rg-saat-vms --offset 1h --query "[?contains(operationName.value, 'restart')].operationName.value | [0]" -o tsv
az monitor activity-log alert delete --resource-group rg-saat-core --name al-vm-restart
az monitor activity-log alert create --resource-group rg-saat-core --name al-vm-restart --scope "/subscriptions/$sub/resourceGroups/rg-saat-vms" --condition "category=Administrative and operationName=Microsoft.Compute/virtualMachines/restart/action" --action-group $ag --description "web01 or win01 restarted" -o none
az vm restart --resource-group rg-saat-vms --name win01The first command prints this, and an email arrives after the second restart:
Microsoft.Compute/virtualMachines/restart/actionClean up: keep the action group, delete the rules, stop win01:
az monitor metrics alert delete --resource-group rg-saat-vms --name al-web01-cpu
az monitor activity-log alert delete --resource-group rg-saat-core --name al-vm-deallocate
az monitor activity-log alert delete --resource-group rg-saat-core --name al-vm-restart
az vm deallocate --resource-group rg-saat-vms --name win01
az monitor action-group list --resource-group rg-saat-core --query "[].name" -o tsvYou should see this:
ag-saat-email
✅ Checkpoint: You closed a “VM gone” gap and fixed a rule that could never match. Only ag-saat-email stays, and both VMs are deallocated.
This happened at work
The weekend nobody was paged
An e-commerce company had CPU, memory and disk alerts on every web server. On a Saturday night, a cost-saving script deallocated the whole web tier by mistake. The site was down for 9 hours, and not a single alert fired.
Every alert rule watched a metric from a running VM. With the VMs deallocated, the metrics simply stopped. The on-call engineer found out on Sunday morning from a customer tweet.
What they changed: Activity log alerts for deallocate, delete and power off on all production resource groups, Resource Health alerts for unplanned downtime, and an availability test that loads the home page every 5 minutes from three regions. The cost script now refuses to touch anything tagged env=prod.
Common mistakes and troubleshooting
| Mistake | What you see | What to do |
|---|---|---|
| Only metric alerts | Silence when the VM is stopped or deleted | Add Activity log, Resource Health and availability alerts. |
| Operation name typed from memory | Activity log alert never fires | Copy operationName from a real event. |
| Thresholds too low | Alerts all day, people stop reading them | Tune thresholds; use dynamic thresholds. |
| One person in the action group | Alert missed on leave or at night | Use a team mailbox, SMS or an on-call tool. |
| No alerts during maintenance planning | Noise or missed real issues | Use alert processing rules for planned windows. |
| Short window with spiky metrics | Fires and resolves repeatedly | Use a longer window or more failing periods. |
Interview questions
Click a question to open it. Each one is written the way an interviewer would ask it. Under it you will see why they ask it and one way you could answer, in your own words.
Fresher level
1. What is the difference between metrics and logs in Azure Monitor?
Why they ask this: The basic concept.
How you might answer: Metrics are numbers sampled at regular intervals, light and fast, good for thresholds and charts. Logs are detailed records stored in Log Analytics and queried with KQL for investigation and complex conditions.
2. What is an action group?
Why they ask this: A building block check.
How you might answer: A reusable list of notifications and actions, like email, SMS, webhooks or runbooks, that alert rules call when they fire.
3. What does the Activity log record?
Why they ask this: They want control-plane awareness.
How you might answer: Every management operation on Azure resources: who did what, when, on which resource, and whether it succeeded. It’s kept for 90 days unless exported.
2–5 years experience
4. A VM went down but no alert fired. Why, and what would you add?
Why they ask this: A real gap they want you to know.
How you might answer: Metric alerts need data, and a stopped VM sends none. I’d add Activity log alerts for deallocate and delete, Resource Health alerts for platform issues, and an availability or heartbeat check for the app.
5. What’s the difference between static and dynamic thresholds?
Why they ask this: They want tuning knowledge.
How you might answer: Static compares to a fixed number. Dynamic learns the metric’s normal pattern by time of day and week, and alerts on unusual deviation, which cuts noise for metrics that vary a lot.
6. How would you stop alerts during a planned maintenance window?
Why they ask this: They’re checking alert processing rules.
How you might answer: An alert processing rule scoped to the affected resources that suppresses notifications for the window. The alerts still fire and are recorded, so nothing is lost for the history.
Senior level
7. How would you design alerting for a production platform?
Why they ask this: They want structure, not a list of metrics.
How you might answer: Start from what users feel: availability tests and key app metrics. Then infrastructure health with metrics and Resource Health, change awareness with Activity log alerts, and log alerts for known failure patterns. Severities map to on-call routes, everything is deployed as code, and each alert has a runbook.
8. How do you manage alert rules across hundreds of resources?
Why they ask this: They want scale.
How you might answer: Multi-resource metric alerts scoped to a subscription or resource group, Azure Policy or the built-in recommended alerts to deploy rules, Bicep for consistency, and alert processing rules to route by tag.
9. How do you avoid alert fatigue?
Why they ask this: They want judgement.
How you might answer: Every alert must be actionable and owned. I’d review noisy alerts monthly, use dynamic thresholds and longer windows, group related alerts, and delete rules nobody acts on.
Quick quiz
Q1. How long are platform metrics kept by default?
- 7 days
- 30 days
- 93 days
- 1 year
Show answer
C — Platform metrics are kept for 93 days.
Q2. What does an action group do?
- Stores metrics
- Lists who and what to notify
- Creates VMs
- Runs KQL
Show answer
B — Action groups hold notifications and actions.
Q3. A VM is deallocated. Does its CPU alert fire?
- Yes, at 0%
- No, there is no data
- Only on weekends
- It deletes the VM
Show answer
B — No metric data means no threshold breach.
Q4. Which alert catches “VM deallocated”?
- Metric alert on CPU
- Activity log alert
- Smart detection
- Storage alert
Show answer
B — Deallocation is a control-plane operation in the Activity log.
Q5. An Activity log alert uses “…/restart” without /action. Result?
- Works
- Never matches
- Fires twice
- Error on create
Show answer
B — The condition must match the exact operation name.
Quick recap
You can now see what your resources are doing and set up Azure Monitor alerts that tell you when it matters.
Before you move on, open Azure Monitor, Alerts in the portal and look at the history of al-web01-cpu. Each fired and resolved event is listed with its time, severity and the value that crossed the line. In real teams, this history is the first thing reviewed after an incident: did the right alert fire, did it reach the right people, and how long did someone take to act on it?
- Metrics are automatic; the Activity log records every change.
- Metric alerts need data; add “it’s gone” alerts too.
- Action groups are reusable notification lists.
- Copy Activity log operation names from real events.
- Every alert should be actionable and owned.
Next lesson
Lesson 32: Azure Monitor Agent and data collection rules → You install the Azure Monitor Agent and send VM logs and performance data to Log Analytics.
Further reading: Azure Monitor alerts
Want to go deeper into Azure Monitor alerts? See Microsoft’s Overview of Azure Monitor alerts and Action groups. You can also see the full plan for this course on the Azure Cloud Administration course page.
