mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-10-31 02:27:19 -04:00 
			
		
		
		
	
		
			Some checks failed
		
		
	
	Lint / lint (macos-14, mac) (push) Waiting to run
				
			Lint / lint (windows-latest, windows) (push) Waiting to run
				
			Tests / test (./cmd/caddy/caddy, ~1.22.3, ubuntu-latest, 0, 1.22, linux) (push) Failing after 2m3s
				
			Tests / test (./cmd/caddy/caddy, ~1.23.0, ubuntu-latest, 0, 1.23, linux) (push) Failing after 1m22s
				
			Tests / test (s390x on IBM Z) (push) Has been skipped
				
			Tests / goreleaser-check (push) Has been skipped
				
			Cross-Build / build (~1.22.3, 1.22, aix) (push) Successful in 1m25s
				
			Cross-Build / build (~1.22.3, 1.22, darwin) (push) Successful in 1m25s
				
			Cross-Build / build (~1.22.3, 1.22, dragonfly) (push) Successful in 1m26s
				
			Cross-Build / build (~1.22.3, 1.22, freebsd) (push) Successful in 1m23s
				
			Cross-Build / build (~1.22.3, 1.22, illumos) (push) Successful in 1m41s
				
			Cross-Build / build (~1.22.3, 1.22, linux) (push) Successful in 1m23s
				
			Cross-Build / build (~1.22.3, 1.22, netbsd) (push) Successful in 1m23s
				
			Cross-Build / build (~1.22.3, 1.22, openbsd) (push) Successful in 1m22s
				
			Cross-Build / build (~1.22.3, 1.22, solaris) (push) Successful in 1m23s
				
			Cross-Build / build (~1.22.3, 1.22, windows) (push) Successful in 1m24s
				
			Cross-Build / build (~1.23.0, 1.23, aix) (push) Successful in 1m15s
				
			Cross-Build / build (~1.23.0, 1.23, darwin) (push) Successful in 1m27s
				
			Cross-Build / build (~1.23.0, 1.23, dragonfly) (push) Successful in 1m27s
				
			Cross-Build / build (~1.23.0, 1.23, freebsd) (push) Successful in 1m15s
				
			Cross-Build / build (~1.23.0, 1.23, illumos) (push) Successful in 1m15s
				
			Cross-Build / build (~1.23.0, 1.23, linux) (push) Successful in 1m14s
				
			Cross-Build / build (~1.23.0, 1.23, netbsd) (push) Successful in 1m16s
				
			Cross-Build / build (~1.23.0, 1.23, openbsd) (push) Successful in 1m15s
				
			Cross-Build / build (~1.23.0, 1.23, solaris) (push) Successful in 1m16s
				
			Cross-Build / build (~1.23.0, 1.23, windows) (push) Successful in 1m42s
				
			Lint / lint (ubuntu-latest, linux) (push) Successful in 2m13s
				
			Lint / govulncheck (push) Successful in 1m33s
				
			Tests / test (./cmd/caddy/caddy, ~1.22.3, macos-14, 0, 1.22, mac) (push) Has been cancelled
				
			Tests / test (./cmd/caddy/caddy, ~1.23.0, macos-14, 0, 1.23, mac) (push) Has been cancelled
				
			Tests / test (./cmd/caddy/caddy.exe, ~1.22.3, windows-latest, True, 1.22, windows) (push) Has been cancelled
				
			Tests / test (./cmd/caddy/caddy.exe, ~1.23.0, windows-latest, True, 1.23, windows) (push) Has been cancelled
				
			Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
		
			
				
	
	
		
			100 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package reverseproxy
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"runtime/debug"
 | |
| 	"sync"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/prometheus/client_golang/prometheus"
 | |
| 	"go.uber.org/zap"
 | |
| 	"go.uber.org/zap/zapcore"
 | |
| 
 | |
| 	"github.com/caddyserver/caddy/v2"
 | |
| )
 | |
| 
 | |
| var reverseProxyMetrics = struct {
 | |
| 	once             sync.Once
 | |
| 	upstreamsHealthy *prometheus.GaugeVec
 | |
| 	logger           *zap.Logger
 | |
| }{}
 | |
