Skip to content

Instantly share code, notes, and snippets.

@enjoylife
Created February 18, 2014 07:40
Show Gist options
  • Save enjoylife/9066279 to your computer and use it in GitHub Desktop.
Save enjoylife/9066279 to your computer and use it in GitHub Desktop.
Runtime stats
func (self *Errplane) ReportRuntimeStats(prefix, context string,
dimensions Dimensions, sleep time.Duration) {
if self.runtimeStatsRunning {
fmt.Fprintf(os.Stderr, "Runtime stats is already running\n")
return
}
self.runtimeStatsRunning = true
go self.reportRuntimeStats(prefix, context, dimensions, sleep)
}
func (self *Errplane) reportRuntimeStats(prefix, context string,
dimensions Dimensions, sleep time.Duration) {
memStats := &runtime.MemStats{}
lastSampleTime := time.Now()
var lastPauseNs uint64 = 0
var lastNumGc uint32 = 0
nsInMs := float64(time.Millisecond)
for self.runtimeStatsRunning {
runtime.ReadMemStats(memStats)
now := time.Now()
self.Report(fmt.Sprintf("%s.goroutines", prefix),
float64(runtime.NumGoroutine()), now, context, dimensions)
self.Report(fmt.Sprintf("%s.memory.allocated", prefix),
float64(memStats.Alloc), now, context, dimensions)
self.Report(fmt.Sprintf("%s.memory.mallocs", prefix),
float64(memStats.Mallocs), now, context, dimensions)
self.Report(fmt.Sprintf("%s.memory.frees", prefix),
float64(memStats.Frees), now, context, dimensions)
self.Report(fmt.Sprintf("%s.memory.gc.total_pause", prefix),
float64(memStats.PauseTotalNs)/nsInMs, now, context, dimensions)
self.Report(fmt.Sprintf("%s.memory.heap", prefix),
float64(memStats.HeapAlloc), now, context, dimensions)
self.Report(fmt.Sprintf("%s.memory.stack", prefix),
float64(memStats.StackInuse), now, context, dimensions)
if lastPauseNs > 0 {
pauseSinceLastSample := memStats.PauseTotalNs - lastPauseNs
self.Report(fmt.Sprintf("%s.memory.gc.pause_per_second", prefix),
float64(pauseSinceLastSample)/nsInMs/sleep.Seconds(), now, context, dimensions)
}
lastPauseNs = memStats.PauseTotalNs
countGc := int(memStats.NumGC - lastNumGc)
if lastNumGc > 0 {
diff := float64(countGc)
diffTime := now.Sub(lastSampleTime).Seconds()
self.Report(fmt.Sprintf("%s.memory.gc.gc_per_second", prefix),
diff/diffTime, now, context, dimensions)
}
// get the individual pause times
if countGc > 0 {
if countGc > 256 {
fmt.Fprintf(os.Stderr, "We're missing some gc pause times")
countGc = 256
}
for i := 0; i < countGc; i++ {
idx := int((memStats.NumGC-uint32(i))+255) % 256
pause := float64(memStats.PauseNs[idx])
self.Aggregate(fmt.Sprintf("%s.memory.gc.pause", prefix),
pause/nsInMs, context, dimensions)
}
}
// keep track of the previous state
lastNumGc = memStats.NumGC
lastSampleTime = now
time.Sleep(sleep)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment