github.com/msales/pkg/v3@v3.24.0/stats/runtime.go (about)

     1  package stats
     2  
     3  import (
     4  	"context"
     5  	"runtime"
     6  	"time"
     7  )
     8  
     9  // DefaultRuntimeInterval is the default runtime ticker interval.
    10  var DefaultRuntimeInterval = 30 * time.Second
    11  
    12  // Runtime enters a loop, reporting runtime stats periodically.
    13  func Runtime(stats Stats) {
    14  	RuntimeEvery(stats, DefaultRuntimeInterval)
    15  }
    16  
    17  // RuntimeEvery enters a loop, reporting runtime stats at the specified interval.
    18  func RuntimeEvery(stats Stats, t time.Duration) {
    19  	c := time.Tick(t)
    20  	for range c {
    21  		r := newRuntimeStats()
    22  		r.send(stats)
    23  	}
    24  }
    25  
    26  // RuntimeFromContext is the same as RuntimeEvery but from context.
    27  func RuntimeFromContext(ctx context.Context, t time.Duration) {
    28  	if s, ok := FromContext(ctx); ok {
    29  		RuntimeEvery(s, t)
    30  	}
    31  }
    32  
    33  type runtimeStats struct {
    34  	*runtime.MemStats
    35  
    36  	goroutines int
    37  }
    38  
    39  func newRuntimeStats() *runtimeStats {
    40  	r := &runtimeStats{MemStats: &runtime.MemStats{}}
    41  	runtime.ReadMemStats(r.MemStats)
    42  	r.goroutines = runtime.NumGoroutine()
    43  
    44  	return r
    45  }
    46  
    47  func (r *runtimeStats) send(stats Stats) {
    48  	// CPU stats
    49  	stats.Gauge("runtime.cpu.goroutines", float64(r.goroutines), 1.0)
    50  
    51  	// Memory stats
    52  	// General
    53  	stats.Gauge("runtime.memory.alloc", float64(r.MemStats.Alloc), 1.0)
    54  	stats.Gauge("runtime.memory.total", float64(r.MemStats.TotalAlloc), 1.0)
    55  	stats.Gauge("runtime.memory.sys", float64(r.MemStats.Sys), 1.0)
    56  	stats.Gauge("runtime.memory.lookups", float64(r.MemStats.Lookups), 1.0)
    57  	stats.Gauge("runtime.memory.mallocs", float64(r.MemStats.Mallocs), 1.0)
    58  	stats.Gauge("runtime.memory.frees", float64(r.MemStats.Frees), 1.0)
    59  
    60  	// Heap
    61  	stats.Gauge("runtime.memory.heap.alloc", float64(r.MemStats.HeapAlloc), 1.0)
    62  	stats.Gauge("runtime.memory.heap.sys", float64(r.MemStats.HeapSys), 1.0)
    63  	stats.Gauge("runtime.memory.heap.idle", float64(r.MemStats.HeapIdle), 1.0)
    64  	stats.Gauge("runtime.memory.heap.inuse", float64(r.MemStats.HeapInuse), 1.0)
    65  	stats.Gauge("runtime.memory.heap.objects", float64(r.MemStats.HeapObjects), 1.0)
    66  	stats.Gauge("runtime.memory.heap.released", float64(r.MemStats.HeapReleased), 1.0)
    67  
    68  	// Stack
    69  	stats.Gauge("runtime.memory.stack.inuse", float64(r.MemStats.StackInuse), 1.0)
    70  	stats.Gauge("runtime.memory.stack.sys", float64(r.MemStats.StackSys), 1.0)
    71  	stats.Gauge("runtime.memory.stack.mcache_inuse", float64(r.MemStats.MCacheInuse), 1.0)
    72  	stats.Gauge("runtime.memory.stack.mcache_sys", float64(r.MemStats.MCacheSys), 1.0)
    73  	stats.Gauge("runtime.memory.stack.mspan_inuse", float64(r.MemStats.MSpanInuse), 1.0)
    74  	stats.Gauge("runtime.memory.stack.mspan_sys", float64(r.MemStats.MSpanSys), 1.0)
    75  
    76  	// GC
    77  	stats.Gauge("runtime.memory.gc.last", float64(r.MemStats.LastGC), 1.0)
    78  	stats.Gauge("runtime.memory.gc.next", float64(r.MemStats.NextGC), 1.0)
    79  	stats.Gauge("runtime.memory.gc.count", float64(r.MemStats.NumGC), 1.0)
    80  	stats.Timing("runtime.memory.gc.pause", time.Duration(r.MemStats.PauseTotalNs), 1.0)
    81  }