github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/debug/stats/memory/memory.go (about)

     1  // Licensed under the Apache License, Version 2.0 (the "License");
     2  // you may not use this file except in compliance with the License.
     3  // You may obtain a copy of the License at
     4  //
     5  //     https://www.apache.org/licenses/LICENSE-2.0
     6  //
     7  // Unless required by applicable law or agreed to in writing, software
     8  // distributed under the License is distributed on an "AS IS" BASIS,
     9  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    10  // See the License for the specific language governing permissions and
    11  // limitations under the License.
    12  //
    13  // Original source: github.com/micro/go-micro/v3/debug/stats/memory/memory.go
    14  
    15  package stats
    16  
    17  import (
    18  	"runtime"
    19  	"sync"
    20  	"time"
    21  
    22  	"github.com/tickoalcantara12/micro/v3/service/debug/stats"
    23  	"github.com/tickoalcantara12/micro/v3/util/ring"
    24  )
    25  
    26  type memoryStats struct {
    27  	// used to store past stats
    28  	buffer *ring.Buffer
    29  
    30  	sync.RWMutex
    31  	started  int64
    32  	requests uint64
    33  	errors   uint64
    34  }
    35  
    36  func (s *memoryStats) snapshot() *stats.Stat {
    37  	s.RLock()
    38  	defer s.RUnlock()
    39  
    40  	var mstat runtime.MemStats
    41  	runtime.ReadMemStats(&mstat)
    42  
    43  	now := time.Now().Unix()
    44  
    45  	return &stats.Stat{
    46  		Timestamp: now,
    47  		Started:   s.started,
    48  		Uptime:    now - s.started,
    49  		Memory:    mstat.Alloc,
    50  		GC:        mstat.PauseTotalNs,
    51  		Threads:   uint64(runtime.NumGoroutine()),
    52  		Requests:  s.requests,
    53  		Errors:    s.errors,
    54  	}
    55  }
    56  
    57  func (s *memoryStats) Read() ([]*stats.Stat, error) {
    58  	buf := s.buffer.Get(s.buffer.Size())
    59  	var buffer []*stats.Stat
    60  
    61  	// get a value from the buffer if it exists
    62  	for _, b := range buf {
    63  		stat, ok := b.Value.(*stats.Stat)
    64  		if !ok {
    65  			continue
    66  		}
    67  		buffer = append(buffer, stat)
    68  	}
    69  
    70  	// get a snapshot
    71  	buffer = append(buffer, s.snapshot())
    72  
    73  	return buffer, nil
    74  }
    75  
    76  func (s *memoryStats) Write(stat *stats.Stat) error {
    77  	s.buffer.Put(stat)
    78  	return nil
    79  }
    80  
    81  func (s *memoryStats) Record(err error) error {
    82  	s.Lock()
    83  	defer s.Unlock()
    84  
    85  	// increment the total request count
    86  	s.requests++
    87  
    88  	// increment the error count
    89  	if err != nil {
    90  		s.errors++
    91  	}
    92  
    93  	return nil
    94  }
    95  
    96  // NewStats returns a new in memory stats buffer
    97  // TODO add options
    98  func NewStats() stats.Stats {
    99  	return &memoryStats{
   100  		started: time.Now().Unix(),
   101  		buffer:  ring.New(1),
   102  	}
   103  }