1 简单示例

  • 下载包

go get github.com/prometheus/client_golang

1 定义指标

// 1. Counter(计数器):用于累计计数(如请求总数)  
var (  
    // NewCounterVec 支持标签(维度)  
    httpRequestsTotal = prometheus.NewCounterVec(  
       prometheus.CounterOpts{  
          Name: "myapp_http_requests_total",      // 指标名称  
          Help: "Total number of HTTP requests.", // 帮助信息  
       },  
       []string{"method", "path"}, // 标签名称列表(此处定义两个标签)  
    )  
)  
  
// 2. Gauge(仪表盘):表示可以增减的瞬时值(如内存使用量)  
var (  
    memoryUsageBytes = prometheus.NewGauge(  
       prometheus.GaugeOpts{  
          Name: "myapp_memory_usage_bytes",  
          Help: "Current memory usage in bytes.",  
       },  
    )  
)  
  
// 3. Histogram(直方图):用于统计数值分布(如请求延迟)  
var (  
    httpRequestDuration = prometheus.NewHistogramVec(  
       prometheus.HistogramOpts{  
          Name:    "myapp_http_request_duration_seconds",  
          Help:    "HTTP request latency distribution in seconds.",  
          Buckets: []float64{0.05, 0.1, 0.5, 1.0}, // 自定义分桶范围  
       },  
       []string{"method"}, // 标签名称列表  
    )  
)  
  
// 4. Summary(摘要):用于计算分位数(客户端计算)  
var (  
    responseSizes = prometheus.NewSummaryVec(  
       prometheus.SummaryOpts{  
          Name:       "myapp_response_sizes_bytes",  
          Help:       "Response size distribution in bytes.",  
          Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01}, // 分位数配置(中位数和90分位)  
       },  
       []string{"status"}, // 标签名称列表  
    )  
)

2 注册指标

在完成指标的定义后,还需要注册他们

/*******************************************  
* 初始化:注册指标到Prometheus默认注册表  
*******************************************/  
func init() {  
    // 注册所有定义的指标  
    prometheus.MustRegister(  
       httpRequestsTotal,  
       memoryUsageBytes,  
       httpRequestDuration,  
       responseSizes,  
    )  
}

3 业务逻辑

在完成以上步骤后,我们还需要模拟一下业务逻辑给指标赋值,且启动HTTP服务并暴露指标。

  
/*******************************************  
* 主函数:启动HTTP服务并暴露指标  
*******************************************/  
func main() {  
    // 启动一个goroutine定期更新Gauge指标(模拟内存使用量)  
    go func() {  
       for {  
          // 模拟内存使用量(500MB ~ 600MB)  
          memoryUsageBytes.Set(500*1024*1024 + float64(time.Now().Unix()%100)*1024*1024)  
          time.Sleep(5 * time.Second)  
       }  
    }()  
  
    // 启动另一个goroutine处理模拟请求  
    go func() {  
       for {  
          // 调用处理函数  
          handleRequest()  
  
          // 更新Counter指标(增加请求计数)  
          httpRequestsTotal.WithLabelValues("GET", "/api").Inc()  
  
          // 更新Summary指标(记录响应大小)  
          responseSizes.WithLabelValues("200").Observe(1024) // 假设固定1KB响应  
  
          time.Sleep(1 * time.Second)  
       }  
    }()  
  
    // 配置HTTP路由  
    http.Handle("/metrics", promhttp.Handler()) // 暴露Prometheus指标的默认端点  
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {  
       w.Write([]byte("Hello, visit /metrics to see metrics!"))  
    })  
  
    // 启动HTTP服务器  
    println("Server started at :8080")  
    http.ListenAndServe(":8080", nil)  
}

4 完整代码

package main  
  
import (  
    "github.com/prometheus/client_golang/prometheus"  
    "github.com/prometheus/client_golang/prometheus/promhttp"    "net/http"    "time")  
  
/*******************************************  
* 定义指标(Metrics)  
*******************************************/  
  
