github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/tendermint/trace/trace.go (about)

     1  package trace
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/log"
     8  )
     9  
    10  const (
    11  	GasUsed          = "GasUsed"
    12  	Produce          = "Produce"
    13  	RunTx            = "RunTx"
    14  	Height           = "Height"
    15  	Tx               = "Tx"
    16  	BlockSize        = "BlockSize"
    17  	Elapsed          = "Elapsed"
    18  	CommitRound      = "CommitRound"
    19  	Round            = "Round"
    20  	Evm              = "Evm"
    21  	Iavl             = "Iavl"
    22  	FlatKV           = "FlatKV"
    23  	WtxRatio         = "WtxRatio"
    24  	SigCacheRatio    = "SigCacheRatio"
    25  	DeliverTxs       = "DeliverTxs"
    26  	EvmHandlerDetail = "EvmHandlerDetail"
    27  	RunAnteDetail    = "RunAnteDetail"
    28  	AnteChainDetail  = "AnteChainDetail"
    29  
    30  	Delta = "Delta"
    31  
    32  	Abci       = "abci"
    33  	InvalidTxs = "InvalidTxs"
    34  	SaveResp   = "saveResp"
    35  	Persist    = "persist"
    36  	SaveState  = "saveState"
    37  
    38  	ApplyBlock = "ApplyBlock"
    39  	Consensus  = "Consensus"
    40  
    41  	MempoolCheckTxCnt = "checkTxCnt"
    42  	MempoolTxsCnt     = "mempoolTxsCnt"
    43  
    44  	Prerun = "Prerun"
    45  )
    46  
    47  type IElapsedTimeInfos interface {
    48  	AddInfo(key string, info string)
    49  	Dump(logger log.Logger)
    50  	SetElapsedTime(elapsedTime int64)
    51  	GetElapsedTime() int64
    52  }
    53  
    54  func SetInfoObject(e IElapsedTimeInfos) {
    55  	if e != nil {
    56  		elapsedInfo = e
    57  	}
    58  }
    59  
    60  var elapsedInfo IElapsedTimeInfos = &EmptyTimeInfo{}
    61  
    62  func GetElapsedInfo() IElapsedTimeInfos {
    63  	return elapsedInfo
    64  }
    65  
    66  type Tracer struct {
    67  	name             string
    68  	startTime        time.Time
    69  	lastPin          string
    70  	lastPinStartTime time.Time
    71  	pins             []string
    72  	intervals        []time.Duration
    73  	elapsedTime      time.Duration
    74  
    75  	pinMap map[string]time.Duration
    76  }
    77  
    78  func NewTracer(name string) *Tracer {
    79  	t := &Tracer{
    80  		startTime: time.Now(),
    81  		name:      name,
    82  		pinMap:    make(map[string]time.Duration),
    83  	}
    84  	return t
    85  }
    86  
    87  func (t *Tracer) Pin(format string, args ...interface{}) {
    88  	t.pinByFormat(fmt.Sprintf(format, args...))
    89  }
    90  
    91  func (t *Tracer) pinByFormat(tag string) {
    92  	if len(tag) == 0 {
    93  		//panic("invalid tag")
    94  		return
    95  	}
    96  
    97  	if len(t.pins) > 100 {
    98  		// 100 pins limitation
    99  		return
   100  	}
   101  
   102  	now := time.Now()
   103  
   104  	if len(t.lastPin) > 0 {
   105  		t.pins = append(t.pins, t.lastPin)
   106  		t.intervals = append(t.intervals, now.Sub(t.lastPinStartTime))
   107  	}
   108  	t.lastPinStartTime = now
   109  	t.lastPin = tag
   110  }
   111  
   112  func (t *Tracer) Format() string {
   113  	if len(t.pins) == 0 {
   114  		now := time.Now()
   115  		t.elapsedTime = now.Sub(t.startTime)
   116  		return fmt.Sprintf("%s<%dms>",
   117  			t.name,
   118  			t.elapsedTime.Milliseconds(),
   119  		)
   120  	}
   121  
   122  	t.Pin("_")
   123  
   124  	now := time.Now()
   125  	t.elapsedTime = now.Sub(t.startTime)
   126  	info := fmt.Sprintf("%s<%dms>",
   127  		t.name,
   128  		t.elapsedTime.Milliseconds(),
   129  	)
   130  
   131  	for i := range t.pins {
   132  		info += fmt.Sprintf(", %s<%dms>", t.pins[i], t.intervals[i].Milliseconds())
   133  	}
   134  	return info
   135  }
   136  
   137  func (t *Tracer) RepeatingPin(format string, args ...interface{}) {
   138  	if len(args) == 0 {
   139  		t.repeatingPinByFormat(format)
   140  	} else {
   141  		t.repeatingPinByFormat(fmt.Sprintf(format, args...))
   142  	}
   143  }
   144  
   145  func (t *Tracer) repeatingPinByFormat(tag string) {
   146  	if len(tag) == 0 {
   147  		//panic("invalid tag")
   148  		return
   149  	}
   150  
   151  	if len(t.pinMap) > 100 {
   152  		// 100 pins limitation
   153  		return
   154  	}
   155  
   156  	now := time.Now()
   157  
   158  	if len(t.lastPin) > 0 {
   159  		t.pinMap[t.lastPin] += now.Sub(t.lastPinStartTime)
   160  	}
   161  	t.lastPinStartTime = now
   162  	t.lastPin = tag
   163  }
   164  
   165  func (t *Tracer) FormatRepeatingPins(ignoredTags string) string {
   166  	var info, comma string
   167  
   168  	if len(t.pinMap) == 0 {
   169  		return info
   170  	}
   171  
   172  	t.RepeatingPin("_")
   173  
   174  	for tag, interval := range t.pinMap {
   175  		if tag == ignoredTags {
   176  			continue
   177  		}
   178  		info += fmt.Sprintf("%s%s<%dms>", comma, tag, interval.Milliseconds())
   179  		comma = ", "
   180  	}
   181  	return info
   182  }
   183  
   184  func (t *Tracer) GetElapsedTime() int64 {
   185  	return t.elapsedTime.Milliseconds()
   186  }
   187  
   188  func (t *Tracer) Reset() {
   189  	t.startTime = time.Now()
   190  	t.lastPin = ""
   191  	t.lastPinStartTime = time.Date(2018, 1, 1, 1, 1, 1, 1, time.Local)
   192  	t.pins = nil
   193  	t.intervals = nil
   194  	t.pinMap = make(map[string]time.Duration)
   195  }
   196  
   197  type EmptyTimeInfo struct {
   198  }
   199  
   200  func (e *EmptyTimeInfo) AddInfo(key string, info string) {
   201  }
   202  
   203  func (e *EmptyTimeInfo) Dump(logger log.Logger) {
   204  }
   205  
   206  func (e *EmptyTimeInfo) SetElapsedTime(elapsedTime int64) {
   207  }
   208  
   209  func (e *EmptyTimeInfo) GetElapsedTime() int64 {
   210  	return 0
   211  }