上周帮朋友公司查服务器卡顿问题,发现他们还在用手工查日志、刷新网页看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”吓退了。