Lý Thuyết Cốt Lõi
1. Log Analytics Workspace — Kho Dữ Liệu Trung Tâm
Log Analytics Workspace (LAW) là nền tảng lưu trữ và truy vấn log dữ liệu của Azure Monitor. Mọi resource logs, performance data, security events đều được ingest vào workspace và truy vấn bằng KQL.
- • Lưu resource logs từ Diagnostic Settings
- • Thu thập performance counters từ VM (qua AMA)
- • Centralize security events, syslog, Windows Event Log
- • Làm data source cho Log Search Alerts
- • Tạo Workbooks và dashboards phân tích nâng cao
- • Lưu Activity Log lâu hơn 90 ngày
- • SKU: PerGB2018 (pay-per-use, khuyến nghị) hoặc Capacity Reservations
- • Retention: 30–730 ngày (mặc định 30 ngày). Phí extra từ ngày 31+
- • Daily Cap: giới hạn GB/ngày để kiểm soát chi phí
- • Region: chọn cùng region với resources để giảm egress cost
- • Access Control: Workspace-context hoặc Resource-context
2. KQL — Kusto Query Language Cơ Bản
KQL (Kusto Query Language) là ngôn ngữ truy vấn read-only dành cho dữ liệu log/time-series của Azure. Cú pháp theo pipeline: Table | operator1 | operator2 | ...
- •
Heartbeat— agent check-in từ VMs - •
Perf— performance counters (CPU, Disk, Memory) - •
Event— Windows Event Log - •
Syslog— Linux syslog - •
SecurityEvent— Windows Security Log - •
AzureActivity— Activity Log (đã stream vào) - •
AzureDiagnostics— Resource diagnostic logs - •
AppRequests— Application Insights requests
- •
where— lọc rows theo điều kiện - •
project— chọn / đổi tên columns - •
summarize— tổng hợp / aggregate - •
order by / sort by— sắp xếp kết quả - •
top N by— lấy N rows cao nhất - •
extend— thêm computed column - •
join— join hai bảng theo key - •
render— hiển thị dạng chart
3. Cấu Trúc KQL — where / project / summarize / render
// Lọc Heartbeat của VM cụ thể trong 1 giờ qua
Heartbeat
| where TimeGenerated > ago(1h)
| where Computer == "vm-monitor-lab30"
// Lọc nhiều điều kiện — performance counter CPU
Perf
| where TimeGenerated > ago(24h)
| where ObjectName == "Processor"
| where CounterName == "% Processor Time"
| where CounterValue > 80
// Lọc text chứa chuỗi (contains không phân biệt hoa thường)
Event
| where TimeGenerated > ago(7d)
| where EventLog == "Application"
| where RenderedDescription contains "error"
| where EventLevelName in ("Error", "Critical")
// Chọn chỉ các cột cần thiết
Heartbeat
| where TimeGenerated > ago(1h)
| project TimeGenerated, Computer, OSType, Version
// Đổi tên cột khi project
Perf
| where TimeGenerated > ago(1h)
| where CounterName == "% Processor Time"
| project Thoi_gian = TimeGenerated,
May_chu = Computer,
CPU_Percent = CounterValue
// project-away: loại bỏ cột không cần
AzureActivity
| where TimeGenerated > ago(7d)
| project-away TenantId, SubscriptionId, _ResourceId
// Đếm heartbeat theo từng VM — xem VM nào đang online
Heartbeat
| where TimeGenerated > ago(1h)
| summarize HeartbeatCount = count() by Computer
| order by HeartbeatCount desc
// CPU trung bình theo VM và theo giờ
Perf
| where TimeGenerated > ago(24h)
| where CounterName == "% Processor Time"
| summarize AvgCPU = avg(CounterValue),
MaxCPU = max(CounterValue)
by Computer, bin(TimeGenerated, 1h)
| order by TimeGenerated desc
// Tổng số Azure activities theo operation name
AzureActivity
| where TimeGenerated > ago(7d)
| summarize EventCount = count() by OperationNameValue, ActivityStatusValue
| order by EventCount desc
| top 20 by EventCount
// Vẽ line chart CPU theo thời gian
Perf
| where TimeGenerated > ago(24h)
| where CounterName == "% Processor Time"
| where Computer == "vm-monitor-lab30"
| summarize AvgCPU = avg(CounterValue) by bin(TimeGenerated, 5m)
| render timechart
// Vẽ pie chart phân bổ operations trong Activity Log
AzureActivity
| where TimeGenerated > ago(7d)
| summarize Count = count() by ActivityStatusValue
| render piechart
// Vẽ bar chart — top VMs theo CPU cao nhất
Perf
| where TimeGenerated > ago(1h)
| where CounterName == "% Processor Time"
| summarize MaxCPU = max(CounterValue) by Computer
| top 10 by MaxCPU
| render barchart
4. Queries Nâng Cao — Tình Huống Thực Tế
let Threshold = 5m;
Heartbeat
| where TimeGenerated > ago(Threshold * 2)
| summarize LastSeen = max(TimeGenerated) by Computer
| where LastSeen < ago(Threshold)
| project Computer, LastSeen,
MinutesSinceLastBeat = datetime_diff('minute', now(), LastSeen)
AzureActivity
| where TimeGenerated > ago(7d)
| where ActivityStatusValue == "Success"
| extend OperationShort = tostring(split(OperationNameValue, "/")[-1])
| summarize Count = count() by OperationShort, Caller
| order by Count desc
| top 10 by Count
Perf
| where TimeGenerated > ago(1h)
| where ObjectName == "LogicalDisk"
| where CounterName == "% Free Space"
| where InstanceName !in ("_Total", "HarddiskVolume1")
| summarize FreeSpacePercent = avg(CounterValue) by Computer, InstanceName
| where FreeSpacePercent < 15
| extend UsedPercent = round(100 - FreeSpacePercent, 1)
| project Computer, Drive = InstanceName, UsedPercent
| order by UsedPercent desc
Bài Tập Thực Hành (Lab)
Tạo Resource Group, Log Analytics Workspace và VM
# Tạo Resource Group
az group create \
--name rg-az104-m30 \
--location southeastasia \
--tags Course=AZ-104 Module=30 Environment=Lab
# Tạo Log Analytics Workspace với retention 60 ngày
az monitor log-analytics workspace create \
--resource-group rg-az104-m30 \
--workspace-name law-az104-m30 \
--location southeastasia \
--sku PerGB2018 \
--retention-time 60
LAW_ID=$(az monitor log-analytics workspace show \
--resource-group rg-az104-m30 \
--workspace-name law-az104-m30 \
--query id -o tsv)
LAW_CUSTOMER_ID=$(az monitor log-analytics workspace show \
--resource-group rg-az104-m30 \
--workspace-name law-az104-m30 \
--query customerId -o tsv)
echo "Workspace ID (customerId): $LAW_CUSTOMER_ID"
echo "Workspace Resource ID: $LAW_ID"
# Tạo VM Windows Server 2022 để thu thập Windows Event Log
az vm create \
--resource-group rg-az104-m30 \
--name vm-law-lab30 \
--image Win2022Datacenter \
--size Standard_B2s \
--admin-username azureuser \
--admin-password "P@ssw0rd2026AZ104!" \
--location southeastasia \
--tags Course=AZ-104 Module=30
Cài Azure Monitor Agent (AMA) và tạo Data Collection Rule
VM_ID=$(az vm show \
--resource-group rg-az104-m30 \
--name vm-law-lab30 \
--query id -o tsv)
LAW_ID=$(az monitor log-analytics workspace show \
--resource-group rg-az104-m30 \
--workspace-name law-az104-m30 \
--query id -o tsv)
# Cài Azure Monitor Agent extension trên VM Windows
az vm extension set \
--resource-group rg-az104-m30 \
--vm-name vm-law-lab30 \
--name AzureMonitorWindowsAgent \
--publisher Microsoft.Azure.Monitor \
--version 1.22
# Tạo Data Collection Rule — thu thập Windows Event Log và Perf counters
az monitor data-collection rule create \
--resource-group rg-az104-m30 \
--name dcr-az104-m30-windows \
--location southeastasia \
--data-flows '[{"streams":["Microsoft-Event","Microsoft-Perf"],"destinations":["law-az104-m30-dest"]}]' \
--destinations '{"logAnalytics":[{"workspaceResourceId":"'"$LAW_ID"'","name":"law-az104-m30-dest"}]}' \
--data-sources '{
"windowsEventLogs":[{
"streams":["Microsoft-Event"],
"xPathQueries":["System!*[System[(Level=1 or Level=2 or Level=3)]]","Application!*[System[(Level=1 or Level=2)]]"],
"name":"windowsEventLogsDataSource"
}],
"performanceCounters":[{
"streams":["Microsoft-Perf"],
"samplingFrequencyInSeconds":60,
"counterSpecifiers":["\\Processor(_Total)\\% Processor Time","\\Memory\\Available MBytes","\\LogicalDisk(_Total)\\% Free Space"],
"name":"perfCountersDataSource"
}]
}'
DCR_ID=$(az monitor data-collection rule show \
--resource-group rg-az104-m30 \
--name dcr-az104-m30-windows \
--query id -o tsv)
# Associate DCR với VM
az monitor data-collection rule association create \
--resource "$VM_ID" \
--association-name "dcra-vm-law-lab30" \
--rule-id "$DCR_ID"
echo "AMA cài xong. Dữ liệu sẽ xuất hiện trong Log Analytics sau 10-15 phút."
Chạy KQL queries trực tiếp qua Azure CLI và Portal
LAW_CUSTOMER_ID=$(az monitor log-analytics workspace show \
--resource-group rg-az104-m30 \
--workspace-name law-az104-m30 \
--query customerId -o tsv)
# Query 1: Xem Heartbeat của VM
az monitor log-analytics query \
--workspace "$LAW_CUSTOMER_ID" \
--analytics-query "Heartbeat | where TimeGenerated > ago(1h) | project TimeGenerated, Computer, OSType | order by TimeGenerated desc | take 10" \
--output table
# Query 2: CPU cao nhất theo VM
az monitor log-analytics query \
--workspace "$LAW_CUSTOMER_ID" \
--analytics-query "Perf | where TimeGenerated > ago(1h) | where CounterName == '% Processor Time' | summarize MaxCPU=max(CounterValue), AvgCPU=round(avg(CounterValue),1) by Computer | order by MaxCPU desc" \
--output table
# Query 3: Windows Event Errors
az monitor log-analytics query \
--workspace "$LAW_CUSTOMER_ID" \
--analytics-query "Event | where TimeGenerated > ago(24h) | where EventLevelName in ('Error','Critical') | summarize Count=count() by EventLog, EventID, RenderedDescription | order by Count desc | take 10" \
--output table
# Query 4: Disk free space thấp
az monitor log-analytics query \
--workspace "$LAW_CUSTOMER_ID" \
--analytics-query "Perf | where TimeGenerated > ago(1h) | where CounterName == '% Free Space' | where ObjectName == 'LogicalDisk' | where InstanceName != '_Total' | summarize FreePercent=avg(CounterValue) by Computer, InstanceName | where FreePercent < 20 | order by FreePercent asc" \
--output table
Tạo Workbook từ template để visualize VM health
LAW_ID=$(az monitor log-analytics workspace show \
--resource-group rg-az104-m30 \
--workspace-name law-az104-m30 \
--query id -o tsv)
# Tạo Workbook đơn giản hiển thị CPU và Memory
# Workbook dùng Azure Resource Manager template
cat > /tmp/workbook-template.json << 'EOF'
{
"version": "Notebook/1.0",
"items": [
{
"type": 1,
"content": {
"json": "## VM Performance Dashboard\n\nWorkbook này hiển thị CPU và Memory của các VMs kết nối với Log Analytics Workspace."
}
},
{
"type": 3,
"content": {
"version": "KqlItem/1.0",
"query": "Perf\n| where TimeGenerated > ago(1h)\n| where CounterName == '% Processor Time'\n| summarize AvgCPU = avg(CounterValue) by bin(TimeGenerated, 5m), Computer\n| render timechart",
"size": 0,
"title": "CPU Usage (1 giờ qua)",
"queryType": 0,
"resourceType": "microsoft.operationalinsights/workspaces"
}
},
{
"type": 3,
"content": {
"version": "KqlItem/1.0",
"query": "Perf\n| where TimeGenerated > ago(1h)\n| where CounterName == 'Available MBytes'\n| summarize AvgMemMB = avg(CounterValue) by bin(TimeGenerated, 5m), Computer\n| render timechart",
"size": 0,
"title": "Available Memory (MB)",
"queryType": 0,
"resourceType": "microsoft.operationalinsights/workspaces"
}
}
]
}
EOF
# Deploy Workbook via ARM
WORKBOOK_GUID=$(cat /proc/sys/kernel/random/uuid 2>/dev/null || python3 -c "import uuid; print(uuid.uuid4())")
az resource create \
--resource-group rg-az104-m30 \
--resource-type "microsoft.insights/workbooks" \
--name "$WORKBOOK_GUID" \
--location southeastasia \
--properties "{
\"displayName\": \"AZ104-M30-VM-Performance\",
\"serializedData\": $(cat /tmp/workbook-template.json | python3 -c \"import sys,json; print(json.dumps(sys.stdin.read()))\"),
\"version\": \"1.0\",
\"sourceId\": \"$LAW_ID\",
\"category\": \"workbook\"
}"
echo "Workbook tạo thành công."
echo "Xem tại: Portal → law-az104-m30 → Workbooks"
Cleanup — Dọn dẹp tài nguyên Lab 30
# Xóa Data Collection Rule Association trước
VM_ID=$(az vm show \
--resource-group rg-az104-m30 \
--name vm-law-lab30 \
--query id -o tsv)
az monitor data-collection rule association delete \
--resource "$VM_ID" \
--association-name "dcra-vm-law-lab30" \
--yes
# Xóa Data Collection Rule
az monitor data-collection rule delete \
--resource-group rg-az104-m30 \
--name dcr-az104-m30-windows \
--yes
# Xóa Resource Group — kéo theo VM, Log Analytics Workspace, Workbook
az group delete --name rg-az104-m30 --yes --no-wait
echo "Cleanup hoàn tất. RG và tất cả tài nguyên sẽ bị xóa trong vài phút."
Kết Quả Đầu Ra
Tạo workspace với SKU, retention, daily cap phù hợp; hiểu workspace-context vs resource-context access
Cài AMA extension, tạo Data Collection Rule thu thập Windows Event Log và performance counters
Lọc, chọn cột, tổng hợp dữ liệu log, tính avg/max/count, nhóm theo time bin
Dùng render timechart/barchart/piechart để visualize dữ liệu time-series và phân bổ
Viết KQL phát hiện VM offline, disk gần đầy, security events, top operations từ Activity Log
Tạo workbook tùy chỉnh với nhiều KQL charts, share cho team, dùng built-in templates
Ứng Dụng Thực Tế
Tình huống 1: Công ty logistics — SOC team dùng KQL điều tra sự cố
VM production bị chậm bất thường lúc 02:00 sáng — SOC team cần điều tra nguyên nhân từ logs trong 15 phút.
KQL query chuỗi: (1) Perf tìm CPU/Memory spike lúc 02:00, (2) Event lọc error events cùng thời điểm, (3) SecurityEvent kiểm tra có login bất thường không, (4) AzureActivity xem có ai thay đổi config VM.
Lưu các query điều tra hay dùng thành Saved Queries trong workspace. Tạo Workbook "Incident Investigation" với các query slot có time parameter. Dùng join để correlate Perf + Event + SecurityEvent theo Computer + TimeGenerated.
Điều tra sự cố từ 4 giờ xuống 15 phút. Root cause analysis đơn giản bằng KQL. Workbook chia sẻ cho toàn đội — junior engineer cũng điều tra được. Bằng chứng log giữ 60 ngày cho audit.
Tình huống 2: Trường đại học — Báo cáo IT compliance hàng tháng tự động
IT phải báo cáo uptime, security events và resource usage cho Ban giám hiệu mỗi tháng — trước đây mất 2 ngày để tổng hợp thủ công.
Workbook tổng hợp: uptime % từ Heartbeat, top 10 security events từ SecurityEvent, CPU/Memory trend từ Perf, Azure cost từ billing API. Export PDF hoặc Excel từ Workbook.
Log Analytics Workspace thu thập từ toàn bộ 50 VMs qua AMA + DCR. Workbook "Monthly IT Report" với time parameter = last 30 days. Logic App tự động chạy export cuối tháng, gửi email PDF cho BGH.
Báo cáo từ 2 ngày xuống 0 giờ — tự động hoàn toàn. Dữ liệu chính xác realtime thay vì ước tính. BGH có dashboard live trên tablet. Tiết kiệm 2 nhân sự IT 2 ngày/tháng.
Tình huống 3: ISP / Nhà cung cấp dịch vụ — Multi-tenant log isolation
MSP quản lý Azure cho 20 khách hàng doanh nghiệp — mỗi khách hàng chỉ được thấy log của mình, không được xem log khách hàng khác.
Mỗi khách hàng có 1 Log Analytics Workspace riêng. Bật Resource-context access control. RBAC: admin MSP có quyền toàn bộ; khách hàng có Log Analytics Reader chỉ trên workspace của họ.
Azure Lighthouse delegate workspace của khách hàng sang MSP tenant để quản lý tập trung. Tạo Saved Queries theo template cho từng khách hàng. Daily Cap riêng mỗi workspace để kiểm soát chi phí theo khách.
Data isolation hoàn toàn giữa khách hàng. MSP quản lý tập trung nhưng billing phân tách rõ ràng. Khách hàng tự query log của mình. Đáp ứng GDPR — data của doanh nghiệp VN không rò sang tenant khác.