mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-15 00:19:29 +01:00
fix #1975
Provide a nondestructive stack trace dump option even when the http pprof listener is disabled
This commit is contained in:
parent
77de026961
commit
d17faf6bcb
@ -12,6 +12,7 @@ import (
|
|||||||
_ "net/http/pprof"
|
_ "net/http/pprof"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"runtime/pprof"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -83,6 +84,7 @@ type Server struct {
|
|||||||
rehashSignal chan os.Signal
|
rehashSignal chan os.Signal
|
||||||
pprofServer *http.Server
|
pprofServer *http.Server
|
||||||
exitSignals chan os.Signal
|
exitSignals chan os.Signal
|
||||||
|
tracebackSignal chan os.Signal
|
||||||
snomasks SnoManager
|
snomasks SnoManager
|
||||||
store *buntdb.DB
|
store *buntdb.DB
|
||||||
historyDB mysql.MySQL
|
historyDB mysql.MySQL
|
||||||
@ -98,11 +100,12 @@ type Server struct {
|
|||||||
func NewServer(config *Config, logger *logger.Manager) (*Server, error) {
|
func NewServer(config *Config, logger *logger.Manager) (*Server, error) {
|
||||||
// initialize data structures
|
// initialize data structures
|
||||||
server := &Server{
|
server := &Server{
|
||||||
ctime: time.Now().UTC(),
|
ctime: time.Now().UTC(),
|
||||||
listeners: make(map[string]IRCListener),
|
listeners: make(map[string]IRCListener),
|
||||||
logger: logger,
|
logger: logger,
|
||||||
rehashSignal: make(chan os.Signal, 1),
|
rehashSignal: make(chan os.Signal, 1),
|
||||||
exitSignals: make(chan os.Signal, len(utils.ServerExitSignals)),
|
exitSignals: make(chan os.Signal, len(utils.ServerExitSignals)),
|
||||||
|
tracebackSignal: make(chan os.Signal, len(utils.ServerTracebackSignals)),
|
||||||
}
|
}
|
||||||
server.defcon.Store(5)
|
server.defcon.Store(5)
|
||||||
|
|
||||||
@ -120,6 +123,9 @@ func NewServer(config *Config, logger *logger.Manager) (*Server, error) {
|
|||||||
// Attempt to clean up when receiving these signals.
|
// Attempt to clean up when receiving these signals.
|
||||||
signal.Notify(server.exitSignals, utils.ServerExitSignals...)
|
signal.Notify(server.exitSignals, utils.ServerExitSignals...)
|
||||||
signal.Notify(server.rehashSignal, syscall.SIGHUP)
|
signal.Notify(server.rehashSignal, syscall.SIGHUP)
|
||||||
|
if len(utils.ServerTracebackSignals) != 0 {
|
||||||
|
signal.Notify(server.tracebackSignal, utils.ServerTracebackSignals...)
|
||||||
|
}
|
||||||
|
|
||||||
time.AfterFunc(alwaysOnMaintenanceInterval, server.periodicAlwaysOnMaintenance)
|
time.AfterFunc(alwaysOnMaintenanceInterval, server.periodicAlwaysOnMaintenance)
|
||||||
|
|
||||||
@ -158,6 +164,8 @@ func (server *Server) Run() {
|
|||||||
case <-server.rehashSignal:
|
case <-server.rehashSignal:
|
||||||
server.logger.Info("server", "Rehashing due to SIGHUP")
|
server.logger.Info("server", "Rehashing due to SIGHUP")
|
||||||
go server.rehash()
|
go server.rehash()
|
||||||
|
case <-server.tracebackSignal:
|
||||||
|
go server.dumpStacks()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1128,3 +1136,11 @@ var (
|
|||||||
Edmund Huber, edmund-huber
|
Edmund Huber, edmund-huber
|
||||||
`, "\n")
|
`, "\n")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (server *Server) dumpStacks() {
|
||||||
|
if gprof := pprof.Lookup("goroutine"); gprof != nil {
|
||||||
|
gprof.WriteTo(os.Stderr, 2)
|
||||||
|
} else {
|
||||||
|
server.logger.Error("internal", "unable to dump goroutine stacks")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -18,4 +18,8 @@ var (
|
|||||||
syscall.SIGTERM,
|
syscall.SIGTERM,
|
||||||
syscall.SIGQUIT,
|
syscall.SIGQUIT,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServerTracebackSignals = []os.Signal{
|
||||||
|
syscall.SIGUSR1,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
@ -18,4 +18,7 @@ var (
|
|||||||
syscall.SIGINT,
|
syscall.SIGINT,
|
||||||
syscall.SIGTERM,
|
syscall.SIGTERM,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no SIGUSR1 on plan9
|
||||||
|
ServerTracebackSignals []os.Signal
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user