blocklogger.go raw

   1  package indexers
   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}
  23  //  ({numTxs}, height {lastBlockHeight}, {lastBlockTimeStamp})
  24  func newBlockProgressLogger(
  25  	progressMessage string,
  26  ) *blockProgressLogger {
  27  	return &blockProgressLogger{
  28  		lastBlockLogTime: time.Now(),
  29  		progressAction:   progressMessage,
  30  		// subsystemLogger:  logger,
  31  	}
  32  }
  33  
  34  // LogBlockHeight logs a new block height as an information message to show progress to the user. In order to prevent
  35  // spam, it limits logging to one message every 10 seconds with duration and totals included.
  36  func (b *blockProgressLogger) LogBlockHeight(block *block.Block) {
  37  	b.Lock()
  38  	defer b.Unlock()
  39  	b.receivedLogBlocks++
  40  	b.receivedLogTx += int64(len(block.WireBlock().Transactions))
  41  	now := time.Now()
  42  	duration := now.Sub(b.lastBlockLogTime)
  43  	if duration < time.Second*10 {
  44  		return
  45  	}
  46  	// Truncate the duration to 10s of milliseconds.
  47  	durationMillis := int64(duration / time.Millisecond)
  48  	tDuration := 10 * time.Millisecond * time.Duration(durationMillis/10)
  49  	// Log information about new block height.
  50  	blockStr := "blocks"
  51  	if b.receivedLogBlocks == 1 {
  52  		blockStr = "block "
  53  	}
  54  	txStr := "transactions"
  55  	if b.receivedLogTx == 1 {
  56  		txStr = "transaction "
  57  	}
  58  	I.F(
  59  		"%s %6d %s in the last %s (%6d %s, height %6d, %s)",
  60  		b.progressAction,
  61  		b.receivedLogBlocks,
  62  		blockStr,
  63  		fmt.Sprintf("%0.1fs", tDuration.Seconds()),
  64  		b.receivedLogTx,
  65  		txStr,
  66  		block.Height(),
  67  		block.WireBlock().Header.Timestamp,
  68  	)
  69  	b.receivedLogBlocks = 0
  70  	b.receivedLogTx = 0
  71  	b.lastBlockLogTime = now
  72  }
  73