EthicsComputerCourses
Join training +91 90532 10052

Azure Monitor, Log Analytics & Application Insights

Microsoft Azure · Lesson 20 of 29 Intermediate 8 min read Updated

By the end of this lesson you will be able to explain metrics, logs and traces, create a Log Analytics workspace, send resource logs to it, add Application Insights to a Python app, write simple KQL queries, and create an alert that emails you before your users complain.

Why monitoring matters

Imagine Meera's online coaching app slows down every evening at 8 pm. Without monitoring she hears about it from angry students on WhatsApp. With monitoring, she sees CPU rise at 7:55, gets an email at 8:01, and can find the slow database query in minutes.

Azure Monitor is the umbrella name for Azure's monitoring features. It collects three kinds of data:

DataWhat it isExample
MetricsNumbers sampled over timeCPU percentage, HTTP 5xx count, database DTU usage
LogsRecords with many fields, stored in a Log Analytics workspaceEvery request, every Key Vault secret read, every VM syslog line
TracesThe path of one request through several servicesWeb app called API, API called SQL, SQL took 900 ms

Think of a hospital patient. Metrics are the heart-rate monitor beeping every second. Logs are the nurse's detailed notes. Traces are the record of one patient's journey from reception to X-ray to pharmacy.

The building blocks

  • Platform metrics are collected automatically for most resources; you can chart them right away.
  • The activity log records management operations (who created or deleted what), as you saw in the portal lesson.
  • A Log Analytics workspace stores logs and lets you query them with KQL (Kusto Query Language).
  • Diagnostic settings send a resource's detailed resource logs and metrics to a workspace, a storage account or an event hub. Resource logs are not collected until you create a diagnostic setting.
  • Application Insights monitors application code: requests, dependencies, exceptions, traces and page views. Modern Application Insights resources store their data in a Log Analytics workspace.
  • Alerts watch metrics or log queries and trigger action groups, which send email, SMS or push notifications, or call a webhook or function.
  • For VMs, the Azure Monitor Agent with data collection rules collects OS logs and performance counters. It replaced the older Log Analytics agent, which you may still see in old guides.

Step by step: workspace and diagnostic settings

Step 1: create a workspace.

Terminal
az group create --name rg-monitor-demo --location centralindia --output none
az monitor log-analytics workspace create --resource-group rg-monitor-demo \
  --workspace-name log-coaching-cin --location centralindia --output none
lawId=$(az monitor log-analytics workspace show --resource-group rg-monitor-demo \
  --workspace-name log-coaching-cin --query id --output tsv)

Step 2: send a Key Vault's audit logs to the workspace, so you can see every secret read. categoryGroup audit selects the audit categories without listing them one by one.

Terminal
kvId=$(az keyvault show --name kv-tiffin-cin-01 --query id --output tsv)
az monitor diagnostic-settings create --name to-law --resource "$kvId" --workspace "$lawId" \
  --logs '[{"categoryGroup":"audit","enabled":true}]' --output none

Application Insights for your code

Step 1: create a workspace-based Application Insights resource. These commands come from the application-insights CLI extension.

Terminal
az monitor app-insights component create --app appi-coaching-cin --location centralindia \
  --resource-group rg-monitor-demo --workspace "$lawId" \
  --query connectionString --output tsv

The command prints a connection string that tells the SDK where to send data. It is not a password, but treat it as configuration, not something to post publicly. Older guides use an instrumentation key alone; Microsoft ended support for key-only ingestion, so always use the connection string.

Step 2: add the Azure Monitor OpenTelemetry Distro to a Python web app. OpenTelemetry is an open standard for collecting telemetry, so your instrumentation is not tied to one vendor.

Python
# app.py
from azure.monitor.opentelemetry import configure_azure_monitor
from flask import Flask

configure_azure_monitor()  # reads APPLICATIONINSIGHTS_CONNECTION_STRING

app = Flask(__name__)

@app.get("/")
def home():
    return "Coaching timetable"

Set the app setting APPLICATIONINSIGHTS_CONNECTION_STRING on the web app to the value from Step 1. Calling configure_azure_monitor() before creating the Flask app lets the distro instrument Flask automatically. Requests, failures and response times now flow into Application Insights. Open Application Map, Failures and Performance in the portal to explore them.

Querying logs with KQL

