github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/system/trace/pprof.go (about) 1 package trace 2 3 import ( 4 "fmt" 5 "os" 6 "path" 7 "runtime/pprof" 8 "time" 9 10 "github.com/fibonacci-chain/fbc/libs/tendermint/libs/log" 11 ) 12 13 const ( 14 defaultLoggerFlags = os.O_RDWR | os.O_CREATE | os.O_APPEND 15 defaultLoggerPerm = 0644 16 defaultCPUSamplingTime = 30 * time.Second // collect 30s cpu profile 17 defaultCoolDown = 3 * time.Minute 18 ) 19 20 var singlePprofDumper *pprofDumper 21 22 func InitializePprofDumper(logger log.Logger, dumpPath string, coolDownStr string, abciElapsed int64) { 23 if singlePprofDumper != nil { 24 return 25 } 26 coolDown, err := time.ParseDuration(coolDownStr) 27 if err != nil { 28 coolDown = defaultCoolDown 29 } 30 singlePprofDumper = &pprofDumper{ 31 logger: logger.With("module", "main"), 32 dumpPath: dumpPath, 33 coolDown: coolDown, 34 cpuCoolDownTime: time.Now(), 35 triggerAbciElapsed: abciElapsed, 36 } 37 } 38 39 type pprofDumper struct { 40 logger log.Logger 41 dumpPath string 42 // the cool down time after every type of dump 43 coolDown time.Duration 44 cpuCoolDownTime time.Time 45 triggerAbciElapsed int64 46 } 47 48 func (dumper *pprofDumper) cpuProfile(height int64) { 49 if dumper.cpuCoolDownTime.After(time.Now()) { 50 dumper.logger.Info(fmt.Sprintf("height(%d) cpu dump is in coolDown", height)) 51 return 52 } 53 dumper.cpuCoolDownTime = time.Now().Add(dumper.coolDown) 54 go dumper.dumpCpuPprof(height) 55 } 56 57 func (dumper *pprofDumper) dumpCpuPprof(height int64) { 58 fileName := dumper.getBinaryFileName(height) 59 bf, err := os.OpenFile(fileName, defaultLoggerFlags, defaultLoggerPerm) 60 if err != nil { 61 dumper.logger.Error("height(%d) dump cpu pprof, open file(%s) error:%s", height, fileName, err.Error()) 62 return 63 } 64 defer bf.Close() 65 66 err = pprof.StartCPUProfile(bf) 67 if err != nil { 68 dumper.logger.Error("height(%d) dump cpu pprof, StartCPUProfile error:%s", height, err.Error()) 69 return 70 } 71 72 time.Sleep(defaultCPUSamplingTime) 73 pprof.StopCPUProfile() 74 dumper.logger.Info("height(%d) dump cpu pprof file(%s)", fileName) 75 } 76 77 func (dumper *pprofDumper) getBinaryFileName(height int64) string { 78 var ( 79 binarySuffix = time.Now().Format("20060102150405") + ".bin" 80 ) 81 fileName := fmt.Sprintf("interval_%d_%s", height, binarySuffix) 82 return path.Join(dumper.dumpPath, fileName) 83 }