golang监控系统和时间序列数据库插件prometheus的使用

Golang监控系统和时间序列数据库插件Prometheus的使用

Prometheus简介

Prometheus是一个开源的系统监控和警报工具包,由Cloud Native Computing Foundation(云原生计算基金会)托管。它具有以下主要特点:

  • 多维数据模型:时间序列通过指标名称和键/值对来标识
  • 强大的查询语言PromQL:可以灵活地查询和分析数据
  • 独立的单节点架构:不依赖分布式存储
  • HTTP拉取模型:定期从配置的目标拉取指标
  • 支持推送模式:通过中间网关支持推送时间序列
  • 服务发现:自动发现监控目标
  • 多种可视化支持:提供多种图形和仪表板支持

架构概述

Prometheus架构图

在Golang中使用Prometheus

基本示例

以下是一个完整的Golang程序示例,展示如何使用Prometheus客户端库暴露指标:

package main

import (
	"net/http"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promauto"
	"github.com/prometheus/client_golang/prometheus/promhttp"
)

// 定义指标
var (
	opsProcessed = promauto.NewCounter(prometheus.CounterOpts{
		Name: "myapp_processed_ops_total",
		Help: "The total number of processed events",
	})
	
	httpRequests = promauto.NewCounterVec(prometheus.CounterOpts{
		Name: "http_requests_total",
		Help: "Number of HTTP requests",
	}, []string{"path", "method"})
	
	requestDuration = promauto.NewHistogram(prometheus.HistogramOpts{
		Name:    "http_request_duration_seconds",
		Help:    "Duration of HTTP requests",
		Buckets: prometheus.DefBuckets,
	})
)

func recordMetrics() {
	go func() {
		for {
			opsProcessed.Inc()
			time.Sleep(2 * time.Second)
		}
	}()
}

func main() {
	// 启动记录指标的goroutine
	recordMetrics()

	// 设置HTTP处理程序
	http.Handle("/metrics", promhttp.Handler())
	
	// 示例HTTP处理程序
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		defer func() {
			duration := time.Since(start).Seconds()
			requestDuration.Observe(duration)
			httpRequests.WithLabelValues(r.URL.Path, r.Method).Inc()
		}()
		
		w.Write([]byte("Hello, world!"))
	})

	// 启动HTTP服务器
	http.ListenAndServe(":2112", nil)
}

指标类型说明

Prometheus客户端库支持四种主要的指标类型:

  1. Counter(计数器):只增不减的指标,如请求总数
  2. Gauge(仪表盘):可增可减的指标,如当前内存使用量
  3. Histogram(直方图):采样观察值,如请求持续时间
  4. Summary(摘要):类似于直方图,但计算客户端定义的分位数

高级示例:自定义收集器

package main

import (
	"net/http"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
)

// 自定义收集器
type CustomCollector struct {
	customMetric *prometheus.Desc
}

func NewCustomCollector() *CustomCollector {
	return &CustomCollector{
		customMetric: prometheus.NewDesc(
			"custom_metric",
			"Custom metric description",
			[]string{"label1", "label2"},
			prometheus.Labels{"const_label": "value"},
		),
	}
}

func (c *CustomCollector) Describe(ch chan<- *prometheus.Desc) {
	ch <- c.customMetric
}

func (c *CustomCollector) Collect(ch chan<- prometheus.Metric) {
	// 模拟收集数据
	value := 42.0
	ch <- prometheus.MustNewConstMetric(
		c.customMetric,
		prometheus.GaugeValue,
		value,
		"label_value1", "label_value2",
	)
}

func main() {
	// 注册自定义收集器
	customCollector := NewCustomCollector()
	prometheus.MustRegister(customCollector)

	// 暴露指标端点
	http.Handle("/metrics", promhttp.Handler())
	http.ListenAndServe(":8080", nil)
}

安装Prometheus

Docker方式运行

docker run --name prometheus -d -p 127.0.0.1:9090:9090 prom/prometheus

配置文件示例

创建一个简单的Prometheus配置文件prometheus.yml来抓取我们的Golang应用指标:

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'golang-app'
    static_configs:
      - targets: ['localhost:2112']

然后使用此配置文件运行Prometheus:

docker run -d -p 9090:9090 -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus

查询指标

Prometheus提供了强大的查询语言PromQL。一些常用查询示例:

  • 查询总请求数:http_requests_total
  • 按路径和方法分组:sum by (path, method) (http_requests_total)
  • 计算请求率:rate(http_requests_total[5m])
  • 计算95百分位延迟:histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))

告警规则

可以在Prometheus中配置告警规则,例如:

groups:
- name: example
  rules:
  - alert: HighRequestRate
    expr: rate(http_requests_total[5m]) > 100
    for: 10m
    labels:
      severity: page
    annotations:
      summary: High request rate on {{ $labels.instance }}
      description: "Request rate is {{ $value }}"

总结

