Added pprof bindings

This commit is contained in:
tidwall 2019-02-15 10:51:28 -07:00
parent 3ac8dc2ffb
commit cda701dcc6
2 changed files with 75 additions and 15 deletions

1
.gitignore vendored
View File

@ -2,6 +2,7 @@
tile38-* tile38-*
!cmd/tile38-* !cmd/tile38-*
*.test *.test
*.prof
data*/ data*/
coverage.out coverage.out
packages/ packages/

View File

@ -7,9 +7,11 @@ import (
"io/ioutil" "io/ioutil"
"net" "net"
"net/http" "net/http"
_ "net/http/pprof"
"os" "os"
"os/signal" "os/signal"
"runtime" "runtime"
"runtime/pprof"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -32,6 +34,9 @@ var (
devMode bool devMode bool
quiet bool quiet bool
pidfile string pidfile string
cpuprofile string
memprofile string
pprofport int
) )
// TODO: Set to false in 2.* // TODO: Set to false in 2.*
@ -51,6 +56,7 @@ func (s *hserver) Send(ctx context.Context, in *hservice.MessageRequest) (*hserv
} }
func main() { func main() {
gitsha := " (" + core.GitSHA + ")" gitsha := " (" + core.GitSHA + ")"
if gitsha == " (0000000)" { if gitsha == " (0000000)" {
gitsha = "" gitsha = ""
@ -240,6 +246,9 @@ Developer Options:
flag.BoolVar(&verbose, "v", false, "Enable verbose logging.") flag.BoolVar(&verbose, "v", false, "Enable verbose logging.")
flag.BoolVar(&quiet, "q", false, "Quiet logging. Totally silent.") flag.BoolVar(&quiet, "q", false, "Quiet logging. Totally silent.")
flag.BoolVar(&veryVerbose, "vv", false, "Enable very verbose logging.") flag.BoolVar(&veryVerbose, "vv", false, "Enable very verbose logging.")
flag.IntVar(&pprofport, "pprofport", 0, "pprofport http at port")
flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to `file`")
flag.StringVar(&memprofile, "memprofile", "", "write memory profile to `file`")
flag.Parse() flag.Parse()
var logw io.Writer = os.Stderr var logw io.Writer = os.Stderr
@ -259,43 +268,88 @@ Developer Options:
core.DevMode = devMode core.DevMode = devMode
core.ShowDebugMessages = veryVerbose core.ShowDebugMessages = veryVerbose
hostd := "" // pprof
if host != "" { if cpuprofile != "" {
hostd = "Addr: " + host + ", " log.Debugf("cpuprofile active")
f, err := os.Create(cpuprofile)
if err != nil {
log.Fatal("could not create CPU profile: ", err)
}
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatal("could not start CPU profile: ", err)
}
}
if memprofile != "" {
log.Debug("memprofile active")
} }
var pidferr error
var cleanedup bool var pprofcleanedup bool
var cleanupMu sync.Mutex var pprofcleanupMu sync.Mutex
cleanup := func() { pprofcleanup := func() {
cleanupMu.Lock() pprofcleanupMu.Lock()
defer cleanupMu.Unlock() defer pprofcleanupMu.Unlock()
if cleanedup { if pprofcleanedup {
return
}
// cleanup code
if cpuprofile != "" {
pprof.StopCPUProfile()
}
if memprofile != "" {
f, err := os.Create(memprofile)
if err != nil {
log.Fatal("could not create memory profile: ", err)
}
runtime.GC() // get up-to-date statistics
if err := pprof.WriteHeapProfile(f); err != nil {
log.Fatal("could not write memory profile: ", err)
}
f.Close()
}
pprofcleanedup = true
}
defer pprofcleanup()
if pprofport != 0 {
log.Debugf("pprof http at port %d", pprofport)
go func() {
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", pprofport), nil))
}()
}
// pid file
var pidferr error
var pidcleanedup bool
var pidcleanupMu sync.Mutex
pidcleanup := func() {
pidcleanupMu.Lock()
defer pidcleanupMu.Unlock()
if pidcleanedup {
return return
} }
// cleanup code // cleanup code
if pidfile != "" { if pidfile != "" {
os.Remove(pidfile) os.Remove(pidfile)
} }
cleanedup = true pidcleanedup = true
} }
defer cleanup() defer pidcleanup()
if pidfile != "" { if pidfile != "" {
pidferr := ioutil.WriteFile(pidfile, []byte(fmt.Sprintf("%d\n", os.Getpid())), 0666) pidferr := ioutil.WriteFile(pidfile, []byte(fmt.Sprintf("%d\n", os.Getpid())), 0666)
if pidferr == nil { if pidferr == nil {
} }
} }
// signal watcher
c := make(chan os.Signal, 1) c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
go func() { go func() {
s := <-c s := <-c
log.Warnf("signal: %v", s) log.Warnf("signal: %v", s)
if pidfile != "" { if pidfile != "" {
cleanup() pidcleanup()
} }
pprofcleanup()
switch { switch {
default: default:
os.Exit(-1) os.Exit(-1)
@ -310,6 +364,11 @@ Developer Options:
} }
}() }()
hostd := ""
if host != "" {
hostd = "Addr: " + host + ", "
}
// _____ _ _ ___ ___ // _____ _ _ ___ ___
// |_ _|_| |___|_ | . | // |_ _|_| |___|_ | . |
// | | | | | -_|_ | . | // | | | | | -_|_ | . |