用go編寫prometheus自研exporter——CPU及內存的指標

需求:利用go語言獲取linux主機的cpu利用率及內存使用量和剩餘量,並將其製做成exporter

編寫go代碼及註解以下:

package main

import (
    "bufio"
    "io/ioutil"
    "net/http"
    "os"
    "fmt"
    "strconv"
    "strings"
    "time"
)
func getCPUSample() (idle, total uint64) {
    //讀取/proc/stat內容
    contents, err := ioutil.ReadFile("/proc/stat")
    if err != nil {
        return
    }
    //讀取內容轉化爲字符串
    lines := strings.Split(string(contents), "\n")
    for _, line := range(lines) {
        //將字符串以空白字符(\t, \n, \v, \f, \r, ’ ‘, U+0085 (NEL), U+00A0 (NBSP) 。)進行分割多個子串
        fields := strings.Fields(line)
        //若是第一列字符爲「cpu」
        if fields[0] == "cpu" {
            //統計子串數量
            numFields := len(fields)
            for i := 1; i < numFields; i++ {
                val, err := strconv.ParseUint(fields[i], 10, 64)
                if err != nil {
                    fmt.Println("Error: ", i, fields[i], err)
                }
                //將是CPU字符的全部子串相加
                total += val // tally up all the numbers to get total ticks
                if i == 4 {  // idle is the 5th field in the cpu line
                    //第五列的數據賦值給idle
                    idle = val
                }
            }
            return
        }
    }
    return
}

func ReadLine(lineNumber int) string{
    //讀取/proc/meminfo內容
    file, _ := os.Open("/proc/meminfo")
    //按行讀取全部內容
    fileScanner := bufio.NewScanner(file)
    lineCount := 1
    for fileScanner.Scan(){
        if lineCount == lineNumber{
            return fileScanner.Text()
        }
        lineCount++
    }
    defer file.Close()
    return ""
}

func handler(w http.ResponseWriter, r *http.Request) {
    //定義一個整數型切片
    var s []int
   //讀取/proc/meminfo的第二行內容
    MemFree := ReadLine(2)
    //將讀取的內容轉化爲字符串
    MemFree_lines := strings.Split(string(MemFree), "\n")
    //將字符串以空白字符(\t, \n, \v, \f, \r, ’ ‘, U+0085 (NEL), U+00A0 (NBSP) 。)進行分割多個子串
    for _, MemFree_line := range (MemFree_lines) {
        fields := strings.Fields(MemFree_line)
        //將第二列的內容轉化爲整數,並將這個整數追加到s切片中
        if MemFree_line, err := strconv.Atoi(fields[1]); err == nil {
            //fmt.Printf("%T, %v", MemFree_line, MemFree_line)
            s = append(s, MemFree_line)
        }
    }
    Buffers := ReadLine(4)
    Buffers_lines := strings.Split(string(Buffers), "\n")
    for _, Buffers_line := range (Buffers_lines) {
        fields := strings.Fields(Buffers_line)
        if Buffers_line, err := strconv.Atoi(fields[1]); err == nil {
            //fmt.Printf("%T, %v", Buffers_line, Buffers_line)
            s = append(s, Buffers_line)
        }
    }
    Cached := ReadLine(4)
    Cached_lines := strings.Split(string(Cached), "\n")
    for _, Cached_line := range (Cached_lines) {
        fields := strings.Fields(Cached_line)
        if Cached_line, err := strconv.Atoi(fields[1]); err == nil {
            //fmt.Printf("%T, %v", Cached_line, Cached_line)
            s = append(s, Cached_line)
        }
    }
    MemTotal := ReadLine(1)
    MemTotal_lines := strings.Split(string(MemTotal), "\n")
    for _, MemTotal_line := range (MemTotal_lines) {
        fields := strings.Fields(MemTotal_line)
        if MemTotal_line, err := strconv.Atoi(fields[1]); err == nil {
            //fmt.Printf("%T, %v", MemTotal_line, MemTotal_line)
            s = append(s, MemTotal_line)

        }
    }

    idle0, total0 := getCPUSample()
    time.Sleep(3 * time.Second)
    idle1, total1 := getCPUSample()

    idleTicks := float64(idle1 - idle0)
    totalTicks := float64(total1 - total0)
    //計算cpu利用率
    cpuUsage := 100 * (totalTicks - idleTicks) / totalTicks
    //計算內存的使用率及剩餘量
    memoryused := (s[0] + s[1] + s[2])
    memoryfreeused:=(s[3]-memoryused)
    //頁面顯示內容
    fmt.Fprintf(w,"#HELP node_memory_guest_seconds\n node_memory{key=\"used\"}\t%v\n node_memory{key=\"free\"}\t%v\n#node_CPU_guest_seconds\n node_cpu{key=\"usage\"}\t%v\n",memoryused,memoryfreeused,cpuUsage)

}

func main(){

//調用handler函數
    http.HandleFunc("/", handler)
    //端口爲8006
    http.ListenAndServe(":8006", nil)
}

執行並打開頁面(每次加載頁面會自動刷新數據值):

[root@localhost ~]# go run  exporter_cpu_memory.go
[root@localhost ~]# curl 127.0.0.1:8006
#HELP node_memory_guest_seconds
 node_memory{key="used"}        117864
 node_memory{key="free"}        878060
#node_CPU_guest_seconds
 node_cpu{key="usage"}  0

用go編寫prometheus自研exporter——CPU及內存的指標

相關文章
相關標籤/搜索