Home / Azure

AzureTroubleshootingIntermediate

Azure Monitor Agent installed but no data in Log Analytics: missing Heartbeat, DCR associations, identity and network checks

The AMA extension shows Succeeded but the VM has no Heartbeat, events or counters in the workspace. Check the DCR association, managed identity, endpoints and the agent's local state in order.

Deepak Bhardwaj7 min read

Applies toAzure Monitor Agent (AzureMonitorWindowsAgent, AzureMonitorLinuxAgent) on Azure VMs and VM scale sets; Log Analytics workspaces; data collection rules

Symptom

A VM has the Azure Monitor Agent (AMA) extension and the portal shows Provisioning succeeded, but one or more of these is true:

  • No rows in Heartbeat for the computer, or heartbeats stopped at a point in time.
  • Heartbeat arrives but Event, Perf, Syslog or a custom table is empty.
  • Alerts based on that VM never fire, or the VM shows as "not monitored" in VM insights.

AMA does nothing on its own. It downloads its configuration from data collection rules (DCRs) associated with the machine, authenticates with a managed identity, and sends data to the workspace over HTTPS. A break in any of those three gives you a healthy-looking extension and an empty workspace.

Quick map: symptom to cause

Symptom Likely cause Fix
No Heartbeat ever, extension Succeeded No DCR associated, or no managed identity Associate a DCR; enable system-assigned identity or configure the user-assigned one
No Heartbeat, worked before Outbound 443 blocked, proxy change, private link scope change, identity removed Restore endpoint access; re-enable identity
Heartbeat OK, no events/counters DCR has no matching data source, wrong XPath, or flow points to another workspace Fix the DCR data sources and dataFlows
Data in the wrong workspace DCR destination is a different workspace Check destinations in each associated DCR
Duplicate rows Legacy MMA/OMS agent still running alongside AMA, or two DCRs collect the same data Remove the legacy agent; dedupe DCRs

Check 1: Is any data arriving at all?

Run this in the workspace you expect the data in:

Heartbeat
| where TimeGenerated > ago(24h)
| where Computer startswith "vm-app01"
| summarize LastHeartbeat = max(TimeGenerated) by Computer, Category, _ResourceId

Category should be Azure Monitor Agent. If you only see Direct Agent, the rows are coming from the legacy Log Analytics agent, not AMA.

To find every AMA machine that went quiet:

Heartbeat
| where TimeGenerated > ago(2d)
| where Category == "Azure Monitor Agent"
| summarize LastHeartbeat = max(TimeGenerated) by Computer
| where LastHeartbeat < ago(15m)
| order by LastHeartbeat asc

If Heartbeat is fine but a specific table is empty, skip to Check 5.

Check 2: Extension and agent process

az vm extension list -g rg-app --vm-name vm-app01 \
  --query "[?contains(typePropertiesType,'AzureMonitor')].{name:name, type:typePropertiesType, version:typeHandlerVersion, state:provisioningState}" -o table

Then confirm the agent is actually running inside the guest. You can do this without logging in by using Run Command:

# Windows: the core agent process is MonAgentCore
az vm run-command invoke -g rg-app -n vm-app01 --command-id RunPowerShellScript \
  --scripts "Get-Process MonAgent* | Select-Object Name, Id, StartTime"

# Linux
az vm run-command invoke -g rg-app -n vm-lnx01 --command-id RunShellScript \
  --scripts "systemctl status azuremonitoragent --no-pager | head -20"

If the process is running, give it about five minutes after any change before deciding it is broken.

Check 3: Is a DCR associated with this VM?

This is the most common cause. A DCR that exists but is not associated with the machine collects nothing.

VM_ID=$(az vm show -g rg-app -n vm-app01 --query id -o tsv)
az monitor data-collection rule association list --resource "$VM_ID" -o table

No rows means no configuration. Associate the DCR:

DCR_ID=$(az monitor data-collection rule show -g rg-mon -n dcr-windows-core --query id -o tsv)
az monitor data-collection rule association create \
  --name dcra-windows-core \
  --rule-id "$DCR_ID" \
  --resource "$VM_ID"

To check at scale, Azure Resource Graph lists associations as extension resources:

insightsresources
| where type == "microsoft.insights/datacollectionruleassociations"
| extend vmId = tolower(tostring(split(id, "/providers/Microsoft.Insights/")[0]))
| summarize dcrs = make_set(tostring(properties.dataCollectionRuleId)) by vmId

Compare that list against your VMs to find machines with the agent but no association.