Prometheus是一个功能强大的监控系统,与Golang应用集成非常方便。通过使用Prometheus客户端库,开发者可以轻松地在应用中暴露各种指标,然后使用Prometheus进行收集、存储和分析。结合Grafana等可视化工具,可以构建完整的监控解决方案。


更多关于golang监控系统和时间序列数据库插件prometheus的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang监控系统和时间序列数据库插件prometheus的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang 监控系统与 Prometheus 时间序列数据库使用指南

Prometheus 是一个开源的系统监控和警报工具包,特别适合处理时间序列数据。下面我将详细介绍如何在 Golang 项目中集成 Prometheus 监控。

1. Prometheus 基础概念

Prometheus 的核心组件包括:

  • 时间序列数据库
  • 数据抓取机制
  • 强大的查询语言 PromQL
  • 告警系统

2. 在 Golang 中集成 Prometheus

首先安装必要的依赖:

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

2.1 基本指标类型

Prometheus 支持四种主要指标类型:

  1. Counter(计数器)
  2. Gauge(仪表盘)
  3. Histogram(直方图)
  4. Summary(摘要)

2.2 示例代码

package main

import (
	"net/http"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
)

// 定义指标
var (
	httpRequestsTotal = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "http_requests_total",
			Help: "Total number of HTTP requests",
		},
		[]string{"method", "path"},
	)

	httpRequestDuration = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Name:    "http_request_duration_seconds",
			Help:    "Duration of HTTP requests",
			Buckets: prometheus.DefBuckets,
		},
		[]string{"method", "path"},
	)

	goroutinesCount = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "goroutines_count",
			Help: "Current number of goroutines",
		},
	)
)

func init() {
	// 注册指标
	prometheus.MustRegister(httpRequestsTotal)
	prometheus.MustRegister(httpRequestDuration)
	prometheus.MustRegister(goroutinesCount)
}

func main() {
	// 启动一个goroutine定期更新goroutines指标
	go func() {
		for {
			goroutinesCount.Set(float64(runtime.NumGoroutine()))
			time.Sleep(5 * time.Second)
		}
	}()

	// 示例HTTP处理函数
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		defer func() {
			duration := time.Since(start).Seconds()
			httpRequestDuration.WithLabelValues(r.Method, r.URL.Path).Observe(duration)
			httpRequestsTotal.WithLabelValues(r.Method, r.URL.Path).Inc()
		}()

		w.Write([]byte("Hello, Prometheus!"))
	})

	// 暴露metrics端点
	http.Handle("/metrics", promhttp.Handler())

	// 启动HTTP服务器
	http.ListenAndServe(":8080", nil)
}

3. 高级用法

3.1 自定义收集器

type CustomCollector struct {
	customMetric *prometheus.Desc
}

func NewCustomCollector() *CustomCollector {
	return &CustomCollector{
		customMetric: prometheus.NewDesc(
			"custom_metric",
			"A custom metric",
			[]string{"label"},
			nil,
		),
	}
}

func (c *CustomCollector) Describe(ch chan<- *prometheus.Desc) {
	ch <- c.customMetric
}

func (c *CustomCollector) Collect(ch chan<- prometheus.Metric) {
	// 这里可以添加获取指标值的逻辑
	value := float64(42)
	ch <- prometheus.MustNewConstMetric(
		c.customMetric,
		prometheus.GaugeValue,
		value,
		"example-label",
	)
}

// 注册自定义收集器
func init() {
	prometheus.MustRegister(NewCustomCollector())
}

3.2 中间件示例

func PrometheusMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		
		// 使用ResponseWriter包装器捕获状态码
		rw := &responseWriter{w, http.StatusOK}
		next.ServeHTTP(rw, r)
		
		duration := time.Since(start).Seconds()
		httpRequestDuration.WithLabelValues(r.Method, r.URL.Path).Observe(duration)
		httpRequestsTotal.WithLabelValues(r.Method, r.URL.Path, strconv.Itoa(rw.status)).Inc()
	})
}

type responseWriter struct {
	http.ResponseWriter
	status int
}

func (rw *responseWriter) WriteHeader(code int) {
	rw.status = code
	rw.ResponseWriter.WriteHeader(code)
}

4. Prometheus 配置

在 Prometheus 的配置文件中添加对应用的抓取配置:

scrape_configs:
  - job_name: 'golang_app'
    scrape_interval: 15s
    static_configs:
      - targets: ['localhost:8080']

5. 查询示例

启动应用后,可以通过以下 PromQL 查询数据:

  • 总请求数:http_requests_total
  • 每秒请求率:rate(http_requests_total[1m])
  • 平均响应时间:rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m])

6. 最佳实践

  1. 为指标添加有意义的标签,但不要过多
  2. 避免使用高基数标签(如用户ID)
  3. 指标名称应使用下划线分隔,单位放在名称最后
  4. 合理设置直方图的桶(buckets)范围

通过以上方式,您可以在 Golang 应用中轻松集成 Prometheus 监控,收集丰富的性能指标数据。

回到顶部