feat(admin): add profiling options for debugging high memory/CPU usage (#8923)
* feat(admin): add profiling options for debugging high memory/CPU usage Add -debug, -debug.port, -cpuprofile, and -memprofile flags to the admin command, matching the profiling support already available in master, volume, and other server commands. This enables investigation of resource usage issues like #8919. * refactor(admin): move profiling flags into AdminOptions struct Move cpuprofile and memprofile flags from global variables into the AdminOptions struct and init() function for consistency with other flags. * fix(debug): bind pprof server to localhost only and document profiling flags StartDebugServer was binding to all interfaces (0.0.0.0), exposing runtime profiling data to the network. Restrict to 127.0.0.1 since this is a development/debugging tool. Also add a "Debugging and Profiling" section to the admin command's help text documenting the new flags.
This commit is contained in:
@@ -30,6 +30,7 @@ import (
|
|||||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||||
"github.com/seaweedfs/seaweedfs/weed/security"
|
"github.com/seaweedfs/seaweedfs/weed/security"
|
||||||
"github.com/seaweedfs/seaweedfs/weed/util"
|
"github.com/seaweedfs/seaweedfs/weed/util"
|
||||||
|
"github.com/seaweedfs/seaweedfs/weed/util/grace"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -48,6 +49,10 @@ type AdminOptions struct {
|
|||||||
dataDir *string
|
dataDir *string
|
||||||
icebergPort *int
|
icebergPort *int
|
||||||
urlPrefix *string
|
urlPrefix *string
|
||||||
|
debug *bool
|
||||||
|
debugPort *int
|
||||||
|
cpuProfile *string
|
||||||
|
memProfile *string
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -64,6 +69,10 @@ func init() {
|
|||||||
a.readOnlyPassword = cmdAdmin.Flag.String("readOnlyPassword", "", "read-only user password (optional, for view-only access; requires adminPassword to be set)")
|
a.readOnlyPassword = cmdAdmin.Flag.String("readOnlyPassword", "", "read-only user password (optional, for view-only access; requires adminPassword to be set)")
|
||||||
a.icebergPort = cmdAdmin.Flag.Int("iceberg.port", 8181, "Iceberg REST Catalog port (0 to hide in UI)")
|
a.icebergPort = cmdAdmin.Flag.Int("iceberg.port", 8181, "Iceberg REST Catalog port (0 to hide in UI)")
|
||||||
a.urlPrefix = cmdAdmin.Flag.String("urlPrefix", "", "URL path prefix when running behind a reverse proxy under a subdirectory (e.g. /seaweedfs)")
|
a.urlPrefix = cmdAdmin.Flag.String("urlPrefix", "", "URL path prefix when running behind a reverse proxy under a subdirectory (e.g. /seaweedfs)")
|
||||||
|
a.debug = cmdAdmin.Flag.Bool("debug", false, "serves runtime profiling data via pprof on the port specified by -debug.port")
|
||||||
|
a.debugPort = cmdAdmin.Flag.Int("debug.port", 6060, "http port for debugging")
|
||||||
|
a.cpuProfile = cmdAdmin.Flag.String("cpuprofile", "", "cpu profile output file")
|
||||||
|
a.memProfile = cmdAdmin.Flag.String("memprofile", "", "memory profile output file")
|
||||||
}
|
}
|
||||||
|
|
||||||
var cmdAdmin = &Command{
|
var cmdAdmin = &Command{
|
||||||
@@ -140,6 +149,16 @@ var cmdAdmin = &Command{
|
|||||||
- All static assets, API endpoints, and navigation links will use the prefix
|
- All static assets, API endpoints, and navigation links will use the prefix
|
||||||
- Session cookies are scoped to the prefix path
|
- Session cookies are scoped to the prefix path
|
||||||
|
|
||||||
|
Debugging and Profiling:
|
||||||
|
- Use -debug to start a pprof HTTP server for live profiling (localhost only)
|
||||||
|
- Set -debug.port to choose the pprof port (default 6060)
|
||||||
|
- Profiles are accessible at http://127.0.0.1:<debug.port>/debug/pprof/
|
||||||
|
- Use -cpuprofile and -memprofile to write profiles to files on shutdown
|
||||||
|
- WARNING: -debug exposes runtime internals; use only in trusted environments
|
||||||
|
- Examples:
|
||||||
|
weed admin -debug -debug.port=6060 -master="localhost:9333"
|
||||||
|
weed admin -cpuprofile=cpu.prof -memprofile=mem.prof -master="localhost:9333"
|
||||||
|
|
||||||
Configuration File:
|
Configuration File:
|
||||||
- The security.toml file is read from ".", "$HOME/.seaweedfs/",
|
- The security.toml file is read from ".", "$HOME/.seaweedfs/",
|
||||||
"/usr/local/etc/seaweedfs/", or "/etc/seaweedfs/", in that order
|
"/usr/local/etc/seaweedfs/", or "/etc/seaweedfs/", in that order
|
||||||
@@ -149,6 +168,12 @@ var cmdAdmin = &Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runAdmin(cmd *Command, args []string) bool {
|
func runAdmin(cmd *Command, args []string) bool {
|
||||||
|
if *a.debug {
|
||||||
|
grace.StartDebugServer(*a.debugPort)
|
||||||
|
}
|
||||||
|
|
||||||
|
grace.SetupProfiling(*a.cpuProfile, *a.memProfile)
|
||||||
|
|
||||||
// Load security configuration
|
// Load security configuration
|
||||||
util.LoadSecurityConfiguration()
|
util.LoadSecurityConfiguration()
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ import (
|
|||||||
// The server runs in a goroutine and serves pprof endpoints at /debug/pprof/*.
|
// The server runs in a goroutine and serves pprof endpoints at /debug/pprof/*.
|
||||||
func StartDebugServer(debugPort int) {
|
func StartDebugServer(debugPort int) {
|
||||||
go func() {
|
go func() {
|
||||||
addr := fmt.Sprintf(":%d", debugPort)
|
addr := fmt.Sprintf("127.0.0.1:%d", debugPort)
|
||||||
glog.V(0).Infof("Starting debug server for pprof at http://localhost%s/debug/pprof/", addr)
|
glog.V(0).Infof("Starting debug server for pprof at http://%s/debug/pprof/", addr)
|
||||||
if err := http.ListenAndServe(addr, nil); err != nil && err != http.ErrServerClosed {
|
if err := http.ListenAndServe(addr, nil); err != nil && err != http.ErrServerClosed {
|
||||||
glog.Errorf("Failed to start debug server on %s: %v", addr, err)
|
glog.Errorf("Failed to start debug server on %s: %v", addr, err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user