88 lines
2.0 KiB
Go
88 lines
2.0 KiB
Go
package observability
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"time"
|
|
|
|
"net/http"
|
|
"net/http/pprof"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/supabase/auth/internal/conf"
|
|
)
|
|
|
|
func ConfigureProfiler(ctx context.Context, pc *conf.ProfilerConfig) error {
|
|
if !pc.Enabled {
|
|
return nil
|
|
}
|
|
addr := net.JoinHostPort(pc.Host, pc.Port)
|
|
baseContext, cancel := context.WithCancel(context.Background())
|
|
cleanupWaitGroup.Add(1)
|
|
go func() {
|
|
server := &http.Server{
|
|
Addr: addr,
|
|
Handler: &ProfilerHandler{},
|
|
BaseContext: func(net.Listener) context.Context {
|
|
return baseContext
|
|
},
|
|
ReadHeaderTimeout: 2 * time.Second,
|
|
}
|
|
|
|
go func() {
|
|
defer cleanupWaitGroup.Done()
|
|
<-ctx.Done()
|
|
|
|
cancel() // close baseContext
|
|
|
|
shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer shutdownCancel()
|
|
|
|
if err := server.Shutdown(shutdownCtx); err != nil {
|
|
logrus.WithError(err).Errorf("profiler server (%s) failed to gracefully shut down", addr)
|
|
}
|
|
}()
|
|
|
|
logrus.Infof("Profiler is listening on %s", addr)
|
|
|
|
if err := server.ListenAndServe(); err != nil {
|
|
logrus.WithError(err).Errorf("profiler server (%s) shut down", addr)
|
|
} else {
|
|
logrus.Info("profiler shut down")
|
|
}
|
|
}()
|
|
|
|
return nil
|
|
}
|
|
|
|
type ProfilerHandler struct{}
|
|
|
|
func (p *ProfilerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
switch r.URL.Path {
|
|
case "/debug/pprof/":
|
|
pprof.Index(w, r)
|
|
case "/debug/pprof/cmdline":
|
|
pprof.Cmdline(w, r)
|
|
case "/debug/pprof/profile":
|
|
pprof.Profile(w, r)
|
|
case "/debug/pprof/symbol":
|
|
pprof.Symbol(w, r)
|
|
case "/debug/pprof/trace":
|
|
pprof.Trace(w, r)
|
|
case "/debug/pprof/goroutine":
|
|
pprof.Handler("goroutine").ServeHTTP(w, r)
|
|
case "/debug/pprof/heap":
|
|
pprof.Handler("heap").ServeHTTP(w, r)
|
|
case "/debug/pprof/allocs":
|
|
pprof.Handler("allocs").ServeHTTP(w, r)
|
|
case "/debug/pprof/threadcreate":
|
|
pprof.Handler("threadcreate").ServeHTTP(w, r)
|
|
case "/debug/pprof/block":
|
|
pprof.Handler("block").ServeHTTP(w, r)
|
|
case "/debug/pprof/mutex":
|
|
pprof.Handler("mutex").ServeHTTP(w, r)
|
|
default:
|
|
http.NotFound(w, r)
|
|
}
|
|
}
|