github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/debug_http.go (about)

     1  package box
     2  
     3  import (
     4  	"net/http"
     5  	"net/http/pprof"
     6  	"runtime"
     7  	"runtime/debug"
     8  
     9  	"github.com/inazumav/sing-box/common/badjson"
    10  	"github.com/inazumav/sing-box/common/json"
    11  	"github.com/inazumav/sing-box/log"
    12  	"github.com/inazumav/sing-box/option"
    13  	E "github.com/sagernet/sing/common/exceptions"
    14  
    15  	"github.com/dustin/go-humanize"
    16  	"github.com/go-chi/chi/v5"
    17  )
    18  
    19  var debugHTTPServer *http.Server
    20  
    21  func applyDebugListenOption(options option.DebugOptions) {
    22  	if debugHTTPServer != nil {
    23  		debugHTTPServer.Close()
    24  		debugHTTPServer = nil
    25  	}
    26  	if options.Listen == "" {
    27  		return
    28  	}
    29  	r := chi.NewMux()
    30  	r.Route("/debug", func(r chi.Router) {
    31  		r.Get("/gc", func(writer http.ResponseWriter, request *http.Request) {
    32  			writer.WriteHeader(http.StatusNoContent)
    33  			go debug.FreeOSMemory()
    34  		})
    35  		r.Get("/memory", func(writer http.ResponseWriter, request *http.Request) {
    36  			var memStats runtime.MemStats
    37  			runtime.ReadMemStats(&memStats)
    38  
    39  			var memObject badjson.JSONObject
    40  			memObject.Put("heap", humanize.IBytes(memStats.HeapInuse))
    41  			memObject.Put("stack", humanize.IBytes(memStats.StackInuse))
    42  			memObject.Put("idle", humanize.IBytes(memStats.HeapIdle-memStats.HeapReleased))
    43  			memObject.Put("goroutines", runtime.NumGoroutine())
    44  			memObject.Put("rss", rusageMaxRSS())
    45  
    46  			encoder := json.NewEncoder(writer)
    47  			encoder.SetIndent("", "  ")
    48  			encoder.Encode(memObject)
    49  		})
    50  		r.HandleFunc("/pprof", pprof.Index)
    51  		r.HandleFunc("/pprof/*", pprof.Index)
    52  		r.HandleFunc("/pprof/cmdline", pprof.Cmdline)
    53  		r.HandleFunc("/pprof/profile", pprof.Profile)
    54  		r.HandleFunc("/pprof/symbol", pprof.Symbol)
    55  		r.HandleFunc("/pprof/trace", pprof.Trace)
    56  	})
    57  	debugHTTPServer = &http.Server{
    58  		Addr:    options.Listen,
    59  		Handler: r,
    60  	}
    61  	go func() {
    62  		err := debugHTTPServer.ListenAndServe()
    63  		if err != nil && !E.IsClosed(err) {
    64  			log.Error(E.Cause(err, "serve debug HTTP server"))
    65  		}
    66  	}()
    67  }