1. Docker deploys Prometheus
1.1 Download prom/prometheus image
docker pull prom/prometheus
1.2 Start the prometheus container
docker run -itd --name=prometheus -p 9090:9090 prom/prometheus
Open the local http://localhost:9090/ to indicate that the startup is successful
1.3 Copy the configuration file of the container
docker cp prometheus:/etc/prometheus/prometheus.yml /Users/chenpeng/share/prometheus/config
1.4 Delete the old container and rebuild the container with the configuration file mounted
docker rm prometheus
docker run -itd --name=prometheus -v /Users/chenpeng/share/prometheus/config/prometheus.yml:/etc/prometheus/prometheus.yml -p 9090:9090 prom/prometheus
2. Docker deploys Grafana
2.1 Download grafana/grafana image
docker pull grafana/grafana
2.2 Start the grafana container
docker run -itd --name=grafana -p 3000:3000 grafana/grafana
Open the webpage localhost:3000, the initial user password is admin, and the first login changes the password to 123456
3. Example of adding monitoring to go code
3.1 Get the prometheus library
go get -u github.com/prometheus/client_golang/prometheus
3.2 go sample code
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"math/rand"
"net/http"
"strconv"
"time"
)
var (
// 随机数
ran = rand.New(rand.NewSource(time.Now().UnixMilli()))
// 请求处理时间指标
httpRequestDurationVec *prometheus.HistogramVec
// 请求个数指标
httpRequestCountVec *prometheus.CounterVec
// DefaultBuckets prometheus buckets in seconds.
DefaultBuckets = []float64{0.1, 0.3, 0.5, 1.0, 3.0, 5.0}
)
func main() {
router := gin.Default()
router.Use(Middleware)
router.GET("/metrics", Metrics())
apiGroup := router.Group("/api")
{
apiGroup.GET("/A", CommonControl)
apiGroup.GET("/B", CommonControl)
apiGroup.GET("/C", CommonControl)
apiGroup.GET("/D", CommonControl)
apiGroup.GET("/E", CommonControl)
}
_ = router.Run(":60000")
}
// 初始化prometheus
func init() {
httpRequestDurationVec = prometheus.NewHistogramVec(prometheus.HistogramOpts{
Name: "http_server_requests_seconds",
Help: "How long it took to process the HTTP request, partitioned by status code, method and HTTP path.",
Buckets: DefaultBuckets,
}, []string{"code", "method", "uri"})
httpRequestCountVec = prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "http_server_requests_count",
Help: "How long it took to process the HTTP request, partitioned by status code, method and HTTP path.",
}, []string{"code", "method"})
prometheus.MustRegister(httpRequestDurationVec, httpRequestCountVec)
}
// 统一处理函数
func CommonControl(ctx *gin.Context) {
time.Sleep(time.Duration(ran.Intn(100)) * time.Millisecond)
ctx.JSON(http.StatusOK, gin.H{
"message": "success",
})
}
// 中间件记录请求指标
func Middleware(ctx *gin.Context) {
start := time.Now()
ctx.Next()
// 返回状态码
statusCode := strconv.Itoa(ctx.Writer.Status())
// 标签
labels := []string{statusCode, ctx.Request.Method, ctx.Request.URL.Path}
// 请求处理时间
duration := float64(time.Since(start).Nanoseconds()) / 1000000000
// 添加指标
httpRequestDurationVec.WithLabelValues(labels...).Observe(duration)
httpRequestCountVec.WithLabelValues(statusCode, ctx.Request.Method).Inc()
fmt.Printf("code: %d | method: %s | path: %s | duration: %f\n ", statusCode, ctx.Request.Method, ctx.Request.URL.Path, duration)
}
// http metrics 指标页面,配置给prometheus
func Metrics() gin.HandlerFunc {
h := promhttp.Handler()
return func(c *gin.Context) {
h.ServeHTTP(c.Writer, c.Request)
}
}
3.3 Visit the metrics page
http://localhost:60000/metrics
3.4 Modify the prometheus configuration file
Modify the configuration file just mounted by docker. My path here is /Users/chenpeng/share/prometheus/config/prometheus.yml
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: "prometheus"
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ["localhost:9090"]
- job_name: "gopractice"
static_configs:
- targets: ["192.168.50.43:60000"] #这里要填本地ip,容器里localhost访问不到
Restart the prometheus docker container
docker restart prometheus
Visit http://localhost:9090/targets?search=
You can see that prometheus has included the metrics of the project
3.5 configure grafana
Enter grafana and select datasource
Enter DATA SOURCES and select prometheus
Configure the prometheus address, also use the local intranet ip address, click save&test
Add a chart and set the corresponding function
4. Write docker-compose.yml to start
4.1 docker-compose.yml file
version: '3.5'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus-compose
restart: no
ports:
- "9090:9090"
volumes:
- "/Users/chenpeng/software/dockercompose/prometheus/config/prometheus.yml:/etc/prometheus/prometheus.yml"
grafana:
image: grafana/grafana:latest
container_name: grafana-compose
restart: no
ports:
- "3000:3000"
4.2 Start docker-compose
docker-compose up -d