github.com/annwntech/go-micro/v2@v2.9.5/debug/stats/default.go (about)

     1  package stats
     2  
     3  import (
     4  	"runtime"
     5  	"sync"
     6  	"time"
     7  
     8  	"github.com/annwntech/go-micro/v2/util/ring"
     9  )
    10  
    11  type stats struct {
    12  	// used to store past stats
    13  	buffer *ring.Buffer
    14  
    15  	sync.RWMutex
    16  	started  int64
    17  	requests uint64
    18  	errors   uint64
    19  }
    20  
    21  func (s *stats) snapshot() *Stat {
    22  	s.RLock()
    23  	defer s.RUnlock()
    24  
    25  	var mstat runtime.MemStats
    26  	runtime.ReadMemStats(&mstat)
    27  
    28  	now := time.Now().Unix()
    29  
    30  	return &Stat{
    31  		Timestamp: now,
    32  		Started:   s.started,
    33  		Uptime:    now - s.started,
    34  		Memory:    mstat.Alloc,
    35  		GC:        mstat.PauseTotalNs,
    36  		Threads:   uint64(runtime.NumGoroutine()),
    37  		Requests:  s.requests,
    38  		Errors:    s.errors,
    39  	}
    40  }
    41  
    42  func (s *stats) Read() ([]*Stat, error) {
    43  	// TODO adjustable size and optional read values
    44  	buf := s.buffer.Get(60)
    45  	var stats []*Stat
    46  
    47  	// get a value from the buffer if it exists
    48  	for _, b := range buf {
    49  		stat, ok := b.Value.(*Stat)
    50  		if !ok {
    51  			continue
    52  		}
    53  		stats = append(stats, stat)
    54  	}
    55  
    56  	// get a snapshot
    57  	stats = append(stats, s.snapshot())
    58  
    59  	return stats, nil
    60  }
    61  
    62  func (s *stats) Write(stat *Stat) error {
    63  	s.buffer.Put(stat)
    64  	return nil
    65  }
    66  
    67  func (s *stats) Record(err error) error {
    68  	s.Lock()
    69  	defer s.Unlock()
    70  
    71  	// increment the total request count
    72  	s.requests++
    73  
    74  	// increment the error count
    75  	if err != nil {
    76  		s.errors++
    77  	}
    78  
    79  	return nil
    80  }
    81  
    82  // NewStats returns a new in memory stats buffer
    83  // TODO add options
    84  func NewStats() Stats {
    85  	return &stats{
    86  		started: time.Now().Unix(),
    87  		buffer:  ring.New(60),
    88  	}
    89  }