github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/app/elapse_info.go (about) 1 package app 2 3 import ( 4 "fmt" 5 "strings" 6 "sync" 7 8 "github.com/fibonacci-chain/fbc/libs/system/trace" 9 "github.com/fibonacci-chain/fbc/libs/tendermint/libs/log" 10 11 "github.com/spf13/viper" 12 ) 13 14 type SchemaConfig struct { 15 schema string 16 enabled int 17 } 18 19 var ( 20 optionalSchemas = []SchemaConfig{ 21 {trace.MempoolCheckTxCnt, 0}, 22 {trace.MempoolCheckTxTime, 0}, 23 {trace.SigCacheRatio, 0}, 24 {trace.Evm, 1}, 25 {trace.Delta, 1}, 26 {trace.Iavl, 1}, 27 {trace.DeliverTxs, 1}, 28 {trace.EvmHandlerDetail, 0}, 29 30 {trace.IavlRuntime, 0}, 31 {trace.RunAnteDetail, 0}, 32 {trace.AnteChainDetail, 0}, 33 {trace.Round, 0}, 34 {trace.CommitRound, 0}, 35 //{trace.RecvBlock, 1}, 36 {trace.First2LastPart, 0}, 37 {trace.BlockParts, 0}, 38 {trace.BlockPartsP2P, 0}, 39 {trace.Produce, 0}, 40 {trace.CompressBlock, 0}, 41 {trace.UncompressBlock, 0}, 42 } 43 44 mandatorySchemas = []string{ 45 trace.Height, 46 trace.Tx, 47 trace.SimTx, 48 trace.BlockSize, 49 trace.BTInterval, 50 trace.RecommendedGP, 51 trace.IsCongested, 52 trace.LastBlockTime, 53 trace.GasUsed, 54 trace.SimGasUsed, 55 trace.InvalidTxs, 56 trace.LastRun, 57 trace.ApplyBlock, 58 trace.RunTx, 59 trace.Prerun, 60 trace.MempoolTxsCnt, 61 trace.Workload, 62 trace.ACOffset, 63 trace.PersistDetails, 64 } 65 66 DefaultElapsedSchemas string 67 ) 68 69 const ( 70 Elapsed = "elapsed" 71 ) 72 73 func init() { 74 for _, k := range optionalSchemas { 75 DefaultElapsedSchemas += fmt.Sprintf("%s=%d,", k.schema, k.enabled) 76 } 77 78 elapsedInfo := &ElapsedTimeInfos{ 79 infoMap: make(map[string]string), 80 schemaMap: make(map[string]struct{}), 81 } 82 83 elapsedInfo.decodeElapseParam(DefaultElapsedSchemas) 84 trace.SetInfoObject(elapsedInfo) 85 86 } 87 88 type ElapsedTimeInfos struct { 89 mtx sync.Mutex 90 infoMap map[string]string 91 schemaMap map[string]struct{} 92 initialized bool 93 elapsedTime int64 94 } 95 96 func (e *ElapsedTimeInfos) AddInfo(key string, info string) { 97 if len(key) == 0 || len(info) == 0 { 98 return 99 } 100 101 _, ok := e.schemaMap[key] 102 if !ok { 103 return 104 } 105 106 e.mtx.Lock() 107 defer e.mtx.Unlock() 108 109 e.infoMap[key] = info 110 } 111 112 func (e *ElapsedTimeInfos) Dump(input interface{}) { 113 114 logger, ok := input.(log.Logger) 115 if !ok { 116 panic("Invalid input") 117 } 118 e.mtx.Lock() 119 defer e.mtx.Unlock() 120 121 if _, ok := e.infoMap[trace.Height]; !ok { 122 return 123 } 124 125 if !e.initialized { 126 e.decodeElapseParam(viper.GetString(Elapsed)) 127 e.initialized = true 128 } 129 130 var mandatoryInfo string 131 for _, key := range mandatorySchemas { 132 _, ok := e.infoMap[key] 133 if !ok { 134 continue 135 } 136 mandatoryInfo += fmt.Sprintf("%s<%s>, ", key, e.infoMap[key]) 137 } 138 139 var optionalInfo string 140 var comma string 141 for _, k := range optionalSchemas { 142 if _, found := e.schemaMap[k.schema]; found { 143 _, ok := e.infoMap[k.schema] 144 if !ok { 145 continue 146 } 147 optionalInfo += fmt.Sprintf("%s%s[%s]", comma, k.schema, e.infoMap[k.schema]) 148 comma = ", " 149 } 150 } 151 152 logger.Info(mandatoryInfo + optionalInfo) 153 e.infoMap = make(map[string]string) 154 } 155 156 func (e *ElapsedTimeInfos) decodeElapseParam(elapsed string) { 157 // elapsed looks like: Evm=x,Iavl=x,DeliverTxs=x,DB=x,Round=x,CommitRound=x,Produce=x,IavlRuntime=x 158 elapsedKV := strings.Split(elapsed, ",") 159 for _, v := range elapsedKV { 160 setVal := strings.Split(v, "=") 161 if len(setVal) == 2 && setVal[1] == "1" { 162 e.schemaMap[setVal[0]] = struct{}{} 163 } 164 } 165 166 for _, key := range mandatorySchemas { 167 e.schemaMap[key] = struct{}{} 168 } 169 } 170 171 func (e *ElapsedTimeInfos) SetElapsedTime(elapsedTime int64) { 172 e.elapsedTime = elapsedTime 173 } 174 175 func (e *ElapsedTimeInfos) GetElapsedTime() int64 { 176 return e.elapsedTime 177 }