用 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 中
  • 設置自訂視圖以顯示應用程式的狀態