Tip

If associations are deployed by Azure Policy, a VM created before the assignment is only fixed by a remediation task. Check the policy's compliance state before associating by hand, or the next VM will have the same gap.

Check 4: Managed identity

AMA uses the VM's system-assigned managed identity by default. If the identity was disabled, or the VM only has a user-assigned identity, the agent cannot get a token and sends nothing.

az vm identity show -g rg-app -n vm-app01

Enable system-assigned identity:

az vm identity assign -g rg-app -n vm-app01

If you standardise on a user-assigned identity, the extension must be told which one to use:

UAMI_ID=$(az identity show -g rg-mon -n id-ama --query id -o tsv)
az vm extension set -g rg-app --vm-name vm-app01 \
  --name AzureMonitorWindowsAgent --publisher Microsoft.Azure.Monitor \
  --enable-auto-upgrade true \
  --settings "{\"authentication\":{\"managedIdentity\":{\"identifier-name\":\"mi_res_id\",\"identifier-value\":\"$UAMI_ID\"}}}"

Use AzureMonitorLinuxAgent for Linux. The agent also needs to reach the Instance Metadata Service (169.254.169.254) to get its token; a host firewall or a guest proxy that captures that address breaks authentication.

Check 5: Network path to Azure Monitor

AMA needs outbound HTTPS (TCP 443) to:

Endpoint Purpose
global.handler.control.monitor.azure.com Configuration service (DCR download)
<region>.handler.control.monitor.azure.com Regional configuration service
<workspace-id>.ods.opinsights.azure.com Log ingestion to the workspace

Test from the guest:

Test-NetConnection global.handler.control.monitor.azure.com -Port 443
Test-NetConnection <workspace-id>.ods.opinsights.azure.com -Port 443
curl -sS -o /dev/null -w "%{http_code}\n" https://global.handler.control.monitor.azure.com

Any HTTP status code means the TCP and TLS path works. A timeout or TLS error points at the NSG, Azure Firewall, route table or proxy. The Azure Firewall service tag AzureMonitor covers these endpoints.

If you use an Azure Monitor Private Link Scope (AMPLS), the VM must resolve these names to private IPs and the DCR must reference a data collection endpoint (DCE) that is in the scope. A workspace set to deny public ingestion will silently drop data from machines that still resolve the public endpoint.

Warning

Changing an AMPLS access mode or the private DNS zones it uses affects every machine and Application Insights resource using that scope, not just the VM you are fixing. Test with one VNet first.

Check 6: The DCR content

When Heartbeat works but a table is empty, the configuration downloaded but does not ask for that data.

az monitor data-collection rule show -g rg-mon -n dcr-windows-core \
  --query "{sources:dataSources, flows:dataFlows, dest:destinations}" -o json

Look for:

  • A data source that matches the data (windowsEventLogs, performanceCounters, syslog, logFiles).
  • XPath queries that are valid. A typo in a channel name returns nothing, not an error.
  • A dataFlows entry whose streams include that source's stream and whose destinations point at the right workspace.
  • A transformation (transformKql) that filters out everything.

Check 7: The agent's local state

If the DCR association exists but the agent has no local copy, it could not reach the configuration service. Paths vary by agent version; check your build:

OS Where to look
Windows C:\WindowsAzure\Resources\AMADataStore.<computername>\mcs\ (downloaded configuration), C:\WindowsAzure\Logs\Plugins\Microsoft.Azure.Monitor.AzureMonitorWindowsAgent\ (extension logs)
Linux /var/opt/microsoft/azuremonitoragent/log/mdsd.err and mdsd.info
az vm run-command invoke -g rg-app -n vm-lnx01 --command-id RunShellScript \
  --scripts "tail -50 /var/opt/microsoft/azuremonitoragent/log/mdsd.err"

Both agents ship a troubleshooter script with the extension that collects these logs into one bundle. Its location depends on the extension version; see Microsoft's AMA troubleshooting guide for your OS before opening a support case.

Prevent it next time

  • Deploy AMA, the managed identity and the DCR association together with Azure Policy, and run remediation tasks after every assignment change.
  • Alert on missing heartbeats using the second query in Check 1, scoped to Category == "Azure Monitor Agent".
  • Add AzureMonitor endpoints to your egress allow list as part of the subnet baseline, not per VM.
  • Remove the legacy Log Analytics agent once AMA is verified, so Heartbeat shows a single source per machine.
  • Review DCR changes like code: a broken XPath or transformation removes data without raising an error.