+
+func (c *StatsConnection) GetMemoryStats(memStats *api.MemoryStats) (err error) {
+ if err := c.updateStats(&c.memStatsData, MemoryStatSegPrefix, MemoryStatSegment, MemoryMainHeap); err != nil {
+ return err
+ }
+ convertStats := func(stats []adapter.Counter) api.MemoryCounters {
+ memUsg := make([]adapter.Counter, 7)
+ copy(memUsg, stats)
+ return api.MemoryCounters{
+ Total: uint64(memUsg[0]), Used: uint64(memUsg[1]), Free: uint64(memUsg[2]), UsedMMap: uint64(memUsg[3]),
+ TotalAlloc: uint64(memUsg[4]), FreeChunks: uint64(memUsg[5]), Releasable: uint64(memUsg[6]),
+ }
+ }
+
+ for _, stat := range c.memStatsData.Entries {
+ if strings.Contains(string(stat.Name), MemoryStatSegPrefix) {
+ _, f := path.Split(string(stat.Name))
+ var val float64
+ m, ok := stat.Data.(adapter.ScalarStat)
+ if ok {
+ val = float64(m)
+ }
+ switch f {
+ case MemoryStats_Total:
+ memStats.Total = val
+ case MemoryStats_Used:
+ memStats.Used = val
+ }
+ } else if string(stat.Name) == MemoryStatSegment {
+ if perHeapStats, ok := stat.Data.(adapter.SimpleCounterStat); ok {
+ if memStats.Stat == nil {
+ memStats.Stat = make(map[int]api.MemoryCounters)
+ }
+ for heap, stats := range perHeapStats {
+ memStats.Stat[heap] = convertStats(stats)
+ }
+ }
+ } else if string(stat.Name) == MemoryMainHeap {
+ if perHeapStats, ok := stat.Data.(adapter.SimpleCounterStat); ok {
+ if memStats.Main == nil {
+ memStats.Main = make(map[int]api.MemoryCounters)
+ }
+ for heap, stats := range perHeapStats {
+ memStats.Main[heap] = convertStats(stats)
+ }
+ }
+ }
+ }
+ return nil
+}
+
+func (c *StatsConnection) sendStatsConnEvent(event ConnectionEvent) {
+ select {
+ case c.connChan <- event:
+ default:
+ log.Warn("Stats connection state channel is full, discarding value.")
+ }
+}