func (self *percentilesContainerHandlerWrapper) GetStats() (*info.ContainerStats, error) { stats, err := self.handler.GetStats() if err != nil { return nil, err } if stats == nil { return nil, fmt.Errorf("container handler returns a nil error and a nil stats") } if stats.Timestamp.IsZero() { return nil, fmt.Errorf("container handler did not set timestamp") } self.lock.Lock() defer self.lock.Unlock() if self.prevStats != nil { sample, err := info.NewSample(self.prevStats, stats) if err != nil { return nil, fmt.Errorf("wrong stats: %v", err) } if sample != nil { self.sampler.Update(sample) } } self.updatePrevStats(stats) if self.containerPercentiles == nil { self.containerPercentiles = new(info.ContainerStatsPercentiles) } self.numStats++ if stats.Memory != nil { if stats.Memory.Usage > self.containerPercentiles.MaxMemoryUsage { self.containerPercentiles.MaxMemoryUsage = stats.Memory.Usage } } return stats, nil }
func NewSamplesFromStats(stats ...*info.ContainerStats) ([]*info.ContainerStatsSample, error) { if len(stats) < 2 { return nil, nil } samples := make([]*info.ContainerStatsSample, 0, len(stats)-1) for i, s := range stats[1:] { prev := stats[i] sample, err := info.NewSample(prev, s) if err != nil { return nil, fmt.Errorf("Unable to generate sample from %+v and %+v: %v", prev, s, err) } samples = append(samples, sample) } return samples, nil }
func (self *containerStorage) AddStats(stats *info.ContainerStats) error { self.lock.Lock() defer self.lock.Unlock() if self.prevStats != nil { sample, err := info.NewSample(self.prevStats, stats) if err != nil { return fmt.Errorf("wrong stats: %v", err) } if sample != nil { self.sampler.Update(sample) } } if stats.Memory != nil { if self.maxMemUsage < stats.Memory.Usage { self.maxMemUsage = stats.Memory.Usage } } if self.recentStats.Len() >= self.maxNumStats { self.recentStats.Remove(self.recentStats.Back()) } self.recentStats.PushFront(stats) self.updatePrevStats(stats) return nil }
func (self *influxdbStorage) containerStatsToValues( ref info.ContainerReference, stats *info.ContainerStats, ) (columns []string, values []interface{}) { // Timestamp columns = append(columns, colTimestamp) values = append(values, stats.Timestamp.Format(time.RFC3339Nano)) // Machine name columns = append(columns, colMachineName) values = append(values, self.machineName) // Container name columns = append(columns, colContainerName) if len(ref.Aliases) > 0 { values = append(values, ref.Aliases[0]) } else { values = append(values, ref.Name) } // Cumulative Cpu Usage columns = append(columns, colCpuCumulativeUsage) values = append(values, stats.Cpu.Usage.Total) // Memory Usage columns = append(columns, colMemoryUsage) values = append(values, stats.Memory.Usage) // Working set size columns = append(columns, colMemoryWorkingSet) values = append(values, stats.Memory.WorkingSet) // Optional: Network stats. if stats.Network != nil { columns = append(columns, colRxBytes) values = append(values, stats.Network.RxBytes) columns = append(columns, colRxErrors) values = append(values, stats.Network.RxErrors) columns = append(columns, colTxBytes) values = append(values, stats.Network.TxBytes) columns = append(columns, colTxErrors) values = append(values, stats.Network.TxErrors) } sample, err := info.NewSample(self.prevStats, stats) if err != nil || sample == nil { return columns, values } // DO NOT ADD ANY STATS BELOW THAT ARE NOT PART OF SAMPLING // Optional: sample duration. Unit: Nanosecond. columns = append(columns, colSampleDuration) values = append(values, sample.Duration.String()) // Optional: Instant cpu usage columns = append(columns, colCpuInstantUsage) values = append(values, sample.Cpu.Usage) return columns, values }
func (self *bigqueryStorage) containerStatsToValues( ref info.ContainerReference, stats *info.ContainerStats, ) (row map[string]interface{}) { row = make(map[string]interface{}) // Timestamp row[colTimestamp] = stats.Timestamp // Machine name row[colMachineName] = self.machineName // Container name name := ref.Name if len(ref.Aliases) > 0 { name = ref.Aliases[0] } row[colContainerName] = name // Cumulative Cpu Usage row[colCpuCumulativeUsage] = stats.Cpu.Usage.Total // Cumulative Cpu Usage in system mode row[colCpuCumulativeUsageSystem] = stats.Cpu.Usage.System // Cumulative Cpu Usage in user mode row[colCpuCumulativeUsageUser] = stats.Cpu.Usage.User // Memory Usage row[colMemoryUsage] = stats.Memory.Usage // Working set size row[colMemoryWorkingSet] = stats.Memory.WorkingSet // container page fault row[colMemoryContainerPgfault] = stats.Memory.ContainerData.Pgfault // container major page fault row[colMemoryContainerPgmajfault] = stats.Memory.ContainerData.Pgmajfault // hierarchical page fault row[colMemoryHierarchicalPgfault] = stats.Memory.HierarchicalData.Pgfault // hierarchical major page fault row[colMemoryHierarchicalPgmajfault] = stats.Memory.HierarchicalData.Pgmajfault // Optional: Network stats. if stats.Network != nil { row[colRxBytes] = stats.Network.RxBytes row[colRxErrors] = stats.Network.RxErrors row[colTxBytes] = stats.Network.TxBytes row[colTxErrors] = stats.Network.TxErrors } sample, err := info.NewSample(self.prevStats, stats) if err != nil || sample == nil { return } // TODO(jnagal): Handle per-cpu stats. // Optional: sample duration. Unit: Nanosecond. row[colSampleDuration] = sample.Duration // Optional: Instant cpu usage row[colCpuInstantUsage] = sample.Cpu.Usage return }
func (self *influxdbStorage) containerStatsToValues( ref info.ContainerReference, stats *info.ContainerStats, ) (columns []string, values []interface{}) { // Timestamp columns = append(columns, colTimestamp) values = append(values, stats.Timestamp.Format(time.RFC3339Nano)) // Machine name columns = append(columns, colMachineName) values = append(values, self.machineName) // Container name columns = append(columns, colContainerName) values = append(values, ref.Name) // Cumulative Cpu Usage columns = append(columns, colCpuCumulativeUsage) values = append(values, stats.Cpu.Usage.Total) // Cumulative Cpu Usage in system mode columns = append(columns, colCpuCumulativeUsageSystem) values = append(values, stats.Cpu.Usage.System) // Cumulative Cpu Usage in user mode columns = append(columns, colCpuCumulativeUsageUser) values = append(values, stats.Cpu.Usage.User) // Memory Usage columns = append(columns, colMemoryUsage) values = append(values, stats.Memory.Usage) // Working set size columns = append(columns, colMemoryWorkingSet) values = append(values, stats.Memory.WorkingSet) // container page fault columns = append(columns, colMemoryContainerPgfault) values = append(values, stats.Memory.ContainerData.Pgfault) // container major page fault columns = append(columns, colMemoryContainerPgmajfault) values = append(values, stats.Memory.ContainerData.Pgmajfault) // hierarchical page fault columns = append(columns, colMemoryHierarchicalPgfault) values = append(values, stats.Memory.HierarchicalData.Pgfault) // hierarchical major page fault columns = append(columns, colMemoryHierarchicalPgmajfault) values = append(values, stats.Memory.HierarchicalData.Pgmajfault) // per cpu cumulative usage for i, u := range stats.Cpu.Usage.PerCpu { columns = append(columns, fmt.Sprintf("%v%v", colPerCoreCumulativeUsagePrefix, i)) values = append(values, u) } sample, err := info.NewSample(self.prevStats, stats) if err != nil || sample == nil { return columns, values } // Optional: sample duration. Unit: Nanosecond. columns = append(columns, colSampleDuration) values = append(values, sample.Duration.String()) // Optional: Instant cpu usage columns = append(columns, colCpuInstantUsage) values = append(values, sample.Cpu.Usage) // Optional: Instant per core usage for i, u := range sample.Cpu.PerCpuUsage { columns = append(columns, fmt.Sprintf("%v%v", colPerCoreInstantUsagePrefix, i)) values = append(values, u) } return columns, values }