internal: skip tracing for go healthcheck and metrics endpoints
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
74ce9cc6fd
commit
bdf76bb4b7
|
@ -85,8 +85,9 @@ def sentry_init(**sentry_init_kwargs):
|
||||||
|
|
||||||
def traces_sampler(sampling_context: dict) -> float:
|
def traces_sampler(sampling_context: dict) -> float:
|
||||||
"""Custom sampler to ignore certain routes"""
|
"""Custom sampler to ignore certain routes"""
|
||||||
|
path = sampling_context.get("asgi_scope", {}).get("path", "")
|
||||||
# Ignore all healthcheck routes
|
# Ignore all healthcheck routes
|
||||||
if sampling_context.get("asgi_scope", {}).get("path", "").startswith("/-/health/"):
|
if path.startswith("/-/health") or path.startswith("/-/metrics"):
|
||||||
return 0
|
return 0
|
||||||
return float(CONFIG.y("error_reporting.sample_rate", 0.5))
|
return float(CONFIG.y("error_reporting.sample_rate", 0.5))
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ for _authentik_app in get_apps():
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns += [
|
urlpatterns += [
|
||||||
path("metrics/", MetricsView.as_view(), name="metrics"),
|
path("-/metrics/", MetricsView.as_view(), name="metrics"),
|
||||||
path("-/health/live/", LiveView.as_view(), name="health-live"),
|
path("-/health/live/", LiveView.as_view(), name="health-live"),
|
||||||
path("-/health/ready/", ReadyView.as_view(), name="health-ready"),
|
path("-/health/ready/", ReadyView.as_view(), name="health-ready"),
|
||||||
]
|
]
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"goauthentik.io/internal/gounicorn"
|
"goauthentik.io/internal/gounicorn"
|
||||||
"goauthentik.io/internal/outpost/ak"
|
"goauthentik.io/internal/outpost/ak"
|
||||||
"goauthentik.io/internal/outpost/proxyv2"
|
"goauthentik.io/internal/outpost/proxyv2"
|
||||||
|
sentryutils "goauthentik.io/internal/utils/sentry"
|
||||||
"goauthentik.io/internal/web"
|
"goauthentik.io/internal/web"
|
||||||
"goauthentik.io/internal/web/tenant_tls"
|
"goauthentik.io/internal/web/tenant_tls"
|
||||||
)
|
)
|
||||||
|
@ -51,7 +52,7 @@ func main() {
|
||||||
err := sentry.Init(sentry.ClientOptions{
|
err := sentry.Init(sentry.ClientOptions{
|
||||||
Dsn: config.G.ErrorReporting.DSN,
|
Dsn: config.G.ErrorReporting.DSN,
|
||||||
AttachStacktrace: true,
|
AttachStacktrace: true,
|
||||||
TracesSampleRate: config.G.ErrorReporting.SampleRate,
|
TracesSampler: sentryutils.SamplerFunc(config.G.ErrorReporting.SampleRate),
|
||||||
Release: fmt.Sprintf("authentik@%s", constants.VERSION),
|
Release: fmt.Sprintf("authentik@%s", constants.VERSION),
|
||||||
Environment: config.G.ErrorReporting.Environment,
|
Environment: config.G.ErrorReporting.Environment,
|
||||||
IgnoreErrors: []string{
|
IgnoreErrors: []string{
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"goauthentik.io/api/v3"
|
"goauthentik.io/api/v3"
|
||||||
"goauthentik.io/internal/constants"
|
"goauthentik.io/internal/constants"
|
||||||
|
sentryutils "goauthentik.io/internal/utils/sentry"
|
||||||
)
|
)
|
||||||
|
|
||||||
var initialSetup = false
|
var initialSetup = false
|
||||||
|
@ -47,10 +48,10 @@ func doGlobalSetup(outpost api.Outpost, globalConfig *api.Config) {
|
||||||
l.WithField("env", globalConfig.ErrorReporting.Environment).Debug("Error reporting enabled")
|
l.WithField("env", globalConfig.ErrorReporting.Environment).Debug("Error reporting enabled")
|
||||||
}
|
}
|
||||||
err := sentry.Init(sentry.ClientOptions{
|
err := sentry.Init(sentry.ClientOptions{
|
||||||
Dsn: dsn,
|
Dsn: dsn,
|
||||||
Environment: globalConfig.ErrorReporting.Environment,
|
Environment: globalConfig.ErrorReporting.Environment,
|
||||||
TracesSampleRate: float64(globalConfig.ErrorReporting.TracesSampleRate),
|
TracesSampler: sentryutils.SamplerFunc(float64(globalConfig.ErrorReporting.TracesSampleRate)),
|
||||||
Release: fmt.Sprintf("authentik@%s", constants.VERSION),
|
Release: fmt.Sprintf("authentik@%s", constants.VERSION),
|
||||||
IgnoreErrors: []string{
|
IgnoreErrors: []string{
|
||||||
http.ErrAbortHandler.Error(),
|
http.ErrAbortHandler.Error(),
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
"goauthentik.io/internal/utils/sentry"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
@ -25,6 +26,7 @@ var (
|
||||||
func RunServer() {
|
func RunServer() {
|
||||||
m := mux.NewRouter()
|
m := mux.NewRouter()
|
||||||
l := log.WithField("logger", "authentik.outpost.metrics")
|
l := log.WithField("logger", "authentik.outpost.metrics")
|
||||||
|
m.Use(sentry.SentryNoSampleMiddleware)
|
||||||
m.HandleFunc("/outpost.goauthentik.io/ping", func(rw http.ResponseWriter, r *http.Request) {
|
m.HandleFunc("/outpost.goauthentik.io/ping", func(rw http.ResponseWriter, r *http.Request) {
|
||||||
rw.WriteHeader(204)
|
rw.WriteHeader(204)
|
||||||
})
|
})
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"goauthentik.io/api/v3"
|
"goauthentik.io/api/v3"
|
||||||
"goauthentik.io/internal/outpost/proxyv2/application"
|
"goauthentik.io/internal/outpost/proxyv2/application"
|
||||||
"goauthentik.io/internal/outpost/proxyv2/metrics"
|
"goauthentik.io/internal/outpost/proxyv2/metrics"
|
||||||
|
sentryutils "goauthentik.io/internal/utils/sentry"
|
||||||
"goauthentik.io/internal/utils/web"
|
"goauthentik.io/internal/utils/web"
|
||||||
staticWeb "goauthentik.io/web"
|
staticWeb "goauthentik.io/web"
|
||||||
)
|
)
|
||||||
|
@ -89,7 +90,7 @@ func (ps *ProxyServer) Handle(rw http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(r.URL.Path, "/outpost.goauthentik.io/ping") {
|
if strings.HasPrefix(r.URL.Path, "/outpost.goauthentik.io/ping") {
|
||||||
ps.HandlePing(rw, r)
|
sentryutils.SentryNoSample(ps.HandlePing)(rw, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
a, host := ps.lookupApp(r)
|
a, host := ps.lookupApp(r)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
"goauthentik.io/internal/utils/sentry"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
@ -25,6 +26,7 @@ var (
|
||||||
func RunServer() {
|
func RunServer() {
|
||||||
m := mux.NewRouter()
|
m := mux.NewRouter()
|
||||||
l := log.WithField("logger", "authentik.outpost.metrics")
|
l := log.WithField("logger", "authentik.outpost.metrics")
|
||||||
|
m.Use(sentry.SentryNoSampleMiddleware)
|
||||||
m.HandleFunc("/outpost.goauthentik.io/ping", func(rw http.ResponseWriter, r *http.Request) {
|
m.HandleFunc("/outpost.goauthentik.io/ping", func(rw http.ResponseWriter, r *http.Request) {
|
||||||
rw.WriteHeader(204)
|
rw.WriteHeader(204)
|
||||||
})
|
})
|
||||||
|
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"goauthentik.io/internal/outpost/ak"
|
"goauthentik.io/internal/outpost/ak"
|
||||||
"goauthentik.io/internal/outpost/proxyv2/application"
|
"goauthentik.io/internal/outpost/proxyv2/application"
|
||||||
"goauthentik.io/internal/outpost/proxyv2/metrics"
|
"goauthentik.io/internal/outpost/proxyv2/metrics"
|
||||||
|
sentryutils "goauthentik.io/internal/utils/sentry"
|
||||||
"goauthentik.io/internal/utils/web"
|
"goauthentik.io/internal/utils/web"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -65,7 +66,7 @@ func NewProxyServer(ac *ak.APIController, portOffset int) *ProxyServer {
|
||||||
defaultCert: defaultCert,
|
defaultCert: defaultCert,
|
||||||
}
|
}
|
||||||
globalMux.PathPrefix("/outpost.goauthentik.io/static").HandlerFunc(s.HandleStatic)
|
globalMux.PathPrefix("/outpost.goauthentik.io/static").HandlerFunc(s.HandleStatic)
|
||||||
globalMux.Path("/outpost.goauthentik.io/ping").HandlerFunc(s.HandlePing)
|
globalMux.Path("/outpost.goauthentik.io/ping").HandlerFunc(sentryutils.SentryNoSample(s.HandlePing))
|
||||||
rootMux.PathPrefix("/").HandlerFunc(s.Handle)
|
rootMux.PathPrefix("/").HandlerFunc(s.Handle)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
34
internal/utils/sentry/sentry.go
Normal file
34
internal/utils/sentry/sentry.go
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package sentry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/getsentry/sentry-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
type contextSentryNoSample struct{}
|
||||||
|
|
||||||
|
func SentryNoSample(handler func(rw http.ResponseWriter, r *http.Request)) func(http.ResponseWriter, *http.Request) {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := context.WithValue(r.Context(), contextSentryNoSample{}, true)
|
||||||
|
handler(w, r.WithContext(ctx))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SentryNoSampleMiddleware(h http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := context.WithValue(r.Context(), contextSentryNoSample{}, true)
|
||||||
|
h.ServeHTTP(rw, r.WithContext(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func SamplerFunc(defaultRate float64) sentry.TracesSamplerFunc {
|
||||||
|
return sentry.TracesSamplerFunc(func(ctx sentry.SamplingContext) sentry.Sampled {
|
||||||
|
data, ok := ctx.Span.Context().Value(contextSentryNoSample{}).(bool)
|
||||||
|
if data && ok {
|
||||||
|
return sentry.SampledFalse
|
||||||
|
}
|
||||||
|
return sentry.UniformTracesSampler(defaultRate).Sample(ctx)
|
||||||
|
})
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"goauthentik.io/internal/config"
|
"goauthentik.io/internal/config"
|
||||||
|
"goauthentik.io/internal/utils/sentry"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -22,6 +23,7 @@ var (
|
||||||
func RunMetricsServer() {
|
func RunMetricsServer() {
|
||||||
m := mux.NewRouter()
|
m := mux.NewRouter()
|
||||||
l := log.WithField("logger", "authentik.router.metrics")
|
l := log.WithField("logger", "authentik.router.metrics")
|
||||||
|
m.Use(sentry.SentryNoSampleMiddleware)
|
||||||
m.Path("/metrics").HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
m.Path("/metrics").HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
promhttp.InstrumentMetricHandler(
|
promhttp.InstrumentMetricHandler(
|
||||||
prometheus.DefaultRegisterer, promhttp.HandlerFor(prometheus.DefaultGatherer, promhttp.HandlerOpts{
|
prometheus.DefaultRegisterer, promhttp.HandlerFor(prometheus.DefaultGatherer, promhttp.HandlerOpts{
|
||||||
|
@ -30,7 +32,7 @@ func RunMetricsServer() {
|
||||||
).ServeHTTP(rw, r)
|
).ServeHTTP(rw, r)
|
||||||
|
|
||||||
// Get upstream metrics
|
// Get upstream metrics
|
||||||
re, err := http.NewRequest("GET", "http://localhost:8000/metrics/", nil)
|
re, err := http.NewRequest("GET", "http://localhost:8000/-/metrics/", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.WithError(err).Warning("failed to get upstream metrics")
|
l.WithError(err).Warning("failed to get upstream metrics")
|
||||||
return
|
return
|
||||||
|
|
Reference in a new issue