[Golang] 使用 Go 程式將 Process memory 資訊寫入 InfluxDB,並在儀表板上顯示
今天要查一個 Linux process 記憶體吃很兇的問題…
在查這種問題前,總是得先觀察一下到底吃多兇。
當然用 atop 就可以一直觀察,不過它沒辦法畫出曲線,
將 atop 檔案轉成可分析的文字檔 + 畫出圖表 雖然可行,
不過那就是得批次做,無法即時將記憶體用量顯示成圖表…
這時想起了最近 使用 Telegraf 和 InfluxDB,記錄系統資源使用量,
這不就是 InfluxDB 可以再次派上用場的時候嗎?
先說明一下環境,我要觀察的 Linux 機器是在實驗室裡面,
只能從 Mac 筆電這邊連過去,實驗室連不回筆電這邊 (也就是單向)。
因此我打算:
- 在 Linux 機器裡放一個 shell script,執行時輸出 process 的記憶體使用量
- 在 Mac 筆電裡定時執行一個 Go 程式,透過 ssh 去執行 Linux 機器上的 shell script,並將取得的資料寫入 InfluxDB 中
來看看怎麼做吧~
1. Linux 中觀察 Process 的記憶體用量
假設我想觀察的 Process 名稱是 mydaemon,
那我就寫一個 get_daemon_ram.sh 內容如下,
基本上就是找出 mydaemon 那支 process (同時避開 grep 自己的 process),
再從 /proc/<PID>/status 中找出 VmRSS (單位是 KB),
再將值除以 1024,就可以得到單位 MB 的記憶體用量:
#!/bin/sh cat /proc/$(ps aux | egrep mydaemon | egrep -v "grep" | awk '{print $2}')/status 2>/dev/null | egrep "VmRSS" | awk '{print $2 / 1024}'
2. 在 InfluxDB 中建立資料來源
打開 InfluxDB > Data > Sources,
在 Client Libraries 這邊有許多種可用的程式語言,
點下 Go 來使用 Golang 開發~
這時會出現如下的畫面,
我們需要一個 token (認證用)來寫入 DB,
可以按 Generate Token 建立一個新的,或是從現有的 token 中選一個。
像我懶得建,就沿用管理者的 admin’s Token。
同時,還需要一個 bucket 來儲存我們的資料,
因此要按下 Create Bucket 來建立一個新的 bucket:
Bucket 的名字可以自己取,像我取了 Process Memory,
因為我預期所有的 process 記憶體用量都會存在這裡面:
Bucket 建立好之後,資料來源就算是完成了~
3. 實作 Go 程式取得資料、並寫入 InfluxDB
在步驟 2 中,當我們點擊 Go 語言時,
它下面其實就把 Go 的範例程式列出來了,
可以直接複製貼上,再作相關的修改就可以:
package main import ( "fmt" "log" "os/exec" influxdb2 "github.com/influxdata/influxdb-client-go/v2" ) func main() { mem_mb, err := exec.Command("ssh", "-i", "/testkey", "[email protected]", "/get_prefetchd_mem.sh").Output() if err != nil { log.Fatal(err) } // You can generate a Token from the "Tokens Tab" in the UI const token = "jHK......" const bucket = "Process Memory" const org = "Home" client := influxdb2.NewClient("http://localhost:8086", token) // always close client at the end defer client.Close() // get non-blocking write client writeAPI := client.WriteAPI(org, bucket) // write line protocol writeAPI.WriteRecord(fmt.Sprintf("stat,unit=MB ram=%s", mem_mb)) // Flush writes writeAPI.Flush() fmt.Printf("RAM: %s", mem_mb) }
這個 Go 程式基本上會透過 ssh,
去遠端機器執行 get_daemon_ram.sh 取得目前的記憶體使用量,
然後用 InfluxDB API 寫入一行到 stat 這張表裡面,
同時加上兩個欄位:
- unit = MB
- ram = <記憶體用量>
4. 建立 InfluxDB Dashboard
從 InfluxDB UI > Boards 選擇 Create Dashboard:
按下 Add Cell 在這儀表板上加一個東西:
資料來源選擇剛建立好的 Process Memory bucket,
從 stat 這張表裡面取出 ram 那個欄位:
設定好之後,就會開始有值進來,
因此開始可以畫出圖表:
時間等久一點,就可以看出長遠的記憶體用量趨勢了:
參考資料: