用 Service Map 建立基礎設備監控解決方案
您是否曾經在服務器進程或連結不存在時設置自動通知呢?透過使用 OMS Azure Log Analytics 和 Service Map,可以經由內建的功能以及一點點 PowerSell 來解決這個問題。
為了顯示 Service Map 的實用性,我們建構了一個簡單的三層混合雲應用程式。在 Azure VM Scale Set 前端具有網路資訊服務 IIS,中間運行 Linux 上的 Tomcat Server,後端則為 MySQL。我們另外使用兩天運行 JMeter 的服務器為應用程式產生恆定的負載。此外,有趣的是,我們有一段程式碼在 Tomcat server 上定期運行,加上使用高等 CPU 和內存來影響其效能。
總而言之,這是一個非常簡單的應用程式---比您的真實世界應用程式簡單的多。不過由於我們偶爾會有意使其運行低落,有時候它反而會因此中斷。也許 server 重新啟動,但 JMeter 沒有重新啟動,或者也許我們在應用程序 server上使用太多內存,Tomcat server 死機。沒有什麼比當您要 demo 時卻發現應用程序已經不在那裡來的更加沮喪了。
幸運的是,我們要給大家介紹的超好用工具,就是用來監控這些問題的。現在只要寫一個腳本,Service Map 有一個 REST API,允許您查詢 Service Map上的所有信息。若您在 Service Map 使用者介面上看到它,您能夠透過 API來獲取它。
這個腳本使用非常方便的 armclient 和服務主體來處理身分驗證和建構 Azure 資源管理器 API 調用。
# Service Principal values - see https://blog.davidebbo.com/2014/12/azure-service-principal.html for explanation $TenantId = "" $AppId = "" $Password = "" armclient spn $TenantId $AppId $Password
在這裡因為運行 Tomcat server 的 box 是應用程式中最重要但也最脆弱的機器,此腳本專注於該機器。(同樣的原因,也有腳本運行在不同的 server 上,而不是我要監控的那一個)。首先,我們查詢最近五分鐘內可用的機器列表,查看這個 server 是否在該列表中,如果 server 不在那裡,我們先記著,然後休眠5分鐘後再進行一次檢查。
$apicall = "$myAPIPath/features/serviceMap/machines?api-version=2015-11-01-preview&startTime=$startTime&endTime=$endTime"
$machines = armclient get $apicall | ConvertFrom-Json
foreach($machine in $machines.value) {
if ($machine.properties.displayName -like $targetMachine) {
$foundMachine = $true
}
}
if (!$foundMachine) {
Write-Log -Message ("Can't find machine " + $targetMachine) -Severity 3
}
如果我們的應用程式 server 在那裡,我們就去獲取所有在這個 box 上運行的進程。Tomcat server在這裡嗎?如果沒有,那就先記著然後休眠。
# Call to get the processes for this machine
$apicall = "$myAPIPath/features/serviceMap/machines/" + $machine.name + "/processes?api-version=2015-11-01-preview&startTime=" + $startTime + "&endTime=" + $endTime
$processes = armclient get $apicall | ConvertFrom-Json
foreach ($process in $processes.value) {
if ($process.properties.displayName -like $targetProcess) {
$foundProcess = $true
break
}
}
if (!$foundProcess) {
Write-Log -Message ("Can't find " + $targetProcess + " on machine " + $targetMachine) -Severity 3
}
如果 Tomcat server 運行正常,最後一次檢查是從 Tomcat server到 MySQL的連接。如果連接不在,記錄下來。
# Call to get everything in a map
$mapRequest = "{ 'startTime':'$startTime', 'endTime':'$endTime', 'kind':'map:single-machine-dependency', 'machineId':'" + $machine.id + "' }"
$apicall = "$myAPIPath/features/serviceMap/generateMap?api-version=2015-11-01-preview"
$serverdep = armclient post $apicall $mapRequest | ConvertFrom-Json
foreach ($connection in $serverdep.map.edges.connections) {
$clientProcess = FindProcess $serverDep.map.nodes.processes
$connection.properties.source.id
$serverPort = FindPort $serverDep.map.nodes.ports
$connection.properties.serverPort.id
if (($clientProcess.properties.displayName -like $targetProcess) -and ($serverPort.properties.portNumber -eq $targetPort)){
$foundProcessOutgoingEdges = $true
break
}
}
if (!$foundProcessOutgoingEdges) {
Write-Log -Message ("Can't find connections to port " + $targetPort + " from " + $targetProcess + " on machine " + $targetMachine) -Severity 3
}
如果每個連接都在,那表示所有東西都順利運行,我們在 log 文件寫狀態良好。
else {
Write-Log -Message "Demo application is healthy"
}
每五分鐘,腳本就啟動再檢查一次。
Start-Sleep -s $period
所以一個漂亮的log file會顯示我們應用程序的使用狀態,每五分鐘一次,看起來會長這樣:
"DateTime","Severity","Message" "6/2/2017 11:00:22 AM","3","Can't find Tomcat on machine admdemo-appsvr" "6/2/2017 11:07:22 AM","3","Can't find Tomcat on machine admdemo-appsvr" "6/2/2017 11:11:32 AM","3","Can't find connections from Tomcat on machine admdemo-appsvr" "6/2/2017 11:14:05 AM","3","Can't find connections from Tomcat on machine admdemo-appsvr" "6/2/2017 11:14:42 AM","3","Can't find connections from Tomcat on machine admdemo-appsvr" "6/2/2017 11:18:13 AM","1","Demo application is healthy" "6/2/2017 11:24:48 AM","1","Demo application is healthy" "6/2/2017 11:29:57 AM","1","Demo application is healthy" "6/2/2017 11:35:05 AM","1","Demo application is healthy"
下一步就是把 log紀錄存入 Log Analytics。能藉由在 Log Analytic 配置自訂 紀錄很輕鬆的完成。
經過幾分鐘,一筆筆的資料就會進入 Log Analytic。
之後,教導 Log Analytics 如何抽取自訂字段,特別是 Status_CF,因為這是我們想要關注的警報。
最後,在這裡我們設置了四個警報,三個是尋找各種錯誤的情況---例如缺少機器、缺少進程、缺少連接,而最後一個是讓使用者知道監控本身是否停止。
太好了!現在我們擁有一個自訂的 demo 應用程式的監控架構咯,demo 變得更可預測容易。
有關於如何在未來版本中改善這個腳本的有幾個特色:
- 在 Azure Automation 中運行腳本,因此我們不需要單獨的 server 來運行它。
- 使用 API 而不是自訂 log 檔案數據來提取到 Log analytics 中
- 設置自訂視圖以顯示應用程式的狀態