Prometheus 提供各种语言的 Client Libraries 来开发 instrumentation metrics 的采集器。这些 lib 库,默认提供如 CPU 使用率、垃圾回收统计信息。
介绍
各种 client 库源代码
实现方式:
- counter: Inc/Dec
- gauge: Set
- histogram(直方图)/summary(百分位): observe
- Collector,实现两个接口
指标采集方式:
- 周期/定时任务触发
- 业务请求时触发,http 请求、异步任务等
- metrics 请求时触发,适用于实时获取指标
认证需自行实现:
示例
python prometheus_client
pip install prometheus-client
# https://stackoverflow.com/questions/59924566/export-prometheus-metrics-using-python-code
import prometheus_client as prom
import random
import time
req_summary = prom.Summary('python_my_req_example', 'Time spent processing a request')
@req_summary.time()
def process_request(t):
time.sleep(t)
if __name__ == '__main__':
counter = prom.Counter('python_my_counter', 'This is my counter')
gauge = prom.Gauge('python_my_gauge', 'This is my gauge')
histogram = prom.Histogram('python_my_histogram', 'This is my histogram')
summary = prom.Summary('python_my_summary', 'This is my summary')
prom.start_http_server(8080)
while True:
counter.inc(random.random())
gauge.set(random.random() * 15 - 5)
histogram.observe(random.random() * 10)
summary.observe(random.random() * 10)
process_request(random.random() * 5)
time.sleep(1)
# https://prometheus.github.io/client_python/getting-started/three-step-demo/
from prometheus_client import start_http_server, Summary
import random
import time
# Create a metric to track time spent and requests made.
REQUEST_TIME = Summary('request_processing_seconds', 'Time spent processing request')
# Decorate function with metric.
@REQUEST_TIME.time()
def process_request(t):
"""A dummy function that takes some time."""
time.sleep(t)
if __name__ == '__main__':
# Start up the server to expose the metrics.
start_http_server(8000)
# Generate some requests.
while True:
process_request(random.random())
# https://prometheus.github.io/client_python/exporting/http/flask/
from flask import Flask
from werkzeug.middleware.dispatcher import DispatcherMiddleware
from prometheus_client import make_wsgi_app
# Create my app
app = Flask(__name__)
# Add prometheus wsgi middleware to route /metrics requests
app.wsgi_app = DispatcherMiddleware(app.wsgi_app, {
'/metrics': make_wsgi_app()
})
基础使用
package main
import (
"fmt"
"log"
"math/rand"
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var diskinfo = []string{"mount"}
var (
// gauge
cpuTemp = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "cpu_temperature_celsius",
Help: "Current temperature of the CPU.",
})
cpuCount = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "cpu_count",
Help: "cout count.",
ConstLabels: prometheus.Labels{
"key1": "val1",
},
})
disk = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "disk",
Help: "disk size info.",
}, diskinfo)
// counter
requestTotal = prometheus.NewCounter(prometheus.CounterOpts{
Name: "request_total",
Help: "http request total",
})
hdFailures = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "hd_errors_total",
Help: "Number of hard-disk errors.",
},
[]string{"device"},
)
// histogram
urlRequestTime = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "url_request_time",
Help: "url request time.",
Buckets: prometheus.LinearBuckets(0, 3, 5),
}, []string{"url"})
// summary
requestSummary = prometheus.NewSummaryVec(
prometheus.SummaryOpts{
Name: "request_time_summary",
Help: "request time summary",
Objectives: map[float64]float64{0.2: 0.1, 0.5: 0.001, 0.99: 0.0001},
}, []string{"url"})
)
func init() {
// Metrics have to be registered to be exposed:
prometheus.MustRegister(cpuCount)
prometheus.MustRegister(disk)
prometheus.MustRegister(cpuTemp)
prometheus.MustRegister(requestTotal)
prometheus.MustRegister(hdFailures)
prometheus.MustRegister(urlRequestTime)
prometheus.MustRegister(requestSummary)
}
func main() {
cpuCount.Set(4)
disk.WithLabelValues("/dev/sda").Set(10)
disk.WithLabelValues("/dev/sdb").Set(10)
cpuTemp.Set(65.3)
//requestTotal.Inc()
hdFailures.With(prometheus.Labels{"device": "/dev/sda"}).Inc()
// histogram
//urlRequestTime.WithLabelValues("/url").Observe(10)
//urlRequestTime.WithLabelValues("/url").Observe(5)
//requestSummary.WithLabelValues("/url").Observe(10)
//requestSummary.WithLabelValues("/url").Observe(5)
// 修改值
//时间触发:磁盘使用、CPU使用、内存使用
go func() {
// for range time.Tick(time.Second) {}
ticker := time.NewTicker(3 * time.Second)
for {
disk.WithLabelValues("/dev/sda").Set(rand.Float64())
disk.WithLabelValues("/dev/sdb").Set(rand.Float64())
<-ticker.C
}
}()
// 事件触发,如 HTTP 请求
http.HandleFunc("/url/", func(writer http.ResponseWriter, request *http.Request) {
requestTotal.Inc()
urlRequestTime.WithLabelValues("/url").Observe(rand.Float64())
requestSummary.WithLabelValues("/url").Observe(rand.Float64())
writer.Write([]byte("done."))
})
// 在访问metrics时触发,只有这两种
//prometheus.NewGaugeFunc()
//prometheus.NewCounterFunc()
fcall := prometheus.NewCounterFunc(prometheus.CounterOpts{
Name: "abc",
Help: "abc",
}, func() float64 {
fmt.Println("call")
return rand.Float64()
})
prometheus.MustRegister(fcall)
// The Handler function provides a default handler to expose metrics
// via an HTTP server. "/metrics" is the usual endpoint for that.
http.Handle("/metrics", promhttp.Handler())
log.Fatal(http.ListenAndServe(":8080", nil))
}
mysql-exporter 示例
https://github.com/xiexianbin/mysql-exporter
应用监控
beego 实现 web.handler("/metrics", promhttp.Handler())
,参考