用Go语言快速搭一个轻量监控系统,运维小哥直呼真香

上周帮朋友公司查服务器卡顿问题,发现他们还在用手工查日志、刷新网页看CPU占用——这哪是监控,这是碰运气。后来我用Go写了不到200行代码,跑在树莓派上,实时抓取Nginx请求量、MySQL连接数、磁盘剩余空间,数据自动推到Telegram群,还带异常告警。朋友试了两天,说比之前买的商业监控工具反应还快。

为什么选Go写监控?

不是赶时髦。Go编译出来是单个二进制文件,扔进CentOS、Ubuntu甚至Alpine Linux都能直接跑,不用装运行时;协程模型天生适合处理大量HTTP探针和定时采集任务;标准库net/http、encoding/json、time全够用,连第三方包都省了大半。

一个能跑的最小监控采集器

先写个基础版:每10秒查一次本机内存使用率,输出JSON格式:

package main

import (
	"encoding/json"
	"fmt"
	"os/exec"
	"strings"
	"time"
)

func getMemUsage() (float64, error) {
	out, err := exec.Command("sh", "-c", "free | awk 'NR==2{printf \"%.1f\", $3*100/$2}'").Output()
	if err != nil {
		return 0, err
	}
	memStr := strings.TrimSpace(string(out))
	var memPct float64
	fmt.Sscanf(memStr, "%f", &memPct)
	return memPct, nil
}

func main() {
	for {
		mem, _ := getMemUsage()
		data := map[string]interface{}{
			"timestamp": time.Now().Unix(),
			"metric":    "memory_usage_percent",
			"value":     mem,
		}
		b, _ := json.Marshal(data)
		fmt.Println(string(b))
		time.Sleep(10 * time.Second)
	}
}

保存为monitor.go,终端执行go run monitor.go就能看到滚动输出。想存文件?加一行os.WriteFile("log.jsonl", append(b, '\n'), 0644)就行。

再加一层:HTTP接口暴露指标

把上面逻辑包进HTTP服务,让Prometheus也能来拉数据:

http.HandleFunc("/metrics", func(w http.ResponseWriter, r *http.Request) {
	mem, _ := getMemUsage()
	fmt.Fprintf(w, "# HELP server_memory_usage_percent Memory usage in percent\n")
	fmt.Fprintf(w, "# TYPE server_memory_usage_percent gauge\n")
	fmt.Fprintf(w, "server_memory_usage_percent %f\n", mem)
})

http.ListenAndServe(":8080", nil)

浏览器打开http://localhost:8080/metrics,立马看到标准Prometheus格式指标,对接现成生态零成本。

别光采,得会告警

监控不告警等于没监。下面这段代码检测内存超85%就发微信(用Server酱):

if mem > 85.0 {
	msg := fmt.Sprintf("警告:服务器内存使用率 %.1f%%!", mem)
	http.PostForm("https://sc.ftqq.com/XXX.send", url.Values{"text": {msg}})
}

Server酱注册个账号就有免费KEY,5分钟接入。当然你也可以换成钉钉机器人或飞书卡片,改几行URL和参数的事。

Go语言写监控,真没那么玄乎。不需要框架堆砌,也不必等“完美设计”。一台老笔记本+Go环境,下午搭完,晚上就能盯生产库慢查询。真正卡住人的,从来不是技术门槛,而是还没动手,就先被“要学Prometheus、Grafana、Alertmanager”吓退了。