AI智能
改变未来

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


需求:利用go语言获取linux主机的cpu利用率及内存使用量和剩余量,并将其制作成exporter

编写go代码及注解如下:

package mainimport (\"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 ticksif i == 4 {  // idle is the 5th field in the cpu line//第五列的数据赋值给idleidle = val}}return}}return}func ReadLine(lineNumber int) string{//读取/proc/meminfo内容file, _ := os.Open(\"/proc/meminfo\")//按行读取所有内容fileScanner := bufio.NewScanner(file)lineCount := 1for 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)//端口为8006http.ListenAndServe(\":8006\", nil)}

执行并打开页面(每次加载页面会自动刷新数据值):

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

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 用go编写prometheus自研exporter——CPU及内存的指标