kube-promethues添加自定义指标

9 篇文章 0 订阅

通过promethues-golang创建自定义指标

https://github.com/prometheus/client_golang/blob/master/examples/random/main.go
直接go run main.go运行起来即可,此时通过IP:8080/metrics可以获取到数据

添加额外监控组件配置scrape_configs

新建prometheus-additional.yaml  文件

- job_name: 'my_metrics'
  static_configs:
    - targets:
      - 172.20.16.185:8080

创建secret

kubectl create secret generic additional-scrape-configs --from-file=prometheus-additional.yaml -n monitoring


名字为additional-scrape-configs, 使用的文件为prometheus-additional.yaml 


修改promethues-promethues.yaml

该文件来自https://github.com/prometheus-operator/kube-prometheus

podMonitorNamespaceSelector: {}
podMonitorSelector: {}
//添加以下三行
additionalScrapeConfigs:      
  name: additional-scrape-configs
  key: prometheus-additional.yaml

应用到promethues

kubectl apply -f prometheus-prometheus.yaml

页面查看

promql查询并展示

 

promethues client_golang简单使用

大致流程为:创建指标->注册指标->定时循环获取数据

package main

import (
	"flag"
	"log"
	"math"
	"math/rand"
	"net/http"
	"time"

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

var (
	addr = flag.String("listen-address", ":8080", "The address to listen on for HTTP requests.")
	oscillationPeriod = flag.Duration("oscillation-period", 10*time.Minute, "The duration of the rate oscillation period.")
)

var (
	myGuage = prometheus.NewGaugeVec(prometheus.GaugeOpts{
		Name: "myGuage",
		Help: "my test guage type",
	}, []string{"myGuage"})
)

func init() {
	// Add Go module build info.
	prometheus.MustRegister(myGuage)
}

func main() {
	flag.Parse()

	start := time.Now()

	oscillationFactor := func() float64 {
		return 2 + math.Sin(math.Sin(2*math.Pi*float64(time.Since(start))/float64(*oscillationPeriod)))
	}

	go func() {
		for {
			v := rand.ExpFloat64() / 1e6
			myGuage.WithLabelValues("myguage").Set(v)
			time.Sleep(time.Duration(50*oscillationFactor()) * time.Millisecond)

		}
	}()

	// Expose the registered metrics via HTTP.
	http.Handle("/metrics", promhttp.HandlerFor(
		prometheus.DefaultGatherer,
		promhttp.HandlerOpts{
			// Opt into OpenMetrics to support exemplars.
			EnableOpenMetrics: true,
		},
	))
	log.Fatal(http.ListenAndServe(*addr, nil))
}

查看新指标

promethues client_golang小案例

        在大多数情况下人们都倾向于使用某些量化指标的平均值,例如CPU的平均使用率、页面的平均响应时间。这种方式的问题很明显,以系统API调用的平均响应时间为例:如果大多数API请求都维持在100ms的响应时间范围内,而个别请求的响应时间需要5s,那么就会导致某些WEB页面的响应时间落到中位数的情况,而这种现象被称为长尾问题。

        为了区分是平均的慢还是长尾的慢,最简单的方式就是按照请求延迟的范围进行分组。例如,统计延迟在0~10ms之间的请求数有多少而10~20ms之间的请求数又有多少。Histogram和Summary都是为了能够解决这样问题的存在,通过Histogram和Summary类型的监控指标,我们可以快速了解监控样本的分布情况。

        此处小案例监控http请求的响应时间、请求次数、响应时间所处区间,将promethues的counter类型、guage类型、Summary类型、Histogram类型都做了演示。

  • counter:只增不减的计数器
  • guage:可憎可减的仪表盘
  • histogram和summary用于分析数据分布
    • histogram:只展示每个区间的结果的个数,只计数,资源消耗小;也可计算分位数的结果,使用promql查询时在promethues服务端计算
    • summary:会直接计算出分位数的结果然后展示,在客户端计算

        因此对于分位数的计算而言,Summary在通过PromQL进行查询时有更好的性能表现,而Histogram则会消耗更多的资源。反之对于客户端而言Histogram消耗的资源更少。在选择这两种方式时用户应该按照自己的实际场景进行选择。

package main

import (
	"flag"
	"fmt"
	"log"
	"math/rand"
	"net/http"
	"strings"
	"time"

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

var (
	addr = flag.String("listen-address", ":8080", "The address to listen on for HTTP requests.")
)

var (
	requestTimes = prometheus.NewCounterVec(prometheus.CounterOpts{
		Name: "request_times",
		Help: "请求次数",
	}, []string{"method", "url", "host"})
	// 多个label,需要与requestTimes.WithLabelValues(strings.ToLower(r.Method), r.URL.String())一一对应,
	// 效果为可用promql  request_times{method="get",url="/metrics",host="172.20.16.185:8080"}查询

	requestTime = prometheus.NewGaugeVec(prometheus.GaugeOpts{
		Name: "request_time",
		Help: "每次请求花费的时间",
	}, []string{"method", "url", "host"})

	// 需要计算,开销大
	requestSummary = prometheus.NewSummaryVec(prometheus.SummaryOpts{
		Name:        "request_time_summary",
		Help:        "summary test",
		Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
		// 0.5,0.9,0.99表示分位数,0.05,0.01,0.001表示可接收的误差,比如0.5分位的值为10,其实这个10可能是(0.45,0.55)这个区间内的某个值,太过精确会导致cpu压力过大
	}, []string{"request_time"})

	// Histogram只计数,不计算,开销小
	// 线性桶
	requestHistogram = prometheus.NewHistogramVec(prometheus.HistogramOpts{
		Name:        "request_time_histogram",
		Help:        "histogram LinearBuckets test",
		Buckets:     prometheus.LinearBuckets(1, 2, 20),   // 初始为1,间隔为2,一共20个取值,Buckets会隐式添加 `+Inf` 值作为取值区间的最大值
		// request_time_histogram_bucket{instance="172.20.16.185:8080", job="my_metrics", le="1.0", request_time="request_time"}
		// request_time_histogram_bucket{instance="172.20.16.185:8080", job="my_metrics", le="3.0", request_time="request_time"}
		// ...
		// 会生成如上所示的指标,le: 小于等于
		// 即,比如第一个数据的值,表示为小于等于1.0的个数,此处即为响应时间小于等于1.0的请求的个数
	}, []string{"request_time"})

	// 默认桶
	requestHistogramDef = prometheus.NewHistogramVec(prometheus.HistogramOpts{
		Name:        "request_time_histogram_def_buckets",
		Help:        "histogram DefBuckets test",
		Buckets:     prometheus.DefBuckets,
	}, []string{"request_time"})

	// 指数桶
	requestHistogramExponentialBuckets = prometheus.NewHistogramVec(prometheus.HistogramOpts{
		Name:        "request_time_histogram_exponential_buckets",
		Help:        "histogram ExponentialBuckets test",
		Buckets:     prometheus.ExponentialBuckets(1, 2, 20),    // 初始值为1,指数为2增长,20个取值
	}, []string{"request_time"})
	// 不同的桶根据具体情况而定
)

func init() {
	// Add Go module build info.
	// 也可prometheus.MustRegister(xx, yy)
	prometheus.MustRegister(requestTime)
	prometheus.MustRegister(requestTimes)
	prometheus.MustRegister(requestSummary)
	prometheus.MustRegister(requestHistogram, requestHistogramDef, requestHistogramExponentialBuckets)
}

func main() {
	flag.Parse()
	r := mux.NewRouter()
	r.HandleFunc("/", handler)
	r.Use(metricsMiddleware)

	r.Handle("/metrics", promhttp.HandlerFor(
		prometheus.DefaultGatherer,
		promhttp.HandlerOpts{
			// Opt into OpenMetrics to support exemplars.
			EnableOpenMetrics: true,
		},
	))
	log.Fatal(http.ListenAndServe(*addr, r))
}


func metricsMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now().Unix()
		next.ServeHTTP(w, r)
		end := time.Now().Unix()
		requestTime.WithLabelValues(strings.ToLower(r.Method), r.URL.String(), r.Host).Set(float64(end-start))
		requestTimes.WithLabelValues(strings.ToLower(r.Method), r.URL.String(), r.Host).Add(1)
		requestSummary.WithLabelValues("request_time").Observe(float64(end-start))
		requestHistogram.WithLabelValues("request_time").Observe(float64(end-start))
		requestHistogramDef.WithLabelValues("request_time").Observe(float64(end-start))
		requestHistogramExponentialBuckets.WithLabelValues("request_time").Observe(float64(end-start))
	})
}


func handler(w http.ResponseWriter, r *http.Request) {
	x := rand.Intn(3)
	time.Sleep(time.Duration(x) * time.Second)
	_, _ = w.Write([]byte("handler response"))
	fmt.Println("print handler")
}

// 清除数据,各项数据都会清零
func dataClear()  {
	requestTime.Reset()
	requestTimes.Reset()
	requestHistogram.Reset()
	requestHistogramExponentialBuckets.Reset()
	requestHistogramDef.Reset()
	requestSummary.Reset()
}

参考链接

Go进阶31:Prometheus Client教程 | 🐶❤️🦀

kube-prometheus 监控kubernetes集群 - 流年晕开时光 - 博客园
​​​​​​Metrics类型 · Prometheus中文技术文档

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值