Skip to content

Commit

Permalink
reverseproxy: ignore duplicate collector registration error (#6820)
Browse files Browse the repository at this point in the history
Signed-off-by: Mohammed Al Sahaf <[email protected]>
  • Loading branch information
mohammed90 authored Feb 4, 2025
1 parent 9996d6a commit 9283770
Showing 1 changed file with 23 additions and 13 deletions.
36 changes: 23 additions & 13 deletions modules/caddyhttp/reverseproxy/metrics.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
package reverseproxy

import (
"errors"
"runtime/debug"
"sync"
"time"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"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
}{}
Expand All @@ -21,12 +23,25 @@ func initReverseProxyMetrics(handler *Handler, registry *prometheus.Registry) {
const ns, sub = "caddy", "reverse_proxy"

upstreamsLabels := []string{"upstream"}
reverseProxyMetrics.upstreamsHealthy = promauto.With(registry).NewGaugeVec(prometheus.GaugeOpts{
Namespace: ns,
Subsystem: sub,
Name: "upstreams_healthy",
Help: "Health status of reverse proxy upstreams.",
}, upstreamsLabels)
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")
}
Expand All @@ -35,13 +50,8 @@ type metricsUpstreamsHealthyUpdater struct {
handler *Handler
}

const upstreamsHealthyMetrics caddy.CtxKey = "reverse_proxy_upstreams_healthy"

func newMetricsUpstreamsHealthyUpdater(handler *Handler, ctx caddy.Context) *metricsUpstreamsHealthyUpdater {
if set := ctx.Value(upstreamsHealthyMetrics); set == nil {
initReverseProxyMetrics(handler, ctx.GetMetricsRegistry())
ctx = ctx.WithValue(upstreamsHealthyMetrics, true)
}
initReverseProxyMetrics(handler, ctx.GetMetricsRegistry())
reverseProxyMetrics.upstreamsHealthy.Reset()

return &metricsUpstreamsHealthyUpdater{handler}
Expand Down

0 comments on commit 9283770

Please sign in to comment.