diff --git a/container/libcontainer/helpers.go b/container/libcontainer/helpers.go index 315bdf67..d11b5865 100644 --- a/container/libcontainer/helpers.go +++ b/container/libcontainer/helpers.go @@ -37,35 +37,40 @@ func toContainerStats(libcontainerStats *libcontainer.ContainerStats) *info.Cont s := libcontainerStats.CgroupStats ret := new(info.ContainerStats) ret.Timestamp = time.Now() - ret.Cpu = new(info.CpuStats) - ret.Cpu.Usage.User = s.CpuStats.CpuUsage.UsageInUsermode - ret.Cpu.Usage.System = s.CpuStats.CpuUsage.UsageInKernelmode - n := len(s.CpuStats.CpuUsage.PercpuUsage) - ret.Cpu.Usage.PerCpu = make([]uint64, n) - ret.Cpu.Usage.Total = 0 - for i := 0; i < n; i++ { - ret.Cpu.Usage.PerCpu[i] = s.CpuStats.CpuUsage.PercpuUsage[i] - ret.Cpu.Usage.Total += s.CpuStats.CpuUsage.PercpuUsage[i] - } - ret.Memory = new(info.MemoryStats) - ret.Memory.Usage = s.MemoryStats.Usage - if v, ok := s.MemoryStats.Stats["pgfault"]; ok { - ret.Memory.ContainerData.Pgfault = v - ret.Memory.HierarchicalData.Pgfault = v - } - if v, ok := s.MemoryStats.Stats["pgmajfault"]; ok { - ret.Memory.ContainerData.Pgmajfault = v - ret.Memory.HierarchicalData.Pgmajfault = v - } - if v, ok := s.MemoryStats.Stats["total_inactive_anon"]; ok { - ret.Memory.WorkingSet = ret.Memory.Usage - v - if v, ok := s.MemoryStats.Stats["total_active_file"]; ok { - ret.Memory.WorkingSet -= v + if s != nil { + ret.Cpu = new(info.CpuStats) + ret.Cpu.Usage.User = s.CpuStats.CpuUsage.UsageInUsermode + ret.Cpu.Usage.System = s.CpuStats.CpuUsage.UsageInKernelmode + n := len(s.CpuStats.CpuUsage.PercpuUsage) + ret.Cpu.Usage.PerCpu = make([]uint64, n) + + ret.Cpu.Usage.Total = 0 + for i := 0; i < n; i++ { + ret.Cpu.Usage.PerCpu[i] = s.CpuStats.CpuUsage.PercpuUsage[i] + ret.Cpu.Usage.Total += s.CpuStats.CpuUsage.PercpuUsage[i] + } + ret.Memory = new(info.MemoryStats) + ret.Memory.Usage = s.MemoryStats.Usage + if v, ok := s.MemoryStats.Stats["pgfault"]; ok { + ret.Memory.ContainerData.Pgfault = v + ret.Memory.HierarchicalData.Pgfault = v + } + if v, ok := s.MemoryStats.Stats["pgmajfault"]; ok { + ret.Memory.ContainerData.Pgmajfault = v + ret.Memory.HierarchicalData.Pgmajfault = v + } + if v, ok := s.MemoryStats.Stats["total_inactive_anon"]; ok { + ret.Memory.WorkingSet = ret.Memory.Usage - v + if v, ok := s.MemoryStats.Stats["total_active_file"]; ok { + ret.Memory.WorkingSet -= v + } } } // TODO(vishh): Perform a deep copy or alias libcontainer network stats. - ret.Network = (*info.NetworkStats)(&libcontainerStats.NetworkStats) + if libcontainerStats.NetworkStats != nil { + ret.Network = (*info.NetworkStats)(libcontainerStats.NetworkStats) + } return ret } diff --git a/info/container.go b/info/container.go index 194f77a3..48252a9c 100644 --- a/info/container.go +++ b/info/container.go @@ -241,21 +241,21 @@ type MemoryStatsMemoryData struct { type NetworkStats struct { // Cumulative count of bytes received. - RxBytes uint64 `json:"rx_bytes,omitempty"` + RxBytes uint64 `json:"rx_bytes"` // Cumulative count of packets received. - RxPackets uint64 `json:"rx_packets,omitempty"` + RxPackets uint64 `json:"rx_packets"` // Cumulative count of receive errors encountered. - RxErrors uint64 `json:"rx_errors,omitempty"` + RxErrors uint64 `json:"rx_errors"` // Cumulative count of packets dropped while receiving. - RxDropped uint64 `json:"rx_dropped,omitempty"` + RxDropped uint64 `json:"rx_dropped"` // Cumulative count of bytes transmitted. - TxBytes uint64 `json:"tx_bytes,omitempty"` + TxBytes uint64 `json:"tx_bytes"` // Cumulative count of packets transmitted. - TxPackets uint64 `json:"tx_packets,omitempty"` + TxPackets uint64 `json:"tx_packets"` // Cumulative count of transmit errors encountered. - TxErrors uint64 `json:"tx_errors,omitempty"` + TxErrors uint64 `json:"tx_errors"` // Cumulative count of packets dropped while transmitting. - TxDropped uint64 `json:"tx_dropped,omitempty"` + TxDropped uint64 `json:"tx_dropped"` } type ContainerStats struct { diff --git a/pages/containers.go b/pages/containers.go index b3302b17..be7c2e26 100644 --- a/pages/containers.go +++ b/pages/containers.go @@ -57,6 +57,7 @@ type pageData struct { ResourcesAvailable bool CpuAvailable bool MemoryAvailable bool + NetworkAvailable bool } func init() { @@ -204,6 +205,14 @@ func ServerContainersPage(m manager.Manager, w http.ResponseWriter, u *url.URL) } } + networkStatsAvailable := false + for _, stat := range cont.Stats { + if stat.Network != nil { + networkStatsAvailable = true + break + } + } + data := &pageData{ ContainerName: displayName, // TODO(vmarmol): Only use strings for this. @@ -215,6 +224,7 @@ func ServerContainersPage(m manager.Manager, w http.ResponseWriter, u *url.URL) ResourcesAvailable: cont.Spec.Cpu != nil || cont.Spec.Memory != nil, CpuAvailable: cont.Spec.Cpu != nil, MemoryAvailable: cont.Spec.Memory != nil, + NetworkAvailable: networkStatsAvailable, } err = pageTemplate.Execute(w, data) if err != nil { diff --git a/pages/containers_html.go b/pages/containers_html.go index fc5f9811..8cbaa3c3 100644 --- a/pages/containers_html.go +++ b/pages/containers_html.go @@ -16,153 +16,160 @@ package pages const containersHtmlTemplate = ` -
-