Added pprof flags

This commit is contained in:
tidwall 2019-03-14 09:24:18 -07:00
parent 14db57cda3
commit 87f57b0cd9
1 changed files with 87 additions and 14 deletions

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,17 +34,35 @@ 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.*
var httpTransport = true var httpTransport = true
////////////////////////////////////////////////////////////////////////////////
//
// Fire up a webhook test server by using the --webhook-http-consumer-port // Fire up a webhook test server by using the --webhook-http-consumer-port
// for example // for example
// $ ./tile38-server --webhook-http-consumer-port 9999 // $ ./tile38-server --webhook-http-consumer-port 9999
// //
// The create hooks like such... // The create hooks like such...
// SETHOOK myhook http://localhost:9999/myhook NEARBY mykey FENCE POINT 33.5 -115.5 1000 // SETHOOK myhook http://localhost:9999/myhook NEARBY mykey FENCE POINT 33.5 -115.5 1000
//
////////////////////////////////////////////////////////////////////////////////
//
// Memory profiling - start the server with the -pprofport flag
//
// $ ./tile38-server -pprofport 6060
//
// Then, at any point, from a different terminal execute:
// $ go tool pprof -svg http://localhost:6060/debug/pprof/heap > out.svg
//
// Load the SVG into a web browser to visualize the memory usage
//
////////////////////////////////////////////////////////////////////////////////
type hserver struct{} type hserver struct{}
@ -240,6 +260,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
@ -263,24 +286,75 @@ Developer Options:
if host != "" { if host != "" {
hostd = "Addr: " + host + ", " hostd = "Addr: " + host + ", "
} }
var pidferr error
var cleanedup bool // pprof
var cleanupMu sync.Mutex if cpuprofile != "" {
cleanup := func() { log.Debugf("cpuprofile active")
cleanupMu.Lock() f, err := os.Create(cpuprofile)
defer cleanupMu.Unlock() if err != nil {
if cleanedup { 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 pprofcleanedup bool
var pprofcleanupMu sync.Mutex
pprofcleanup := func() {
pprofcleanupMu.Lock()
defer pprofcleanupMu.Unlock()
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() {
if pidfile != "" {
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 {
@ -296,9 +370,8 @@ Developer Options:
continue continue
} }
log.Warnf("signal: %v", s) log.Warnf("signal: %v", s)
if pidfile != "" { pidcleanup()
cleanup() pprofcleanup()
}
switch { switch {
default: default:
os.Exit(-1) os.Exit(-1)