KQL reads like a pipeline: start from a table, then pass rows through steps separated by |. In a workspace, Application Insights requests are in the AppRequests table.

Text
AppRequests
| where TimeGenerated > ago(1h)
| summarize Requests = count(), AvgMs = avg(DurationMs) by ResultCode
| order by ResultCode asc

This counts the last hour's requests by HTTP result code with the average duration. A query for the slowest pages:

Text
AppRequests
| where TimeGenerated > ago(1d)
| top 5 by DurationMs desc
| project TimeGenerated, Name, DurationMs, ResultCode

You can run KQL in the portal's Logs page, or from code with the Azure Monitor Query library:

Python
from datetime import timedelta
from azure.identity import DefaultAzureCredential
from azure.monitor.query import LogsQueryClient

client = LogsQueryClient(DefaultAzureCredential())
query = "AppRequests | summarize Requests = count() by ResultCode | order by ResultCode asc"
result = client.query_workspace("<workspace-id>", query, timespan=timedelta(hours=1))

for row in result.tables[0].rows:
    print(row["ResultCode"], row["Requests"])
Output
200 1520
404 12
500 3

The numbers are illustrative; yours depend on your traffic. <workspace-id> is the workspace's customer ID (a GUID), not its resource ID. You need at least the Log Analytics Reader role.

Step by step: alert on server errors

Step 1: create an action group that emails the on-call person.

Terminal
az monitor action-group create --resource-group rg-monitor-demo --name ag-oncall \
  --short-name oncall --action email meera meera@example.com --output none

Step 2: alert when the web app returns more than 5 server errors in 5 minutes.

Terminal
appId=$(az webapp show --resource-group rg-web-demo --name app-tiffin-pune-01 --query id --output tsv)
az monitor metrics alert create --resource-group rg-monitor-demo --name alert-http5xx \
  --scopes "$appId" --condition "total Http5xx > 5" \
  --window-size 5m --evaluation-frequency 1m --action ag-oncall --severity 2 --output none

You should receive an email when the condition fires, and another when it resolves.

Costs of monitoring

Log Analytics charges mainly for data ingested and retained. Sending every debug log from every service can cost more than the app itself. Collect what you will query, set sensible retention, and use sampling in Application Insights for very busy apps. Check the Azure Monitor pricing page for the current model.

Clean up: az group delete --name rg-monitor-demo --yes --no-wait.

Common mistakes

  • Expecting resource logs without a diagnostic setting. Only metrics and the activity log are automatic.
  • Using classic, non-workspace Application Insights in new guides. Create workspace-based resources.
  • Logging secrets or personal data. Logs are read by many people and kept for a long time. Mask phone numbers and Aadhaar-like IDs.
  • Alerts with no owner. Every alert should go to a person or team who knows what to do.

Key points

  • Azure Monitor collects metrics, logs and traces; Log Analytics workspaces store logs queried with KQL.
  • Diagnostic settings are needed to send resource logs to a workspace.
  • Application Insights, set up with the Azure Monitor OpenTelemetry Distro and a connection string, monitors your code.
  • Alerts watch metrics or queries and notify people through action groups.
  • Control monitoring costs by collecting only useful data and setting retention.

Exercise

Write a KQL query that shows, for the last 24 hours, the five request names (Name) with the most failed requests (where Success == false), along with the failure count. Then write the CLI command for an alert called alert-cpu that fires when the average CpuPercentage of an App Service plan with ID stored in $planId is above 80 over 15 minutes, using the action group ag-oncall.

Show solution
Text
AppRequests
| where TimeGenerated > ago(1d) and Success == false
| summarize Failures = count() by Name
| top 5 by Failures desc
Terminal
az monitor metrics alert create --resource-group rg-monitor-demo --name alert-cpu \
  --scopes "$planId" --condition "avg CpuPercentage > 80" \
  --window-size 15m --evaluation-frequency 5m --action ag-oncall --output none

The query filters failures first, then groups and ranks them. The alert uses the plan's CpuPercentage metric averaged over a 15-minute window.

Quick Quiz

1. Where do you write KQL queries over collected logs?

2. A Key Vault's secret-read logs do not appear in your workspace. What is the likely cause?

3. What should a new app use to send data to Application Insights?

Learn Microsoft Azure with a mentor

Free lessons get you started. Our Cloud & DevOps training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call