Files
sing-box-extended-mirror/debug_http.go
T

77 lines
2.2 KiB
Go
Raw Normal View History

2023-04-22 15:58:25 +08:00
package box
import (
2026-07-15 20:50:36 +08:00
"net"
2023-04-22 15:58:25 +08:00
"net/http"
"net/http/pprof"
"runtime"
"runtime/debug"
2023-12-27 17:33:07 +08:00
"strings"
2023-04-22 15:58:25 +08:00
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
2025-04-28 23:12:39 +08:00
"github.com/sagernet/sing/common/byteformats"
2023-04-22 15:58:25 +08:00
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/json"
"github.com/sagernet/sing/common/json/badjson"
2023-04-22 15:58:25 +08:00
"github.com/go-chi/chi/v5"
)
2026-07-15 20:50:36 +08:00
func startDebugHTTPServer(options option.DebugOptions) (*http.Server, error) {
2023-04-22 15:58:25 +08:00
if options.Listen == "" {
2026-07-15 20:50:36 +08:00
return nil, nil
2023-04-22 15:58:25 +08:00
}
r := chi.NewMux()
r.Route("/debug", func(r chi.Router) {
r.Get("/gc", func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusNoContent)
go debug.FreeOSMemory()
})
r.Get("/memory", func(writer http.ResponseWriter, request *http.Request) {
var memStats runtime.MemStats
runtime.ReadMemStats(&memStats)
var memObject badjson.JSONObject
2025-04-28 23:12:39 +08:00
memObject.Put("heap", byteformats.FormatMemoryBytes(memStats.HeapInuse))
memObject.Put("stack", byteformats.FormatMemoryBytes(memStats.StackInuse))
memObject.Put("idle", byteformats.FormatMemoryBytes(memStats.HeapIdle-memStats.HeapReleased))
2023-04-22 15:58:25 +08:00
memObject.Put("goroutines", runtime.NumGoroutine())
memObject.Put("rss", rusageMaxRSS())
encoder := json.NewEncoder(writer)
encoder.SetIndent("", " ")
2024-11-20 10:52:26 +08:00
encoder.Encode(&memObject)
2023-04-22 15:58:25 +08:00
})
2023-12-27 17:33:07 +08:00
r.Route("/pprof", func(r chi.Router) {
r.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
if !strings.HasSuffix(request.URL.Path, "/") {
http.Redirect(writer, request, request.URL.Path+"/", http.StatusMovedPermanently)
} else {
pprof.Index(writer, request)
}
})
r.HandleFunc("/*", pprof.Index)
r.HandleFunc("/cmdline", pprof.Cmdline)
r.HandleFunc("/profile", pprof.Profile)
r.HandleFunc("/symbol", pprof.Symbol)
r.HandleFunc("/trace", pprof.Trace)
})
2023-04-22 15:58:25 +08:00
})
2026-07-15 20:50:36 +08:00
server := &http.Server{
2023-04-22 15:58:25 +08:00
Addr: options.Listen,
Handler: r,
}
2026-07-15 20:50:36 +08:00
listener, err := net.Listen("tcp", options.Listen)
if err != nil {
return nil, E.Cause(err, "listen debug HTTP server")
}
2023-04-22 15:58:25 +08:00
go func() {
2026-07-15 20:50:36 +08:00
err := server.Serve(listener)
2023-04-22 15:58:25 +08:00
if err != nil && !E.IsClosed(err) {
log.Error(E.Cause(err, "serve debug HTTP server"))
}
}()
2026-07-15 20:50:36 +08:00
return server, nil
2023-04-22 15:58:25 +08:00
}