在日常 Go 服务开发中,我们通常需要同时监控 业务指标(比如 QPS、请求延迟、错误率),也需要关注 系统指标(CPU、内存、磁盘占用情况)。
过去这类场景通常要引入多个库:一个负责业务指标采集(Prometheus client),另一个负责系统指标采集(比如 node_exporter 或 gopsutil)。

现在有一个新的开源项目 —— go-commons,它内置了 CPU / 内存 / 磁盘的采集工具,并且提供了丰富的字符串、并发、集合操作工具,可以让我们更快地把 系统监控和业务监控结合起来

这篇文章就带大家写一个最小化的 Web 服务:
👉 使用 go-commons 获取系统资源指标
👉 同时统计 Web 服务的 QPS
👉 最终暴露 /metrics 接口,交给 Prometheus 采集


场景描写:为什么需要应用+系统双指标?

想象一下,你上线了一个 Go Web 服务,结果突然响应变慢。
你打开监控系统:

  • 看到 QPS 正常,但是 平均响应时间升高
  • 系统监控发现 内存使用率拉满
  • 最后定位是某个业务逻辑有内存泄漏

如果你的应用里没有同时暴露业务指标和系统指标,可能要对接多个监控面板来排查。
而现在我们用 go-commons + Prometheus,一站式搞定。


代码实现

下面我们实现一个最小的 Web 服务:

  • /hello:业务 API,用来模拟请求
  • /metrics:暴露 Prometheus 指标,包括 QPS + 内存使用率
package main

import (
	"fmt"
	"net/http"
	"sync/atomic"
	"time"

	"github.com/Rodert/go-commons/systemutils/memutils"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
)

var (
	// 定义业务指标:QPS
	requestsTotal = prometheus.NewCounter(
		prometheus.CounterOpts{
			Name: "app_requests_total",
			Help: "Total number of requests handled by the app",
		},
	)

	// 定义系统指标:内存使用率
	memUsageGauge = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "system_memory_usage_percent",
			Help: "Memory usage percentage from go-commons",
		},
	)

	// 并发安全计数器
	activeRequests int64
)

func init() {
	// 注册 Prometheus 指标
	prometheus.MustRegister(requestsTotal)
	prometheus.MustRegister(memUsageGauge)
}

// 模拟业务接口
func helloHandler(w http.ResponseWriter, r *http.Request) {
	atomic.AddInt64(&activeRequests, 1)
	defer atomic.AddInt64(&activeRequests, -1)

	requestsTotal.Inc() // 请求数 +1

	fmt.Fprintf(w, "Hello, world! Active Requests: %d\n", atomic.LoadInt64(&activeRequests))
}

// 定时采集内存使用率
func startMemCollector() {
	go func() {
		for {
			memInfo, err := memutils.GetMemInfo()
			if err == nil && memInfo.Total > 0 {
				usage := float64(memInfo.Used) / float64(memInfo.Total) * 100
				memUsageGauge.Set(usage)
			}
			time.Sleep(5 * time.Second)
		}
	}()
}

func main() {
	startMemCollector()

	http.HandleFunc("/hello", helloHandler)
	http.Handle("/metrics", promhttp.Handler())

	fmt.Println("🚀 Server started at :8080")
	http.ListenAndServe(":8080", nil)
}

运行服务后:

go run main.go

访问接口:

  • http://localhost:8080/hello 👉 模拟业务请求
  • http://localhost:8080/metrics 👉 可以看到 Prometheus 指标,包括:
# HELP app_requests_total Total number of requests handled by the app
# TYPE app_requests_total counter
app_requests_total 3

# HELP system_memory_usage_percent Memory usage percentage from go-commons
# TYPE system_memory_usage_percent gauge
system_memory_usage_percent 45.8

现在你就拥有了 应用+系统双指标 的监控能力 🚀。


为什么选择 go-commons?

相比直接使用 gopsutil 或者 node_exporter:

  • go-commons 更轻量,依赖更少,大部分功能基于标准库实现
  • 内置了 字符串、集合、并发工具,不仅能采集系统指标,还能在业务逻辑里更快写工具函数
  • 提供了 本地/在线 API 文档点击查看),开发体验更友好

一句话:它不仅是工具库,还能成为你写监控采集器的“底座”


邀请大家参与开源 🎉

go-commons 目前还在快速迭代中:

  • 我们计划增强 systemutils,提供更多监控指标(网络、进程、IO 等)
  • 欢迎大家提交 PR,贡献新的工具函数或监控扩展
  • 也欢迎在 Issue 里分享你的使用场景,让这个项目更贴近开发者的需求

开源的意义不仅在于“拿来用”,更在于一起打磨
如果你也对 Go 工具库 + 监控场景 感兴趣,快来加入吧!

👉 项目地址:https://github.com/Rodert/go-commons