mirror of
https://github.com/nicksherron/bashhub-server.git
synced 2025-09-05 03:44:30 +08:00
cmd/root: add runtime profiling
This adds trace, cpu and memory profiling to the root command. To use, set any of the environment variables BH_SERVER_DEBUG_TRACE, BH_SERVER_DEBUG_CPU, BH_SERVER_DEBUG_MEM to a file name and the coinciding profile will run until you interrupt or terminate the process. Use the go tool pprof to analyse the output file you set in the environment variable.
This commit is contained in:
parent
276abf37b0
commit
703567f19c
1 changed files with 63 additions and 4 deletions
67
cmd/root.go
67
cmd/root.go
|
@ -22,8 +22,13 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"runtime/pprof"
|
||||
"runtime/trace"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/nicksherron/bashhub-server/internal"
|
||||
|
@ -32,14 +37,20 @@ import (
|
|||
|
||||
// rootCmd represents the base command when called without any subcommands
|
||||
var (
|
||||
logFile string
|
||||
dbPath string
|
||||
addr string
|
||||
rootCmd = &cobra.Command{
|
||||
logFile string
|
||||
dbPath string
|
||||
addr string
|
||||
traceProfile = os.Getenv("BH_SERVER_DEBUG_TRACE")
|
||||
cpuProfile = os.Getenv("BH_SERVER_DEBUG_CPU")
|
||||
memProfile = os.Getenv("BH_SERVER_DEBUG_MEM")
|
||||
rootCmd = &cobra.Command{
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmd.Flags().Parse(args)
|
||||
checkBhEnv()
|
||||
startupMessage()
|
||||
if cpuProfile != "" || memProfile != "" || traceProfile != "" {
|
||||
profileInit()
|
||||
}
|
||||
internal.Run(dbPath, logFile, addr)
|
||||
},
|
||||
}
|
||||
|
@ -121,3 +132,51 @@ export BH_URL=%v to your .bashrc or .zshrc`, addr)
|
|||
fmt.Println(msg)
|
||||
}
|
||||
}
|
||||
|
||||
func profileInit() {
|
||||
|
||||
go func() {
|
||||
defer os.Exit(1)
|
||||
if traceProfile != "" {
|
||||
f, err := os.Create(traceProfile)
|
||||
if err != nil {
|
||||
log.Fatal("could not create trace profile: ", err)
|
||||
}
|
||||
defer f.Close()
|
||||
if err := trace.Start(f); err != nil {
|
||||
log.Fatal("could not start trace profile: ", err)
|
||||
}
|
||||
defer trace.Stop()
|
||||
}
|
||||
|
||||
if cpuProfile != "" {
|
||||
f, err := os.Create(cpuProfile)
|
||||
if err != nil {
|
||||
log.Fatal("could not create CPU profile: ", err)
|
||||
}
|
||||
defer f.Close()
|
||||
if err := pprof.StartCPUProfile(f); err != nil {
|
||||
log.Fatal("could not start CPU profile: ", err)
|
||||
}
|
||||
defer pprof.StopCPUProfile()
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if memProfile != "" {
|
||||
mf, err := os.Create(memProfile)
|
||||
if err != nil {
|
||||
log.Fatal("could not create memory profile: ", err)
|
||||
}
|
||||
defer mf.Close()
|
||||
runtime.GC() // get up-to-date statistics
|
||||
if err := pprof.WriteHeapProfile(mf); err != nil {
|
||||
log.Fatal("could not write memory profile: ", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
sigs := make(chan os.Signal, 1)
|
||||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-sigs
|
||||
}()
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue