Go 应用监控:库与工具

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Go (Golang) 应用监控:工具与库完全指南



监控是任何服务器应用运维中至关重要的一环。Go (Golang) 生态系统已开发出众多工具,用于实时跟踪性能、状态和错误。本文将深入探讨 Go 应用监控的关键库和方法,包括 Prometheus、expvar、pprof 和 OpenTelemetry。



为什么需要监控 Go 应用?

Go 应用常用于高负载微服务、API 网关和后台处理器。没有监控,您可能会错过:

  • 内存和 goroutine 泄漏;
  • 慢请求和锁竞争;
  • 负载下的性能下降;
  • 数据库和外部服务的连接错误。


1. Prometheus — 指标收集标准

Prometheus 是 Go 世界中指标收集的事实标准。官方客户端库 prometheus/client_golang 可以轻松以 Prometheus 格式导出指标。



安装

go get github.com/prometheus/client_golang/prometheusgo get github.com/prometheus/client_golang/prometheus/promhttp


示例:请求计数器和时间直方图

package main

import ( "net/http" "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp")

var ( requestCount = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "http_requests_total", Help: "Total number of HTTP requests", }, []string{"method", "endpoint"}, ) requestDuration = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "http_request_duration_seconds", Help: "Duration of HTTP requests in seconds", Buckets: prometheus.DefBuckets, }, []string{"method", "endpoint"}, ))

func init() { prometheus.MustRegister(requestCount, requestDuration)}

func middleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() next.ServeHTTP(w, r) duration := time.Since(start).Seconds() requestCount.WithLabelValues(r.Method, r.URL.Path).Inc() requestDuration.WithLabelValues(r.Method, r.URL.Path).Observe(duration) })}

func main() { mux := http.NewServeMux() mux.Handle("/metrics", promhttp.Handler()) mux.Handle("/", middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello, World!")) }))) http.ListenAndServe(":8080", mux)}

启动后,指标可通过 http://localhost:8080/metrics 访问。Prometheus 将配置从此端点进行采集。



2. expvar — 内置指标导出

Go 标准库提供了 expvar 包,用于发布应用状态变量。它不需要外部依赖。



使用示例

package main

import ( "expvar" "net/http")

var ( requests = expvar.NewInt("requests_total") errors = expvar.NewInt("errors_total"))

func handler(w http.ResponseWriter, r *http.Request) { requests.Add(1) // 模拟错误 if r.URL.Query().Get("error") == "1" { errors.Add(1) w.WriteHeader(http.StatusInternalServerError) return } w.Write([]byte("OK"))}

func main() { http.HandleFunc("/debug/vars", expvar.Handler().ServeHTTP) http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil)}

指标可通过路径 /debug/vars 以 JSON 格式访问。要与 Prometheus 集成,可以使用 <

推荐