ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

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

2021-04-07 16:04:40  阅读:277  来源: 互联网

标签:node exporter err 自研 fields prometheus line strings Buffers


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

标签:node,exporter,err,自研,fields,prometheus,line,strings,Buffers
来源: https://blog.51cto.com/13858192/2690390

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有