github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/common/counters/memory.go (about)

     1  package counters
     2  
     3  import (
     4  	"database/sql"
     5  	"runtime"
     6  	"sync"
     7  	"time"
     8  
     9  	c "github.com/Azareal/Gosora/common"
    10  	qgen "github.com/Azareal/Gosora/query_gen"
    11  	"github.com/pkg/errors"
    12  )
    13  
    14  var MemoryCounter *DefaultMemoryCounter
    15  
    16  type DefaultMemoryCounter struct {
    17  	insert *sql.Stmt
    18  
    19  	totMem     uint64
    20  	totCount   uint64
    21  	stackMem   uint64
    22  	stackCount uint64
    23  	heapMem    uint64
    24  	heapCount  uint64
    25  
    26  	sync.Mutex
    27  }
    28  
    29  func NewMemoryCounter(acc *qgen.Accumulator) (*DefaultMemoryCounter, error) {
    30  	co := &DefaultMemoryCounter{
    31  		insert: acc.Insert("memchunks").Columns("count,stack,heap,createdAt").Fields("?,?,?,UTC_TIMESTAMP()").Prepare(),
    32  	}
    33  	c.Tasks.FifteenMin.Add(co.Tick)
    34  	//c.Tasks.Sec.Add(co.Tick)
    35  	c.Tasks.Shutdown.Add(co.Tick)
    36  	ticker := time.NewTicker(time.Minute)
    37  	go func() {
    38  		defer c.EatPanics()
    39  		for {
    40  			select {
    41  			case <-ticker.C:
    42  				var m runtime.MemStats
    43  				runtime.ReadMemStats(&m)
    44  				co.Lock()
    45  				co.totCount++
    46  				co.totMem += m.Sys
    47  				co.stackCount++
    48  				co.stackMem += m.StackInuse
    49  				co.heapCount++
    50  				co.heapMem += m.HeapAlloc
    51  				co.Unlock()
    52  			}
    53  		}
    54  	}()
    55  	return co, acc.FirstError()
    56  }
    57  
    58  func (co *DefaultMemoryCounter) Tick() (e error) {
    59  	var m runtime.MemStats
    60  	runtime.ReadMemStats(&m)
    61  	var rTotMem, rTotCount, rStackMem, rStackCount, rHeapMem, rHeapCount uint64
    62  
    63  	co.Lock()
    64  
    65  	rTotMem = co.totMem
    66  	rTotCount = co.totCount
    67  	rStackMem = co.stackMem
    68  	rStackCount = co.stackCount
    69  	rHeapMem = co.heapMem
    70  	rHeapCount = co.heapCount
    71  
    72  	co.totMem = 0
    73  	co.totCount = 0
    74  	co.stackMem = 0
    75  	co.stackCount = 0
    76  	co.heapMem = 0
    77  	co.heapCount = 0
    78  
    79  	co.Unlock()
    80  
    81  	var avgMem, avgStack, avgHeap uint64
    82  	avgMem = (rTotMem + m.Sys) / (rTotCount + 1)
    83  	avgStack = (rStackMem + m.StackInuse) / (rStackCount + 1)
    84  	avgHeap = (rHeapMem + m.HeapAlloc) / (rHeapCount + 1)
    85  
    86  	c.DebugLogf("Inserting a memchunk with a value of %d - %d - %d", avgMem, avgStack, avgHeap)
    87  	_, e = co.insert.Exec(avgMem, avgStack, avgHeap)
    88  	if e != nil {
    89  		return errors.Wrap(errors.WithStack(e), "mem counter")
    90  	}
    91  	return nil
    92  }