// 1. Counter(计数器):用于累计计数(如请求总数)  
var (  
    // NewCounterVec 支持标签(维度)  
    httpRequestsTotal = prometheus.NewCounterVec(  
       prometheus.CounterOpts{  
          Name: "myapp_http_requests_total",      // 指标名称  
          Help: "Total number of HTTP requests.", // 帮助信息  
       },  
       []string{"method", "path"}, // 标签名称列表(此处定义两个标签)  
    )  
)  
  
// 2. Gauge(仪表盘):表示可以增减的瞬时值(如内存使用量)  
var (  
    memoryUsageBytes = prometheus.NewGauge(  
       prometheus.GaugeOpts{  
          Name: "myapp_memory_usage_bytes",  
          Help: "Current memory usage in bytes.",  
       },  
    )  
)  
  
// 3. Histogram(直方图):用于统计数值分布(如请求延迟)  
var (  
    httpRequestDuration = prometheus.NewHistogramVec(  
       prometheus.HistogramOpts{  
          Name:    "myapp_http_request_duration_seconds",  
          Help:    "HTTP request latency distribution in seconds.",  
          Buckets: []float64{0.05, 0.1, 0.5, 1.0}, // 自定义分桶范围  
       },  
       []string{"method"}, // 标签名称列表  
    )  
)  
  
// 4. Summary(摘要):用于计算分位数(客户端计算)  
var (  
    responseSizes = prometheus.NewSummaryVec(  
       prometheus.SummaryOpts{  
          Name:       "myapp_response_sizes_bytes",  
          Help:       "Response size distribution in bytes.",  
          Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01}, // 分位数配置(中位数和90分位)  
       },  
       []string{"status"}, // 标签名称列表  
    )  
)  
  
/*******************************************  
* 初始化:注册指标到Prometheus默认注册表  
*******************************************/  
func init() {  
    // 注册所有定义的指标  
    prometheus.MustRegister(  
       httpRequestsTotal,  
       memoryUsageBytes,  
       httpRequestDuration,  
       responseSizes,  
    )  
}  
  
/*******************************************  
* 业务逻辑模拟  
*******************************************/  
func handleRequest() {  
    // 模拟处理时间(随机0~1秒)  
    startTime := time.Now()  
    defer func() {  
       duration := time.Since(startTime).Seconds()  
  
       // 更新Histogram指标(记录请求耗时)  
       httpRequestDuration.WithLabelValues("GET").Observe(duration)  
    }()  
  
    // 模拟处理过程  
    time.Sleep(time.Duration(100) * time.Millisecond)  
}  
  
/*******************************************  
* 主函数:启动HTTP服务并暴露指标  
*******************************************/  
func main() {  
    // 启动一个goroutine定期更新Gauge指标(模拟内存使用量)  
    go func() {  
       for {  
          // 模拟内存使用量(500MB ~ 600MB)  
          memoryUsageBytes.Set(500*1024*1024 + float64(time.Now().Unix()%100)*1024*1024)  
          time.Sleep(5 * time.Second)  
       }  
    }()  
  
    // 启动另一个goroutine处理模拟请求  
    go func() {  
       for {  
          // 调用处理函数  
          handleRequest()  
  
          // 更新Counter指标(增加请求计数)  
          httpRequestsTotal.WithLabelValues("GET", "/api").Inc()  
  
          // 更新Summary指标(记录响应大小)  
          responseSizes.WithLabelValues("200").Observe(1024) // 假设固定1KB响应  
  
          time.Sleep(1 * time.Second)  
       }  
    }()  
  
    // 配置HTTP路由  
    http.Handle("/metrics", promhttp.Handler()) // 暴露Prometheus指标的默认端点  
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {  
       w.Write([]byte("Hello, visit /metrics to see metrics!"))  
    })  
  
    // 启动HTTP服务器  
    println("Server started at :8080")  
    http.ListenAndServe(":8080", nil)  
}

最后更新于