[Golang] 使用 Go 程式將 Process memory 資訊寫入 InfluxDB,並在儀表板上顯示

[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", "root@172.22.1.2", "/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 那個欄位:

 

設定好之後,就會開始有值進來,

因此開始可以畫出圖表:

 

時間等久一點,就可以看出長遠的記憶體用量趨勢了:

 

參考資料:

(本頁面已被瀏覽過 212 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料