Go应用高级监控:从指标到告警
在现代Go(Golang)开发中,基本的日志记录和健康检查已不够用。对于生产系统,需要深入的可观测性:收集自定义指标、导出到Prometheus、在Grafana中可视化以及自动告警。本文将深入探讨Go应用监控的高级层面——从指标架构到基于业务逻辑的告警配置。
监控架构:Prometheus + Go
Go的标准监控栈包括:
- Prometheus — 指标采集和存储系统(拉取模型)。
- Prometheus Go客户端(
prometheus/client_golang)— 用于导出指标的库。 - Grafana — 仪表盘可视化。
- Alertmanager — 告警管理(邮件、Slack、Telegram)。
Go应用需要提供一个HTTP端点(通常是/metrics),Prometheus从中拉取数据。我们来看一下基本配置。
package main
import ( "net/http" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp")
func main() { // 注册标准Go指标(运行时、GC、协程) prometheus.MustRegister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{})) prometheus.MustRegister(prometheus.NewGoCollector())
http.Handle("/metrics", promhttp.Handler()) http.ListenAndServe(":8080", nil)}运行应用后,您将获得标准指标:go_goroutines、process_cpu_seconds_total、go_memstats_alloc_bytes等。但对于高级监控来说,这还不够——需要自定义指标。
创建自定义指标:Gauge、Counter、Histogram
Prometheus支持四种主要指标类型。我们以处理HTTP请求的Go应用为例进行说明。
Counter(计数器)— 事件数量
用于统计请求、错误、任务执行次数。
var requestCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "http_requests_total", Help: "HTTP请求总数", }, []string{"method", "endpoint", "status"},)
func init() { prometheus.MustRegister(requestCounter)}
func handler(w http.ResponseWriter, r *http.Request) { // 处理请求 requestCounter.WithLabelValues(r.Method, r.URL.Path, "200").Inc()}Gauge(仪表盘)— 当前值
适用于监控队列、连接池、温度等。
var queueSize = prometheus.NewGauge( prometheus.GaugeOpts{ Name: "task_queue_size", Help: "当前任务队列大小", },)
func addToQueue() { queueSize.Inc()}
func processFromQueue() { queueSize.Dec()}Histogram(直方图)— 值分布
用于测量响应时间或数据大小。
var requestDuration = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "http_request_duration_seconds", Help: "请求处理时间直方图", Buckets: prometheus.DefBuckets, // 0.005, 0.01, 0.025, 0.05, ... }, []string{"endpoint"},)
func measureRequest(endpoint string, duration float64) { requestDuration.WithLabelValues(endpoint).Observe(duration)}Summary(摘要)— 分位数
类似于直方图,但计算精确的分位数(p50、p95、p99)。
var requestLatency = prometheus.NewSummaryVec( prometheus.SummaryOpts{ Name: "http_request_latency_seconds", Help: "请求延迟(分位数)",