| 
 | |
| func initReverseProxyMetrics(handler *Handler, registry *prometheus.Registry) {
 | |
| 	const ns, sub = "caddy", "reverse_proxy"
 | |
| 
 | |
| 	upstreamsLabels := []string{"upstream"}
 | |
| 	reverseProxyMetrics.once.Do(func() {
 | |
| 		reverseProxyMetrics.upstreamsHealthy = prometheus.NewGaugeVec(prometheus.GaugeOpts{
 | |
| 			Namespace: ns,
 | |
| 			Subsystem: sub,
 | |
| 			Name:      "upstreams_healthy",
 | |
| 			Help:      "Health status of reverse proxy upstreams.",
 | |
| 		}, upstreamsLabels)
 | |
| 	})
 | |
| 
 | |
| 	// duplicate registration could happen if multiple sites with reverse proxy are configured; so ignore the error because
 | |
| 	// there's no good way to capture having multiple sites with reverse proxy. If this happens, the metrics will be
 | |
| 	// registered twice, but the second registration will be ignored.
 | |
| 	if err := registry.Register(reverseProxyMetrics.upstreamsHealthy); err != nil &&
 | |
| 		!errors.Is(err, prometheus.AlreadyRegisteredError{
 | |
| 			ExistingCollector: reverseProxyMetrics.upstreamsHealthy,
 | |
| 			NewCollector:      reverseProxyMetrics.upstreamsHealthy,
 | |
| 		}) {
 | |
| 		panic(err)
 | |
| 	}
 | |
| 
 | |
| 	reverseProxyMetrics.logger = handler.logger.Named("reverse_proxy.metrics")
 | |
| }
 | |
| 
 | |
| type metricsUpstreamsHealthyUpdater struct {
 | |
| 	handler *Handler
 | |
| }
 | |
| 
 | |
| func newMetricsUpstreamsHealthyUpdater(handler *Handler, ctx caddy.Context) *metricsUpstreamsHealthyUpdater {
 | |
| 	initReverseProxyMetrics(handler, ctx.GetMetricsRegistry())
 | |
| 	reverseProxyMetrics.upstreamsHealthy.Reset()
 | |
| 
 | |
| 	return &metricsUpstreamsHealthyUpdater{handler}
 | |
| }
 | |
| 
 | |
| func (m *metricsUpstreamsHealthyUpdater) init() {
 | |
| 	go func() {
 | |
| 		defer func() {
 | |
| 			if err := recover(); err != nil {
 | |
| 				if c := reverseProxyMetrics.logger.Check(zapcore.ErrorLevel, "upstreams healthy metrics updater panicked"); c != nil {
 | |
| 					c.Write(
 | |
| 						zap.Any("error", err),
 | |
| 						zap.ByteString("stack", debug.Stack()),
 | |
| 					)
 | |
| 				}
 | |
| 			}
 | |
| 		}()
 | |
| 
 | |
| 		m.update()
 | |
| 
 | |
| 		ticker := time.NewTicker(10 * time.Second)
 | |
| 		for {
 | |
| 			select {
 | |
| 			case <-ticker.C:
 | |
| 				m.update()
 | |
| 			case <-m.handler.ctx.Done():
 | |
| 				ticker.Stop()
 | |
| 				return
 | |
| 			}
 | |
| 		}
 | |
| 	}()
 | |
| }
 | |
| 
 | |
| func (m *metricsUpstreamsHealthyUpdater) update() {
 | |
| 	for _, upstream := range m.handler.Upstreams {
 | |
| 		labels := prometheus.Labels{"upstream": upstream.Dial}
 | |
| 
 | |
| 		gaugeValue := 0.0
 | |
| 		if upstream.Healthy() {
 | |
| 			gaugeValue = 1.0
 | |
| 		}
 | |
| 
 | |
| 		reverseProxyMetrics.upstreamsHealthy.With(labels).Set(gaugeValue)
 | |
| 	}
 | |
| }
 |