github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/cmd/geth/log_display_basic.go (about) 1 // --- 2 //2017-02-03 16:44:00 Discover 0/25 peers 3 //2017-02-03 16:45:00 Discover 1/25 peers 4 //2017-02-03 16:46:00 Fast #2481951 of #3124363 79.4% 1211/ 554 blk/mgas sec 6/25 peers 5 //2017-02-03 16:47:00 Fast #2689911 of #3124363 86.1% 611/ 981 blk/mgas sec 6/25 peers 6 //2017-02-03 16:48:00 Fast #2875913 of #3124363 92.0% 502/ 760 blk/mgas sec 4/25 peers 7 //2017-02-03 16:49:00 Sync #3124227 of #3124363 c76c34e7 77/ 242/ 7 blk/tx/mgas sec 4/25 peers 8 //2017-02-03 16:50:00 Sync #3124247 of #3124363 75e48eff 51/ 51/ 5 blk/tx/mgas sec 4/25 peers 9 //2017-02-03 16:51:00 Sync #3124567 of #3124363 9af334ae 117/ 129/11 blk/tx/mgas sec 5/25 peers 10 //2017-02-03 16:52:00 Sync #3124787 of #3124363 1e3a8351 9/ 6/ 1 blk/tx/mgas sec 7/25 peers 11 //2017-02-03 16:52:05 Import #3124788 84e11ff4 15/ 7 tx/mgas 10/25 peers 12 //2017-02-03 16:52:25 Import #3124789 9e45a241 5/ 1 tx/mgas 12/25 peers 13 //2017-02-03 16:52:45 Import #3124790 d819f71c 0/ 0 tx/mgas 18/25 peers 14 //2017-02-03 16:52:46 Mined #3124791 b719f31b 7/ 1 tx/mgas 18/25 peers 15 // --- 16 17 package main 18 19 import ( 20 "fmt" 21 "math/big" 22 "strconv" 23 "time" 24 25 "github.com/ethereumproject/go-ethereum/core" 26 "github.com/ethereumproject/go-ethereum/core/types" 27 "github.com/ethereumproject/go-ethereum/eth" 28 "github.com/ethereumproject/go-ethereum/eth/downloader" 29 "github.com/ethereumproject/go-ethereum/logger" 30 "github.com/ethereumproject/go-ethereum/logger/glog" 31 "gopkg.in/urfave/cli.v1" 32 ) 33 34 // basicDisplaySystem is the basic display system spec'd in #127. 35 var basicDisplaySystem = displayEventHandlers{ 36 { 37 eventT: logEventCoreChainInsert, 38 ev: core.ChainInsertEvent{}, 39 handlers: displayEventHandlerFns{ 40 func(ctx *cli.Context, e *eth.Ethereum, evData interface{}, tickerInterval time.Duration) { 41 // Conditional prevents chain insert event logs during full/fast sync 42 if currentMode == lsModeImport { 43 switch d := evData.(type) { 44 case core.ChainInsertEvent: 45 currentBlockNumber = PrintStatusBasic(e, tickerInterval, &d, ctx.GlobalInt(aliasableName(MaxPeersFlag.Name, ctx))) 46 chainEventLastSent = time.Now() 47 } 48 } 49 }, 50 }, 51 }, 52 { 53 eventT: logEventCoreMinedBlock, 54 ev: core.NewMinedBlockEvent{}, 55 handlers: displayEventHandlerFns{ 56 func(ctx *cli.Context, e *eth.Ethereum, evData interface{}, tickerInterval time.Duration) { 57 switch d := evData.(type) { 58 case core.NewMinedBlockEvent: 59 glog.D(logger.Warn).Infof(basicScanLn, 60 "Mined", 61 formatBlockNumber(d.Block.NumberU64()), 62 d.Block.Hash().Hex()[2:2+len(xlocalHeadHashD)], 63 fmt.Sprintf("%3d/%2d", d.Block.Transactions().Len(), new(big.Int).Div(d.Block.GasUsed(), big.NewInt(1000000)).Int64()), 64 "txs/mgas", 65 fmt.Sprintf("%2d/%2d peers", e.Downloader().GetPeers().Len(), ctx.GlobalInt(aliasableName(MaxPeersFlag.Name, ctx))), 66 ) 67 currentBlockNumber = d.Block.NumberU64() 68 } 69 }, 70 }, 71 }, 72 { 73 eventT: logEventDownloaderStart, 74 ev: downloader.StartEvent{}, 75 }, 76 { 77 eventT: logEventDownloaderDone, 78 ev: downloader.DoneEvent{}, 79 }, 80 { 81 eventT: logEventDownloaderFailed, 82 ev: downloader.FailedEvent{}, 83 }, 84 { 85 eventT: logEventInterval, 86 handlers: displayEventHandlerFns{ 87 func(ctx *cli.Context, e *eth.Ethereum, evData interface{}, tickerInterval time.Duration) { 88 // If not in import mode OR if we haven't logged a chain event. 89 if currentMode != lsModeImport || chainEventLastSent.IsZero() { 90 currentBlockNumber = PrintStatusBasic(e, tickerInterval, nil, ctx.GlobalInt(aliasableName(MaxPeersFlag.Name, ctx))) 91 } 92 }, 93 }, 94 }, 95 } 96 97 func formatBlockNumber(i uint64) string { 98 return "#" + strconv.FormatUint(i, 10) 99 } 100 101 // Examples of spec'd output. 102 const ( 103 xlocalOfMaxD = "#92481951 of #93124363" // #2481951 of #3124363 104 // xpercentD = " 92.0%" // 92.0% // commented because it is an item in the spec, but shorter than xLocalHeadHashD 105 xlocalHeadHashD = "c76c34e7" // c76c34e7 106 xprogressRateD = " 117/ 129/ 11" // 117/ 129/11 107 xprogressRateUnitsD = "blk/txs/mgas sec" // blk/tx/mgas sec 108 xpeersD = "18/25 peers" // 18/25 peers 109 ) 110 111 const basicScanLn = "%-8s %-22s %8s %13s %-16s %11s" 112 113 func strScanLenOf(s string, leftAlign bool) string { 114 if leftAlign { 115 return "%-" + strconv.Itoa(len(s)) + "s" 116 } 117 return "%" + strconv.Itoa(len(s)) + "s" 118 } 119 120 type printUnit struct { 121 value string 122 example string 123 leftAlign bool 124 } 125 126 func (p *printUnit) String() string { 127 return fmt.Sprintf("%s", p.value) 128 } 129 130 func calcBlockDiff(e *eth.Ethereum, lastLoggedBlockN uint64, localHead *types.Block) (blks, txs, mgas int) { 131 // Calculate block stats for interval 132 localHeadN := localHead.NumberU64() 133 blks = int(localHeadN - lastLoggedBlockN) 134 txs = 0 135 mGas := new(big.Int) 136 137 for i := lastLoggedBlockN + 1; i <= localHeadN; i++ { 138 b := e.BlockChain().GetBlockByNumber(i) 139 if b != nil { 140 // Add to tallies 141 txs += b.Transactions().Len() 142 mGas = mGas.Add(mGas, b.GasUsed()) 143 } 144 } 145 mGas.Div(mGas, big.NewInt(1000000)) 146 return blks, txs, int(mGas.Int64()) 147 } 148 149 func calcPercent(quotient, divisor uint64) float64 { 150 out := float64(quotient) / float64(divisor) 151 return out * 100 152 } 153 154 // PrintStatusBasic implements the displayEventHandlerFn interface 155 var PrintStatusBasic = func(e *eth.Ethereum, tickerInterval time.Duration, insertEvent *core.ChainInsertEvent, maxPeers int) uint64 { 156 157 // Set variable copy of current mode to avoid issue around currentMode's non-thread safety 158 currentModeLocal := currentMode 159 160 localOfMaxD := &printUnit{"", xlocalOfMaxD, true} 161 percentOrHash := &printUnit{"", xlocalHeadHashD, false} 162 progressRateD := &printUnit{"", xprogressRateD, false} // 117/ 129/11 163 progressRateUnitsD := &printUnit{"", xprogressRateUnitsD, false} // blk/tx/mgas sec 164 peersD := &printUnit{"", xpeersD, false} // 18/25 peers 165 166 formatLocalOfMaxD := func(localheight, syncheight uint64) string { 167 if localheight < syncheight { 168 return fmt.Sprintf("%9s of %9s", formatBlockNumber(localheight), formatBlockNumber(syncheight)) 169 } 170 // Show diff if imported more than one block. 171 if insertEvent != nil && insertEvent.Processed > 1 { 172 return fmt.Sprintf("%9s (+%4d) ", formatBlockNumber(localheight), insertEvent.Processed) 173 } 174 return fmt.Sprintf("%9s ", formatBlockNumber(localheight)) 175 } 176 177 formatPercentD := func(localheight, syncheight uint64) string { 178 // Calculate and format percent sync of known height 179 fHeightRatio := fmt.Sprintf("%4.2f%%", calcPercent(localheight, syncheight)) 180 return fmt.Sprintf("%s", fHeightRatio) 181 } 182 183 formatBlockHashD := func(b *types.Block) string { 184 return b.Hash().Hex()[2 : 2+len(xlocalHeadHashD)] 185 } 186 187 formatProgressRateD := func(blksN, txsN, mgasN int) string { 188 if blksN < 0 { 189 return fmt.Sprintf("%4d/%2d", txsN, mgasN) 190 } 191 if txsN < 0 { 192 return fmt.Sprintf("%3d/%2d", blksN, mgasN) 193 } 194 return fmt.Sprintf("%3d/%4d/%2d", blksN, txsN, mgasN) 195 } 196 197 formatPeersD := func(peersN, maxpeersN int) string { 198 return fmt.Sprintf("%2d/%2d peers", peersN, maxpeersN) 199 } 200 201 peersD.value = formatPeersD(e.Downloader().GetPeers().Len(), maxPeers) 202 defer func() { 203 glog.D(logger.Warn).Infof(basicScanLn, 204 currentModeLocal, localOfMaxD, percentOrHash, progressRateD, progressRateUnitsD, peersD) 205 206 }() 207 208 origin, current, chainSyncHeight, _, _ := e.Downloader().Progress() // origin, current, height, pulled, known 209 mode := e.Downloader().GetMode() 210 if mode == downloader.FastSync { 211 current = e.BlockChain().CurrentFastBlock().NumberU64() 212 } 213 214 if currentModeLocal == lsModeDiscover { 215 return current 216 } 217 218 var localHead *types.Block 219 if insertEvent != nil { 220 if evB := e.BlockChain().GetBlock(insertEvent.LastHash); evB != nil && currentModeLocal == lsModeImport { 221 localHead = evB 222 } 223 } else { 224 localHead = e.BlockChain().GetBlockByNumber(current) 225 } 226 // Sanity/safety check 227 if localHead == nil { 228 localHead = e.BlockChain().CurrentBlock() 229 if mode == downloader.FastSync { 230 localHead = e.BlockChain().CurrentFastBlock() 231 } 232 } 233 234 // Calculate progress rates 235 var blks, txs, mgas int 236 if currentModeLocal == lsModeImport && insertEvent != nil && insertEvent.Processed == 1 { 237 blks, txs, mgas = 1, localHead.Transactions().Len(), int(new(big.Int).Div(localHead.GasUsed(), big.NewInt(1000000)).Uint64()) 238 } else if insertEvent != nil && insertEvent.Processed > 1 { 239 blks, txs, mgas = calcBlockDiff(e, localHead.NumberU64()-uint64(insertEvent.Processed), localHead) 240 } else if currentBlockNumber == 0 && origin > 0 { 241 blks, txs, mgas = calcBlockDiff(e, origin, localHead) 242 } else if currentBlockNumber != 0 && currentBlockNumber < localHead.NumberU64() { 243 blks, txs, mgas = calcBlockDiff(e, currentBlockNumber, localHead) 244 } else { 245 blks, txs, mgas = calcBlockDiff(e, localHead.NumberU64()-1, localHead) 246 } 247 248 switch currentModeLocal { 249 case lsModeFastSync: 250 lh := localHead.NumberU64() 251 localOfMaxD.value = formatLocalOfMaxD(lh, chainSyncHeight) 252 percentOrHash.value = formatPercentD(lh, chainSyncHeight) 253 progressRateD.value = formatProgressRateD(blks/int(tickerInterval.Seconds()), -1, mgas/int(tickerInterval.Seconds())) 254 progressRateUnitsD.value = fmt.Sprintf(strScanLenOf(xprogressRateUnitsD, true), "blk/mgas sec") 255 case lsModeFullSync: 256 localOfMaxD.value = formatLocalOfMaxD(localHead.NumberU64(), chainSyncHeight) 257 percentOrHash.value = formatBlockHashD(localHead) 258 progressRateD.value = formatProgressRateD(blks/int(tickerInterval.Seconds()), txs/int(tickerInterval.Seconds()), mgas/int(tickerInterval.Seconds())) 259 progressRateUnitsD.value = fmt.Sprintf(strScanLenOf(xprogressRateUnitsD, true), "blk/txs/mgas sec") 260 case lsModeImport: 261 localOfMaxD.value = formatLocalOfMaxD(localHead.NumberU64(), chainSyncHeight) 262 percentOrHash.value = formatBlockHashD(localHead) 263 progressRateD.value = fmt.Sprintf(strScanLenOf(xprogressRateD, false), formatProgressRateD(-1, txs, mgas)) 264 progressRateUnitsD.value = fmt.Sprintf(strScanLenOf(xprogressRateUnitsD, true), "txs/mgas") 265 default: 266 // Without establishing currentModeLocal it would be possible to reach this case if currentMode changed during 267 // execution of last ~40 lines. 268 } 269 return current 270 }