github.com/btcsuite/btcd@v0.24.0/netsync/blocklogger.go (about)

     1  // Copyright (c) 2015-2017 The btcsuite developers
     2  // Use of this source code is governed by an ISC
     3  // license that can be found in the LICENSE file.
     4  
     5  package netsync
     6  
     7  import (
     8  	"fmt"
     9  	"sync"
    10  	"time"
    11  
    12  	"github.com/btcsuite/btcd/blockchain"
    13  	"github.com/btcsuite/btcd/btcutil"
    14  	"github.com/btcsuite/btclog"
    15  )
    16  
    17  // blockProgressLogger provides periodic logging for other services in order
    18  // to show users progress of certain "actions" involving some or all current
    19  // blocks. Ex: syncing to best chain, indexing all blocks, etc.
    20  type blockProgressLogger struct {
    21  	receivedLogBlocks int64
    22  	receivedLogTx     int64
    23  	lastBlockLogTime  time.Time
    24  
    25  	subsystemLogger btclog.Logger
    26  	progressAction  string
    27  	sync.Mutex
    28  }
    29  
    30  // newBlockProgressLogger returns a new block progress logger.
    31  // The progress message is templated as follows:
    32  //
    33  //	{progressAction} {numProcessed} {blocks|block} in the last {timePeriod}
    34  //	({numTxs}, height {lastBlockHeight}, {lastBlockTimeStamp})
    35  func newBlockProgressLogger(progressMessage string, logger btclog.Logger) *blockProgressLogger {
    36  	return &blockProgressLogger{
    37  		lastBlockLogTime: time.Now(),
    38  		progressAction:   progressMessage,
    39  		subsystemLogger:  logger,
    40  	}
    41  }
    42  
    43  // LogBlockHeight logs a new block height as an information message to show
    44  // progress to the user. In order to prevent spam, it limits logging to one
    45  // message every 10 seconds with duration and totals included.
    46  func (b *blockProgressLogger) LogBlockHeight(block *btcutil.Block, chain *blockchain.BlockChain) {
    47  	b.Lock()
    48  	defer b.Unlock()
    49  
    50  	b.receivedLogBlocks++
    51  	b.receivedLogTx += int64(len(block.MsgBlock().Transactions))
    52  
    53  	now := time.Now()
    54  	duration := now.Sub(b.lastBlockLogTime)
    55  	if duration < time.Second*10 {
    56  		return
    57  	}
    58  
    59  	// Truncate the duration to 10s of milliseconds.
    60  	durationMillis := int64(duration / time.Millisecond)
    61  	tDuration := 10 * time.Millisecond * time.Duration(durationMillis/10)
    62  
    63  	// Log information about new block height.
    64  	blockStr := "blocks"
    65  	if b.receivedLogBlocks == 1 {
    66  		blockStr = "block"
    67  	}
    68  	txStr := "transactions"
    69  	if b.receivedLogTx == 1 {
    70  		txStr = "transaction"
    71  	}
    72  	cacheSizeStr := fmt.Sprintf("~%d MiB", chain.CachedStateSize()/1024/1024)
    73  	b.subsystemLogger.Infof("%s %d %s in the last %s (%d %s, height %d, %s, %s cache)",
    74  		b.progressAction, b.receivedLogBlocks, blockStr, tDuration, b.receivedLogTx,
    75  		txStr, block.Height(), block.MsgBlock().Header.Timestamp, cacheSizeStr)
    76  
    77  	b.receivedLogBlocks = 0
    78  	b.receivedLogTx = 0
    79  	b.lastBlockLogTime = now
    80  }
    81  
    82  func (b *blockProgressLogger) SetLastLogTime(time time.Time) {
    83  	b.lastBlockLogTime = time
    84  }