golang - 시스템 상태 알기
import (
"encoding/json"
"io"
"net/http"
"runtime"
"strconv"
"sync"
"time"
)
// Stats represents activity status of Go.
type Stats struct {
Time int64 `json:"time"`
// runtime
GoVersion string `json:"go_version"`
GoOs string `json:"go_os"`
GoArch string `json:"go_arch"`
CpuNum int `json:"cpu_num"`
GoroutineNum int `json:"goroutine_num"`
Gomaxprocs int `json:"gomaxprocs"`
CgoCallNum int64 `json:"cgo_call_num"`
// memory
MemoryAlloc uint64 `json:"memory_alloc"`
MemoryTotalAlloc uint64 `json:"memory_total_alloc"`
MemorySys uint64 `json:"memory_sys"`
MemoryLookups uint64 `json:"memory_lookups"`
MemoryMallocs uint64 `json:"memory_mallocs"`
MemoryFrees uint64 `json:"memory_frees"`
// stack
StackInUse uint64 `json:"memory_stack"`
// heap
HeapAlloc uint64 `json:"heap_alloc"`
HeapSys uint64 `json:"heap_sys"`
HeapIdle uint64 `json:"heap_idle"`
HeapInuse uint64 `json:"heap_inuse"`
HeapReleased uint64 `json:"heap_released"`
HeapObjects uint64 `json:"heap_objects"`
// garbage collection
GcNext uint64 `json:"gc_next"`
GcLast uint64 `json:"gc_last"`
GcNum uint32 `json:"gc_num"`
GcPerSecond float64 `json:"gc_per_second"`
GcPausePerSecond float64 `json:"gc_pause_per_second"`
GcPause []float64 `json:"gc_pause"`
}
var lastSampleTime time.Time
var lastPauseNs uint64 = 0
var lastNumGc uint32 = 0
var nsInMs float64 = float64(time.Millisecond)
var statsMux sync.Mutex
func GetStats() *Stats {
statsMux.Lock()
defer statsMux.Unlock()
var mem runtime.MemStats
runtime.ReadMemStats(&mem)
now := time.Now()
var gcPausePerSecond float64
if lastPauseNs > 0 {
pauseSinceLastSample := mem.PauseTotalNs - lastPauseNs
gcPausePerSecond = float64(pauseSinceLastSample) / nsInMs
}
lastPauseNs = mem.PauseTotalNs
countGc := int(mem.NumGC - lastNumGc)
var gcPerSecond float64
if lastNumGc > 0 {
diff := float64(countGc)
diffTime := now.Sub(lastSampleTime).Seconds()
gcPerSecond = diff / diffTime
}
if countGc > 256 {
// lagging GC pause times
countGc = 256
}
gcPause := make([]float64, countGc)
for i := 0; i < countGc; i++ {
idx := int((mem.NumGC-uint32(i))+255) % 256
pause := float64(mem.PauseNs[idx])
gcPause[i] = pause / nsInMs
}
lastNumGc = mem.NumGC
lastSampleTime = time.Now()
return &Stats{
Time: now.UnixNano(),
GoVersion: runtime.Version(),
GoOs: runtime.GOOS,
GoArch: runtime.GOARCH,
CpuNum: runtime.NumCPU(),
GoroutineNum: runtime.NumGoroutine(),
Gomaxprocs: runtime.GOMAXPROCS(0),
CgoCallNum: runtime.NumCgoCall(),
// memory
MemoryAlloc: mem.Alloc,
MemoryTotalAlloc: mem.TotalAlloc,
MemorySys: mem.Sys,
MemoryLookups: mem.Lookups,
MemoryMallocs: mem.Mallocs,
MemoryFrees: mem.Frees,
// stack
StackInUse: mem.StackInuse,
// heap
HeapAlloc: mem.HeapAlloc,
HeapSys: mem.HeapSys,
HeapIdle: mem.HeapIdle,
HeapInuse: mem.HeapInuse,
HeapReleased: mem.HeapReleased,
HeapObjects: mem.HeapObjects,
// garbage collection
GcNext: mem.NextGC,
GcLast: mem.LastGC,
GcNum: mem.NumGC,
GcPerSecond: gcPerSecond,
GcPausePerSecond: gcPausePerSecond,
GcPause: gcPause,
}
}
이 글은 2019-10-04에 작성되었습니다.