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 }