@marcel91200 / caddy Mirror · read-only / commits / 0c57facc
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 13, 14:15 UTC

reverseproxy: Add upstreams healthy metrics (#4935)

Dávid Szabó committed Aug 27, 2022 at 20:30 UTC 0c57facc67910a6b0994763ac8e6e55e693f20e4
2 files changed +84
modules/caddyhttp/reverseproxy/metrics.go new
+81
@@ -0,0 +1,81 @@
1 +package reverseproxy
2 +
3 +import (
4 + "runtime/debug"
5 + "sync"
6 + "time"
7 +
8 + "github.com/prometheus/client_golang/prometheus"
9 + "github.com/prometheus/client_golang/prometheus/promauto"
10 + "go.uber.org/zap"
11 +)
12 +
13 +var reverseProxyMetrics = struct {
14 + init sync.Once
15 + upstreamsHealthy *prometheus.GaugeVec
16 + logger *zap.Logger
17 +}{}
18 +
19 +func initReverseProxyMetrics(handler *Handler) {
20 + const ns, sub = "caddy", "reverse_proxy"
21 +
22 + upstreamsLabels := []string{"upstream"}
23 + reverseProxyMetrics.upstreamsHealthy = promauto.NewGaugeVec(prometheus.GaugeOpts{
24 + Namespace: ns,
25 + Subsystem: sub,
26 + Name: "upstreams_healthy",
27 + Help: "Health status of reverse proxy upstreams.",
28 + }, upstreamsLabels)
29 +
30 + reverseProxyMetrics.logger = handler.logger.Named("reverse_proxy.metrics")
31 +}
32 +
33 +type metricsUpstreamsHealthyUpdater struct {
34 + handler *Handler
35 +}
36 +
37 +func newMetricsUpstreamsHealthyUpdater(handler *Handler) *metricsUpstreamsHealthyUpdater {
38 + reverseProxyMetrics.init.Do(func() {
39 + initReverseProxyMetrics(handler)
40 + })
41 +
42 + return &metricsUpstreamsHealthyUpdater{handler}
43 +}
44 +
45 +func (m *metricsUpstreamsHealthyUpdater) Init() {
46 + go func() {
47 + defer func() {
48 + if err := recover(); err != nil {
49 + reverseProxyMetrics.logger.Error("upstreams healthy metrics updater panicked",
50 + zap.Any("error", err),
51 + zap.ByteString("stack", debug.Stack()))
52 + }
53 + }()
54 +
55 + m.update()
56 +
57 + ticker := time.NewTicker(10 * time.Second)
58 + for {
59 + select {
60 + case <-ticker.C:
61 + m.update()
62 + case <-m.handler.ctx.Done():
63 + ticker.Stop()
64 + return
65 + }
66 + }
67 + }()
68 +}
69 +
70 +func (m *metricsUpstreamsHealthyUpdater) update() {
71 + for _, upstream := range m.handler.Upstreams {
72 + labels := prometheus.Labels{"upstream": upstream.Dial}
73 +
74 + gaugeValue := 0.0
75 + if upstream.Healthy() {
76 + gaugeValue = 1.0
77 + }
78 +
79 + reverseProxyMetrics.upstreamsHealthy.With(labels).Set(gaugeValue)
80 + }
81 +}
modules/caddyhttp/reverseproxy/reverseproxy.go
+3
@@ -392,6 +392,9 @@ func (h *Handler) Provision(ctx caddy.Context) error {
392 }
393 }
394
395 + upstreamHealthyUpdater := newMetricsUpstreamsHealthyUpdater(h)
396 + upstreamHealthyUpdater.Init()
397 +
398 return nil
399 }
400