github.com/rudderlabs/rudder-go-kit@v0.30.0/profiler/profiler.go (about)

     1  package profiler
     2  
     3  import (
     4  	"context"
     5  	"expvar"
     6  	"fmt"
     7  	"net/http"
     8  	pprof "net/http/pprof"
     9  	"strconv"
    10  	"time"
    11  
    12  	"github.com/rudderlabs/rudder-go-kit/httputil"
    13  )
    14  
    15  // StartServer starts a HTTP server that serves profiling information. The function
    16  // returns when the server is shut down or when the context is canceled.
    17  func StartServer(ctx context.Context, port int) error {
    18  	mux := http.NewServeMux()
    19  	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    20  		r.URL.Path = "/debug/pprof/"
    21  		http.Redirect(w, r, r.URL.String(), http.StatusMovedPermanently)
    22  	})
    23  	mux.HandleFunc("/debug/pprof/", pprof.Index)
    24  	mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
    25  	mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
    26  	mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
    27  	mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
    28  	mux.HandleFunc("/debug/vars", func(w http.ResponseWriter, r *http.Request) {
    29  		first := true
    30  		w.Header().Set("Content-Type", "application/json")
    31  		fmt.Fprintf(w, "{\n")
    32  		expvar.Do(func(kv expvar.KeyValue) {
    33  			if !first {
    34  				fmt.Fprintf(w, ",\n")
    35  			}
    36  			first = false
    37  			fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value)
    38  		})
    39  		fmt.Fprintf(w, "\n}\n")
    40  	})
    41  
    42  	srv := &http.Server{
    43  		Handler: mux,
    44  		Addr:    ":" + strconv.Itoa(port),
    45  	}
    46  	if err := httputil.ListenAndServe(ctx, srv, 3*time.Second); err != nil && ctx.Err() != nil {
    47  		return fmt.Errorf("profiler server: %w", err)
    48  	}
    49  	return nil
    50  }