blocklogger.go raw
1 package netsync
2
3 import (
4 "fmt"
5 "github.com/p9c/p9/pkg/block"
6 "sync"
7 "time"
8 )
9
10 // blockProgressLogger provides periodic logging for other services in order to show users progress of certain "actions"
11 // involving some or all current blocks. Ex: syncing to best chain, indexing all blocks, etc.
12 type blockProgressLogger struct {
13 receivedLogBlocks int64
14 receivedLogTx int64
15 lastBlockLogTime time.Time
16 // subsystemLogger *log.Logger
17 progressAction string
18 sync.Mutex
19 }
20
21 // newBlockProgressLogger returns a new block progress logger. The progress message is templated as follows:
22 // {progressAction } {numProcessed} {blocks|block} in the last {timePeriod} ({numTxs}, height {lastBlockHeight},
23 // {lastBlockTimeStamp})
24 func newBlockProgressLogger(progressMessage string) *blockProgressLogger {
25 return &blockProgressLogger{
26 lastBlockLogTime: time.Now(),
27 progressAction: progressMessage,
28 }
29 }
30
31 // LogBlockHeight logs a new block height as an information message to show progress to the user.
32 //
33 // In order to prevent spam, it limits logging to one message every 10 seconds with duration and totals included.
34 func (b *blockProgressLogger) LogBlockHeight(block *block.Block) {
35 b.Lock()
36 defer b.Unlock()
37 b.receivedLogBlocks++
38 b.receivedLogTx += int64(len(block.WireBlock().Transactions))
39 now := time.Now()
40 duration := now.Sub(b.lastBlockLogTime)
41 if duration < time.Second*2 {
42 return
43 }
44 // Truncate the duration to 10s of milliseconds.
45 durationMillis := int64(duration / time.Millisecond)
46 tDuration := 10 * time.Millisecond * time.Duration(durationMillis/10)
47 // Log information about new block height.
48 blockStr := "blocks"
49 if b.receivedLogBlocks == 1 {
50 blockStr = "block "
51 }
52 txStr := "transactions"
53 if b.receivedLogTx == 1 {
54 txStr = "transaction "
55 }
56 tD := tDuration.Seconds()
57 I.F(
58 "%s %6d %s in the last %s (%6d %s, height %8d, %s) %0.2f tx/s",
59 b.progressAction,
60 b.receivedLogBlocks,
61 blockStr,
62 fmt.Sprintf("%0.1fs", tD),
63 b.receivedLogTx,
64 txStr, block.Height(),
65 block.WireBlock().Header.Timestamp,
66 float64(b.receivedLogTx)/tD,
67 )
68 b.receivedLogBlocks = 0
69 b.receivedLogTx = 0
70 b.lastBlockLogTime = now
71 }
72
73 func (b *blockProgressLogger) SetLastLogTime(time time.Time) {
74 b.lastBlockLogTime = time
75 }
76