用go编写prometheus自研exporter——CPU及内存的指标

上古杰作 · · 1064 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

需求:利用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及内存的指标


有疑问加站长微信联系(非本文作者)

本文来自:51CTO博客

感谢作者:上古杰作

查看原文:用go编写prometheus自研exporter——CPU及内存的指标

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1064 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传