github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/internal/debug/flags.go (about) 1 package debug 2 3 import ( 4 "fmt" 5 "io" 6 "net/http" 7 _ "net/http/pprof" 8 "os" 9 "runtime" 10 11 "github.com/quickchainproject/quickchain/log" 12 "github.com/quickchainproject/quickchain/log/term" 13 "github.com/quickchainproject/quickchain/metrics" 14 "github.com/quickchainproject/quickchain/metrics/exp" 15 "github.com/fjl/memsize/memsizeui" 16 colorable "github.com/mattn/go-colorable" 17 "gopkg.in/urfave/cli.v1" 18 ) 19 20 var Memsize memsizeui.Handler 21 22 var ( 23 verbosityFlag = cli.IntFlag{ 24 Name: "verbosity", 25 Usage: "Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail", 26 Value: 3, 27 } 28 vmoduleFlag = cli.StringFlag{ 29 Name: "vmodule", 30 Usage: "Per-module verbosity: comma-separated list of <pattern>=<level> (e.g. eth/*=5,p2p=4)", 31 Value: "", 32 } 33 backtraceAtFlag = cli.StringFlag{ 34 Name: "backtrace", 35 Usage: "Request a stack trace at a specific logging statement (e.g. \"block.go:271\")", 36 Value: "", 37 } 38 debugFlag = cli.BoolFlag{ 39 Name: "debug", 40 Usage: "Prepends log messages with call-site location (file and line number)", 41 } 42 pprofFlag = cli.BoolFlag{ 43 Name: "pprof", 44 Usage: "Enable the pprof HTTP server", 45 } 46 pprofPortFlag = cli.IntFlag{ 47 Name: "pprofport", 48 Usage: "pprof HTTP server listening port", 49 Value: 6060, 50 } 51 pprofAddrFlag = cli.StringFlag{ 52 Name: "pprofaddr", 53 Usage: "pprof HTTP server listening interface", 54 Value: "127.0.0.1", 55 } 56 memprofilerateFlag = cli.IntFlag{ 57 Name: "memprofilerate", 58 Usage: "Turn on memory profiling with the given rate", 59 Value: runtime.MemProfileRate, 60 } 61 blockprofilerateFlag = cli.IntFlag{ 62 Name: "blockprofilerate", 63 Usage: "Turn on block profiling with the given rate", 64 } 65 cpuprofileFlag = cli.StringFlag{ 66 Name: "cpuprofile", 67 Usage: "Write CPU profile to the given file", 68 } 69 traceFlag = cli.StringFlag{ 70 Name: "trace", 71 Usage: "Write execution trace to the given file", 72 } 73 ) 74 75 // Flags holds all command-line flags required for debugging. 76 var Flags = []cli.Flag{ 77 verbosityFlag, vmoduleFlag, backtraceAtFlag, debugFlag, 78 pprofFlag, pprofAddrFlag, pprofPortFlag, 79 memprofilerateFlag, blockprofilerateFlag, cpuprofileFlag, traceFlag, 80 } 81 82 var glogger *log.GlogHandler 83 84 func init() { 85 usecolor := term.IsTty(os.Stderr.Fd()) && os.Getenv("TERM") != "dumb" 86 output := io.Writer(os.Stderr) 87 if usecolor { 88 output = colorable.NewColorableStderr() 89 } 90 glogger = log.NewGlogHandler(log.StreamHandler(output, log.TerminalFormat(usecolor))) 91 } 92 93 // Setup initializes profiling and logging based on the CLI flags. 94 // It should be called as early as possible in the program. 95 func Setup(ctx *cli.Context) error { 96 // logging 97 log.PrintOrigins(ctx.GlobalBool(debugFlag.Name)) 98 glogger.Verbosity(log.Lvl(ctx.GlobalInt(verbosityFlag.Name))) 99 glogger.Vmodule(ctx.GlobalString(vmoduleFlag.Name)) 100 glogger.BacktraceAt(ctx.GlobalString(backtraceAtFlag.Name)) 101 log.Root().SetHandler(glogger) 102 103 // profiling, tracing 104 runtime.MemProfileRate = ctx.GlobalInt(memprofilerateFlag.Name) 105 Handler.SetBlockProfileRate(ctx.GlobalInt(blockprofilerateFlag.Name)) 106 if traceFile := ctx.GlobalString(traceFlag.Name); traceFile != "" { 107 if err := Handler.StartGoTrace(traceFile); err != nil { 108 return err 109 } 110 } 111 if cpuFile := ctx.GlobalString(cpuprofileFlag.Name); cpuFile != "" { 112 if err := Handler.StartCPUProfile(cpuFile); err != nil { 113 return err 114 } 115 } 116 117 // pprof server 118 if ctx.GlobalBool(pprofFlag.Name) { 119 address := fmt.Sprintf("%s:%d", ctx.GlobalString(pprofAddrFlag.Name), ctx.GlobalInt(pprofPortFlag.Name)) 120 StartPProf(address) 121 } 122 return nil 123 } 124 125 func StartPProf(address string) { 126 // Hook go-metrics into expvar on any /debug/metrics request, load all vars 127 // from the registry into expvar, and execute regular expvar handler. 128 exp.Exp(metrics.DefaultRegistry) 129 http.Handle("/memsize/", http.StripPrefix("/memsize", &Memsize)) 130 log.Info("Starting pprof server", "addr", fmt.Sprintf("http://%s/debug/pprof", address)) 131 go func() { 132 if err := http.ListenAndServe(address, nil); err != nil { 133 log.Error("Failure in running pprof server", "err", err) 134 } 135 }() 136 } 137 138 // Exit stops all running profiles, flushing their output to the 139 // respective file. 140 func Exit() { 141 Handler.StopCPUProfile() 142 Handler.StopGoTrace() 143 }