diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 5bccb7d92c..4b4996c0f9 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -2002,188 +2002,188 @@ }, { "ImportPath": "github.com/google/cadvisor/accelerators", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/cache/memory", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/client/v2", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/collector", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/container", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/container/common", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/container/containerd", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/container/crio", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/container/docker", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/container/libcontainer", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/container/mesos", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/container/raw", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/container/rkt", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/container/systemd", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/devicemapper", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/events", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/fs", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/info/v1", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/info/v2", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/machine", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/manager", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/manager/watcher", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/manager/watcher/raw", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/manager/watcher/rkt", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/metrics", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/storage", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/summary", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/utils", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/utils/cloudinfo", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/utils/cpuload", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/utils/cpuload/netlink", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/utils/docker", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/utils/oomparser", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/utils/sysfs", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/utils/sysinfo", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/version", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/cadvisor/zfs", - "Comment": "v0.32.0", - "Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee" + "Comment": "v0.33.0", + "Rev": "511ec9ef821b334c3825cebb728208578c2300e8" }, { "ImportPath": "github.com/google/certificate-transparency-go", diff --git a/vendor/github.com/google/cadvisor/container/common/fsHandler.go b/vendor/github.com/google/cadvisor/container/common/fsHandler.go index 2a14358eb5..9de6a0f07f 100644 --- a/vendor/github.com/google/cadvisor/container/common/fsHandler.go +++ b/vendor/github.com/google/cadvisor/container/common/fsHandler.go @@ -51,7 +51,6 @@ type realFsHandler struct { } const ( - timeout = 2 * time.Minute maxBackoffFactor = 20 ) @@ -74,17 +73,16 @@ func NewFsHandler(period time.Duration, rootfs, extraDir string, fsInfo fs.FsInf func (fh *realFsHandler) update() error { var ( - baseUsage, extraDirUsage, inodeUsage uint64 - rootDiskErr, rootInodeErr, extraDiskErr error + rootUsage, extraUsage fs.UsageInfo + rootErr, extraErr error ) // TODO(vishh): Add support for external mounts. if fh.rootfs != "" { - baseUsage, rootDiskErr = fh.fsInfo.GetDirDiskUsage(fh.rootfs, timeout) - inodeUsage, rootInodeErr = fh.fsInfo.GetDirInodeUsage(fh.rootfs, timeout) + rootUsage, rootErr = fh.fsInfo.GetDirUsage(fh.rootfs) } if fh.extraDir != "" { - extraDirUsage, extraDiskErr = fh.fsInfo.GetDirDiskUsage(fh.extraDir, timeout) + extraUsage, extraErr = fh.fsInfo.GetDirUsage(fh.extraDir) } // Wait to handle errors until after all operartions are run. @@ -92,18 +90,17 @@ func (fh *realFsHandler) update() error { fh.Lock() defer fh.Unlock() fh.lastUpdate = time.Now() - if rootInodeErr == nil && fh.rootfs != "" { - fh.usage.InodeUsage = inodeUsage + if fh.rootfs != "" && rootErr == nil { + fh.usage.InodeUsage = rootUsage.Inodes + fh.usage.TotalUsageBytes = rootUsage.Bytes + extraUsage.Bytes } - if rootDiskErr == nil && fh.rootfs != "" { - fh.usage.TotalUsageBytes = baseUsage + extraDirUsage - } - if extraDiskErr == nil && fh.extraDir != "" { - fh.usage.BaseUsageBytes = baseUsage + if fh.extraDir != "" && extraErr == nil { + fh.usage.BaseUsageBytes = rootUsage.Bytes } + // Combine errors into a single error to return - if rootDiskErr != nil || rootInodeErr != nil || extraDiskErr != nil { - return fmt.Errorf("rootDiskErr: %v, rootInodeErr: %v, extraDiskErr: %v", rootDiskErr, rootInodeErr, extraDiskErr) + if rootErr != nil || extraErr != nil { + return fmt.Errorf("rootDiskErr: %v, extraDiskErr: %v", rootErr, extraErr) } return nil } @@ -132,7 +129,7 @@ func (fh *realFsHandler) trackUsage() { // if the long duration is persistent either because of slow // disk or lots of containers. longOp = longOp + time.Second - klog.V(2).Infof("du and find on following dirs took %v: %v; will not log again for this container unless duration exceeds %v", duration, []string{fh.rootfs, fh.extraDir}, longOp) + klog.V(2).Infof("fs: disk usage and inodes count on following dirs took %v: %v; will not log again for this container unless duration exceeds %v", duration, []string{fh.rootfs, fh.extraDir}, longOp) } } } diff --git a/vendor/github.com/google/cadvisor/container/common/helpers.go b/vendor/github.com/google/cadvisor/container/common/helpers.go index d38777f93b..3a84c2550f 100644 --- a/vendor/github.com/google/cadvisor/container/common/helpers.go +++ b/vendor/github.com/google/cadvisor/container/common/helpers.go @@ -134,7 +134,7 @@ func readString(dirpath string, file string) string { if err != nil { // Ignore non-existent files if !os.IsNotExist(err) { - klog.Errorf("readString: Failed to read %q: %s", cgroupFile, err) + klog.Warningf("readString: Failed to read %q: %s", cgroupFile, err) } return "" } diff --git a/vendor/github.com/google/cadvisor/container/containerd/factory.go b/vendor/github.com/google/cadvisor/container/containerd/factory.go index 2e2bb33346..2a7f9dd512 100644 --- a/vendor/github.com/google/cadvisor/container/containerd/factory.go +++ b/vendor/github.com/google/cadvisor/container/containerd/factory.go @@ -128,7 +128,7 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics return fmt.Errorf("failed to fetch containerd client version: %v", err) } - cgroupSubsystems, err := libcontainer.GetCgroupSubsystems() + cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics) if err != nil { return fmt.Errorf("failed to get cgroup subsystems: %v", err) } diff --git a/vendor/github.com/google/cadvisor/container/containerd/handler.go b/vendor/github.com/google/cadvisor/container/containerd/handler.go index 82aa8082c4..9e090d7fee 100644 --- a/vendor/github.com/google/cadvisor/container/containerd/handler.go +++ b/vendor/github.com/google/cadvisor/container/containerd/handler.go @@ -18,7 +18,6 @@ package containerd import ( "encoding/json" "fmt" - "path" "strings" "time" @@ -67,10 +66,7 @@ func newContainerdContainerHandler( includedMetrics container.MetricSet, ) (container.ContainerHandler, error) { // Create the cgroup paths. - cgroupPaths := make(map[string]string, len(cgroupSubsystems.MountPoints)) - for key, val := range cgroupSubsystems.MountPoints { - cgroupPaths[key] = path.Join(val, name) - } + cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name) // Generate the equivalent cgroup manager for this container. cgroupManager := &cgroupfs.Manager{ diff --git a/vendor/github.com/google/cadvisor/container/crio/factory.go b/vendor/github.com/google/cadvisor/container/crio/factory.go index 510b66f91c..b3380b02b5 100644 --- a/vendor/github.com/google/cadvisor/container/crio/factory.go +++ b/vendor/github.com/google/cadvisor/container/crio/factory.go @@ -149,7 +149,7 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics // TODO determine crio version so we can work differently w/ future versions if needed - cgroupSubsystems, err := libcontainer.GetCgroupSubsystems() + cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics) if err != nil { return fmt.Errorf("failed to get cgroup subsystems: %v", err) } diff --git a/vendor/github.com/google/cadvisor/container/crio/handler.go b/vendor/github.com/google/cadvisor/container/crio/handler.go index d17ba6d932..4078474fef 100644 --- a/vendor/github.com/google/cadvisor/container/crio/handler.go +++ b/vendor/github.com/google/cadvisor/container/crio/handler.go @@ -86,10 +86,7 @@ func newCrioContainerHandler( includedMetrics container.MetricSet, ) (container.ContainerHandler, error) { // Create the cgroup paths. - cgroupPaths := make(map[string]string, len(cgroupSubsystems.MountPoints)) - for key, val := range cgroupSubsystems.MountPoints { - cgroupPaths[key] = path.Join(val, name) - } + cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name) // Generate the equivalent cgroup manager for this container. cgroupManager := &cgroupfs.Manager{ diff --git a/vendor/github.com/google/cadvisor/container/docker/factory.go b/vendor/github.com/google/cadvisor/container/docker/factory.go index 7502781c43..5802be033e 100644 --- a/vendor/github.com/google/cadvisor/container/docker/factory.go +++ b/vendor/github.com/google/cadvisor/container/docker/factory.go @@ -325,7 +325,7 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics dockerAPIVersion, _ := APIVersion() - cgroupSubsystems, err := libcontainer.GetCgroupSubsystems() + cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics) if err != nil { return fmt.Errorf("failed to get cgroup subsystems: %v", err) } diff --git a/vendor/github.com/google/cadvisor/container/docker/handler.go b/vendor/github.com/google/cadvisor/container/docker/handler.go index 638350c092..ae8f48efa7 100644 --- a/vendor/github.com/google/cadvisor/container/docker/handler.go +++ b/vendor/github.com/google/cadvisor/container/docker/handler.go @@ -134,10 +134,7 @@ func newDockerContainerHandler( zfsWatcher *zfs.ZfsWatcher, ) (container.ContainerHandler, error) { // Create the cgroup paths. - cgroupPaths := make(map[string]string, len(cgroupSubsystems.MountPoints)) - for key, val := range cgroupSubsystems.MountPoints { - cgroupPaths[key] = path.Join(val, name) - } + cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name) // Generate the equivalent cgroup manager for this container. cgroupManager := &cgroupfs.Manager{ diff --git a/vendor/github.com/google/cadvisor/container/libcontainer/handler.go b/vendor/github.com/google/cadvisor/container/libcontainer/handler.go index 5b44fb7437..1951a1d670 100644 --- a/vendor/github.com/google/cadvisor/container/libcontainer/handler.go +++ b/vendor/github.com/google/cadvisor/container/libcontainer/handler.go @@ -66,8 +66,7 @@ func (h *Handler) GetStats() (*info.ContainerStats, error) { libcontainerStats := &libcontainer.Stats{ CgroupStats: cgroupStats, } - withPerCPU := h.includedMetrics.Has(container.PerCpuUsageMetrics) - stats := newContainerStats(libcontainerStats, withPerCPU) + stats := newContainerStats(libcontainerStats, h.includedMetrics) if h.includedMetrics.Has(container.ProcessSchedulerMetrics) { pids, err := h.cgroupManager.GetAllPids() @@ -599,14 +598,16 @@ func setNetworkStats(libcontainerStats *libcontainer.Stats, ret *info.ContainerS } } -func newContainerStats(libcontainerStats *libcontainer.Stats, withPerCPU bool) *info.ContainerStats { +func newContainerStats(libcontainerStats *libcontainer.Stats, includedMetrics container.MetricSet) *info.ContainerStats { ret := &info.ContainerStats{ Timestamp: time.Now(), } if s := libcontainerStats.CgroupStats; s != nil { - setCpuStats(s, ret, withPerCPU) - setDiskIoStats(s, ret) + setCpuStats(s, ret, includedMetrics.Has(container.PerCpuUsageMetrics)) + if includedMetrics.Has(container.DiskIOMetrics) { + setDiskIoStats(s, ret) + } setMemoryStats(s, ret) } if len(libcontainerStats.Interfaces) > 0 { diff --git a/vendor/github.com/google/cadvisor/container/libcontainer/helpers.go b/vendor/github.com/google/cadvisor/container/libcontainer/helpers.go index 05554465ca..9877d75a6d 100644 --- a/vendor/github.com/google/cadvisor/container/libcontainer/helpers.go +++ b/vendor/github.com/google/cadvisor/container/libcontainer/helpers.go @@ -19,6 +19,7 @@ import ( info "github.com/google/cadvisor/info/v1" + "github.com/google/cadvisor/container" "github.com/opencontainers/runc/libcontainer/cgroups" "k8s.io/klog" ) @@ -33,18 +34,36 @@ type CgroupSubsystems struct { MountPoints map[string]string } -// Get information about the cgroup subsystems. -func GetCgroupSubsystems() (CgroupSubsystems, error) { +// Get information about the cgroup subsystems those we want +func GetCgroupSubsystems(includedMetrics container.MetricSet) (CgroupSubsystems, error) { // Get all cgroup mounts. allCgroups, err := cgroups.GetCgroupMounts(true) if err != nil { return CgroupSubsystems{}, err } - return getCgroupSubsystemsHelper(allCgroups) + disableCgroups := map[string]struct{}{} + + //currently we only support disable blkio subsystem + if !includedMetrics.Has(container.DiskIOMetrics) { + disableCgroups["blkio"] = struct{}{} + } + return getCgroupSubsystemsHelper(allCgroups, disableCgroups) } -func getCgroupSubsystemsHelper(allCgroups []cgroups.Mount) (CgroupSubsystems, error) { +// Get information about all the cgroup subsystems. +func GetAllCgroupSubsystems() (CgroupSubsystems, error) { + // Get all cgroup mounts. + allCgroups, err := cgroups.GetCgroupMounts(true) + if err != nil { + return CgroupSubsystems{}, err + } + + emptyDisableCgroups := map[string]struct{}{} + return getCgroupSubsystemsHelper(allCgroups, emptyDisableCgroups) +} + +func getCgroupSubsystemsHelper(allCgroups []cgroups.Mount, disableCgroups map[string]struct{}) (CgroupSubsystems, error) { if len(allCgroups) == 0 { return CgroupSubsystems{}, fmt.Errorf("failed to find cgroup mounts") } @@ -55,6 +74,9 @@ func getCgroupSubsystemsHelper(allCgroups []cgroups.Mount) (CgroupSubsystems, er mountPoints := make(map[string]string, len(allCgroups)) for _, mount := range allCgroups { for _, subsystem := range mount.Subsystems { + if _, exists := disableCgroups[subsystem]; exists { + continue + } if _, ok := supportedSubsystems[subsystem]; !ok { // Unsupported subsystem continue diff --git a/vendor/github.com/google/cadvisor/container/mesos/factory.go b/vendor/github.com/google/cadvisor/container/mesos/factory.go index b2c61bb3fa..dd610a4320 100644 --- a/vendor/github.com/google/cadvisor/container/mesos/factory.go +++ b/vendor/github.com/google/cadvisor/container/mesos/factory.go @@ -130,7 +130,7 @@ func Register( return fmt.Errorf("unable to create mesos agent client: %v", err) } - cgroupSubsystems, err := libcontainer.GetCgroupSubsystems() + cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics) if err != nil { return fmt.Errorf("failed to get cgroup subsystems: %v", err) } diff --git a/vendor/github.com/google/cadvisor/container/mesos/handler.go b/vendor/github.com/google/cadvisor/container/mesos/handler.go index 65d0b9878e..3ad9ef8d6d 100644 --- a/vendor/github.com/google/cadvisor/container/mesos/handler.go +++ b/vendor/github.com/google/cadvisor/container/mesos/handler.go @@ -17,7 +17,6 @@ package mesos import ( "fmt" - "path" "github.com/google/cadvisor/container" "github.com/google/cadvisor/container/common" @@ -68,9 +67,6 @@ func newMesosContainerHandler( client mesosAgentClient, ) (container.ContainerHandler, error) { cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name) - for key, val := range cgroupSubsystems.MountPoints { - cgroupPaths[key] = path.Join(val, name) - } // Generate the equivalent cgroup manager for this container. cgroupManager := &cgroupfs.Manager{ diff --git a/vendor/github.com/google/cadvisor/container/mesos/mesos_agent.go b/vendor/github.com/google/cadvisor/container/mesos/mesos_agent.go index 20f921b9f6..108746cc98 100644 --- a/vendor/github.com/google/cadvisor/container/mesos/mesos_agent.go +++ b/vendor/github.com/google/cadvisor/container/mesos/mesos_agent.go @@ -113,8 +113,10 @@ func (s *state) fetchLabelsFromTask(exID string, labels map[string]string) error } } - for _, l := range t.Labels.Labels { - labels[l.Key] = *l.Value + if t.Labels != nil { + for _, l := range t.Labels.Labels { + labels[l.Key] = *l.Value + } } return nil diff --git a/vendor/github.com/google/cadvisor/container/raw/factory.go b/vendor/github.com/google/cadvisor/container/raw/factory.go index afc852e345..c42e473ffa 100644 --- a/vendor/github.com/google/cadvisor/container/raw/factory.go +++ b/vendor/github.com/google/cadvisor/container/raw/factory.go @@ -63,17 +63,20 @@ func (self *rawFactory) NewContainerHandler(name string, inHostNamespace bool) ( return newRawContainerHandler(name, self.cgroupSubsystems, self.machineInfoFactory, self.fsInfo, self.watcher, rootFs, self.includedMetrics) } -// The raw factory can handle any container. If --docker_only is set to false, non-docker containers are ignored. +// The raw factory can handle any container. If --docker_only is set to true, non-docker containers are ignored except for "/" and those whitelisted by raw_cgroup_prefix_whitelist flag. func (self *rawFactory) CanHandleAndAccept(name string) (bool, bool, error) { - accept := name == "/" || !*dockerOnly - + if name == "/" { + return true, true, nil + } + if *dockerOnly && self.rawPrefixWhiteList[0] == "" { + return true, false, nil + } for _, prefix := range self.rawPrefixWhiteList { if strings.HasPrefix(name, prefix) { - accept = true - break + return true, true, nil } } - return true, accept, nil + return true, false, nil } func (self *rawFactory) DebugInfo() map[string][]string { @@ -81,7 +84,7 @@ func (self *rawFactory) DebugInfo() map[string][]string { } func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics map[container.MetricKind]struct{}, rawPrefixWhiteList []string) error { - cgroupSubsystems, err := libcontainer.GetCgroupSubsystems() + cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics) if err != nil { return fmt.Errorf("failed to get cgroup subsystems: %v", err) } diff --git a/vendor/github.com/google/cadvisor/container/raw/handler.go b/vendor/github.com/google/cadvisor/container/raw/handler.go index 7e7504d933..c00e82d46b 100644 --- a/vendor/github.com/google/cadvisor/container/raw/handler.go +++ b/vendor/github.com/google/cadvisor/container/raw/handler.go @@ -39,8 +39,9 @@ type rawContainerHandler struct { // (e.g.: "cpu" -> "/sys/fs/cgroup/cpu/test") cgroupPaths map[string]string - fsInfo fs.FsInfo - externalMounts []common.Mount + fsInfo fs.FsInfo + externalMounts []common.Mount + includedMetrics container.MetricSet libcontainerHandler *libcontainer.Handler } @@ -86,6 +87,7 @@ func newRawContainerHandler(name string, cgroupSubsystems *libcontainer.CgroupSu cgroupPaths: cgroupPaths, fsInfo: fsInfo, externalMounts: externalMounts, + includedMetrics: includedMetrics, libcontainerHandler: handler, }, nil } @@ -185,36 +187,40 @@ func fsToFsStats(fs *fs.Fs) info.FsStats { } func (self *rawContainerHandler) getFsStats(stats *info.ContainerStats) error { - var allFs []fs.Fs - // Get Filesystem information only for the root cgroup. - if isRootCgroup(self.name) { - filesystems, err := self.fsInfo.GetGlobalFsInfo() - if err != nil { - return err + var filesystems []fs.Fs + + if self.includedMetrics.Has(container.DiskUsageMetrics) || self.includedMetrics.Has(container.DiskIOMetrics) { + var err error + // Get Filesystem information only for the root cgroup. + if isRootCgroup(self.name) { + filesystems, err = self.fsInfo.GetGlobalFsInfo() + if err != nil { + return err + } + } else if len(self.externalMounts) > 0 { + var mountSet map[string]struct{} + mountSet = make(map[string]struct{}) + for _, mount := range self.externalMounts { + mountSet[mount.HostDir] = struct{}{} + } + filesystems, err = self.fsInfo.GetFsInfoForPath(mountSet) + if err != nil { + return err + } } - for i := range filesystems { - fs := filesystems[i] - stats.Filesystem = append(stats.Filesystem, fsToFsStats(&fs)) - } - allFs = filesystems - } else if len(self.externalMounts) > 0 { - var mountSet map[string]struct{} - mountSet = make(map[string]struct{}) - for _, mount := range self.externalMounts { - mountSet[mount.HostDir] = struct{}{} - } - filesystems, err := self.fsInfo.GetFsInfoForPath(mountSet) - if err != nil { - return err - } - for i := range filesystems { - fs := filesystems[i] - stats.Filesystem = append(stats.Filesystem, fsToFsStats(&fs)) - } - allFs = filesystems } - common.AssignDeviceNamesToDiskStats(&fsNamer{fs: allFs, factory: self.machineInfoFactory}, &stats.DiskIo) + if self.includedMetrics.Has(container.DiskUsageMetrics) { + for i := range filesystems { + fs := filesystems[i] + stats.Filesystem = append(stats.Filesystem, fsToFsStats(&fs)) + } + } + + if self.includedMetrics.Has(container.DiskIOMetrics) { + common.AssignDeviceNamesToDiskStats(&fsNamer{fs: filesystems, factory: self.machineInfoFactory}, &stats.DiskIo) + + } return nil } diff --git a/vendor/github.com/google/cadvisor/container/rkt/factory.go b/vendor/github.com/google/cadvisor/container/rkt/factory.go index cf80603242..ab3397088f 100644 --- a/vendor/github.com/google/cadvisor/container/rkt/factory.go +++ b/vendor/github.com/google/cadvisor/container/rkt/factory.go @@ -78,7 +78,7 @@ func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, incl return fmt.Errorf("unable to get the RktPath variable %v", err) } - cgroupSubsystems, err := libcontainer.GetCgroupSubsystems() + cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics) if err != nil { return fmt.Errorf("failed to get cgroup subsystems: %v", err) } diff --git a/vendor/github.com/google/cadvisor/fs/fs.go b/vendor/github.com/google/cadvisor/fs/fs.go index e628b29ffd..fd1bae3df8 100644 --- a/vendor/github.com/google/cadvisor/fs/fs.go +++ b/vendor/github.com/google/cadvisor/fs/fs.go @@ -19,7 +19,6 @@ package fs import ( "bufio" - "bytes" "fmt" "io/ioutil" "os" @@ -30,7 +29,6 @@ import ( "strconv" "strings" "syscall" - "time" "github.com/docker/docker/pkg/mount" "github.com/google/cadvisor/devicemapper" @@ -47,8 +45,12 @@ const ( LabelCrioImages = "crio-images" ) -// The maximum number of `du` and `find` tasks that can be running at once. -const maxConcurrentOps = 20 +const ( + // The block size in bytes. + statBlockSize uint64 = 512 + // The maximum number of `disk usage` tasks that can be running at once. + maxConcurrentOps = 20 +) // A pool for restricting the number of consecutive `du` and `find` tasks running. var pool = make(chan struct{}, maxConcurrentOps) @@ -559,78 +561,73 @@ func (self *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) { return nil, fmt.Errorf("could not find device with major: %d, minor: %d in cached partitions map", major, minor) } -func (self *RealFsInfo) GetDirDiskUsage(dir string, timeout time.Duration) (uint64, error) { +func GetDirUsage(dir string) (UsageInfo, error) { + var usage UsageInfo + + if dir == "" { + return usage, fmt.Errorf("invalid directory") + } + + rootInfo, err := os.Stat(dir) + if err != nil { + return usage, fmt.Errorf("could not stat %q to get inode usage: %v", dir, err) + } + + rootStat, ok := rootInfo.Sys().(*syscall.Stat_t) + if !ok { + return usage, fmt.Errorf("unsuported fileinfo for getting inode usage of %q", dir) + } + + rootDevId := rootStat.Dev + + // dedupedInode stores inodes that could be duplicates (nlink > 1) + dedupedInodes := make(map[uint64]struct{}) + + err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if os.IsNotExist(err) { + // expected if files appear/vanish + return nil + } + if err != nil { + return fmt.Errorf("unable to count inodes for part of dir %s: %s", dir, err) + } + + // according to the docs, Sys can be nil + if info.Sys() == nil { + return fmt.Errorf("fileinfo Sys is nil") + } + + s, ok := info.Sys().(*syscall.Stat_t) + if !ok { + return fmt.Errorf("unsupported fileinfo; could not convert to stat_t") + } + + if s.Dev != rootDevId { + // don't descend into directories on other devices + return filepath.SkipDir + } + if s.Nlink > 1 { + if _, ok := dedupedInodes[s.Ino]; !ok { + // Dedupe things that could be hardlinks + dedupedInodes[s.Ino] = struct{}{} + + usage.Bytes += uint64(s.Blocks) * statBlockSize + usage.Inodes++ + } + } else { + usage.Bytes += uint64(s.Blocks) * statBlockSize + usage.Inodes++ + } + return nil + }) + + return usage, nil +} + +func (self *RealFsInfo) GetDirUsage(dir string) (UsageInfo, error) { claimToken() defer releaseToken() - return GetDirDiskUsage(dir, timeout) -} - -func GetDirDiskUsage(dir string, timeout time.Duration) (uint64, error) { - if dir == "" { - return 0, fmt.Errorf("invalid directory") - } - cmd := exec.Command("ionice", "-c3", "nice", "-n", "19", "du", "-s", dir) - stdoutp, err := cmd.StdoutPipe() - if err != nil { - return 0, fmt.Errorf("failed to setup stdout for cmd %v - %v", cmd.Args, err) - } - stderrp, err := cmd.StderrPipe() - if err != nil { - return 0, fmt.Errorf("failed to setup stderr for cmd %v - %v", cmd.Args, err) - } - - if err := cmd.Start(); err != nil { - return 0, fmt.Errorf("failed to exec du - %v", err) - } - timer := time.AfterFunc(timeout, func() { - klog.Warningf("Killing cmd %v due to timeout(%s)", cmd.Args, timeout.String()) - cmd.Process.Kill() - }) - stdoutb, souterr := ioutil.ReadAll(stdoutp) - if souterr != nil { - klog.Errorf("Failed to read from stdout for cmd %v - %v", cmd.Args, souterr) - } - stderrb, _ := ioutil.ReadAll(stderrp) - err = cmd.Wait() - timer.Stop() - if err != nil { - return 0, fmt.Errorf("du command failed on %s with output stdout: %s, stderr: %s - %v", dir, string(stdoutb), string(stderrb), err) - } - stdout := string(stdoutb) - usageInKb, err := strconv.ParseUint(strings.Fields(stdout)[0], 10, 64) - if err != nil { - return 0, fmt.Errorf("cannot parse 'du' output %s - %s", stdout, err) - } - return usageInKb * 1024, nil -} - -func (self *RealFsInfo) GetDirInodeUsage(dir string, timeout time.Duration) (uint64, error) { - claimToken() - defer releaseToken() - return GetDirInodeUsage(dir, timeout) -} - -func GetDirInodeUsage(dir string, timeout time.Duration) (uint64, error) { - if dir == "" { - return 0, fmt.Errorf("invalid directory") - } - var counter byteCounter - var stderr bytes.Buffer - findCmd := exec.Command("ionice", "-c3", "nice", "-n", "19", "find", dir, "-xdev", "-printf", ".") - findCmd.Stdout, findCmd.Stderr = &counter, &stderr - if err := findCmd.Start(); err != nil { - return 0, fmt.Errorf("failed to exec cmd %v - %v; stderr: %v", findCmd.Args, err, stderr.String()) - } - timer := time.AfterFunc(timeout, func() { - klog.Warningf("Killing cmd %v due to timeout(%s)", findCmd.Args, timeout.String()) - findCmd.Process.Kill() - }) - err := findCmd.Wait() - timer.Stop() - if err != nil { - return 0, fmt.Errorf("cmd %v failed. stderr: %s; err: %v", findCmd.Args, stderr.String(), err) - } - return counter.bytesWritten, nil + return GetDirUsage(dir) } func getVfsStats(path string) (total uint64, free uint64, avail uint64, inodes uint64, inodesFree uint64, err error) { diff --git a/vendor/github.com/google/cadvisor/fs/types.go b/vendor/github.com/google/cadvisor/fs/types.go index 59305819a5..5074f7132e 100644 --- a/vendor/github.com/google/cadvisor/fs/types.go +++ b/vendor/github.com/google/cadvisor/fs/types.go @@ -16,7 +16,6 @@ package fs import ( "errors" - "time" ) type DeviceInfo struct { @@ -62,6 +61,11 @@ type DiskStats struct { WeightedIoTime uint64 } +type UsageInfo struct { + Bytes uint64 + Inodes uint64 +} + // ErrNoSuchDevice is the error indicating the requested device does not exist. var ErrNoSuchDevice = errors.New("cadvisor: no such device") @@ -72,11 +76,8 @@ type FsInfo interface { // Returns capacity and free space, in bytes, of the set of mounts passed. GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, error) - // Returns number of bytes occupied by 'dir'. - GetDirDiskUsage(dir string, timeout time.Duration) (uint64, error) - - // Returns number of inodes used by 'dir'. - GetDirInodeUsage(dir string, timeout time.Duration) (uint64, error) + // GetDirUsage returns a usage information for 'dir'. + GetDirUsage(dir string) (UsageInfo, error) // GetDeviceInfoByFsUUID returns the information of the device with the // specified filesystem uuid. If no such device exists, this function will diff --git a/vendor/github.com/google/cadvisor/machine/machine.go b/vendor/github.com/google/cadvisor/machine/machine.go index 3a60e2e5c5..d85e38f193 100644 --- a/vendor/github.com/google/cadvisor/machine/machine.go +++ b/vendor/github.com/google/cadvisor/machine/machine.go @@ -16,12 +16,13 @@ package machine import ( + "bytes" "fmt" "io/ioutil" + "path/filepath" "regexp" "strconv" "strings" - // s390/s390x changes "runtime" @@ -36,9 +37,10 @@ import ( ) var ( - cpuRegExp = regexp.MustCompile(`^processor\s*:\s*([0-9]+)$`) - coreRegExp = regexp.MustCompile(`^core id\s*:\s*([0-9]+)$`) - nodeRegExp = regexp.MustCompile(`^physical id\s*:\s*([0-9]+)$`) + cpuRegExp = regexp.MustCompile(`^processor\s*:\s*([0-9]+)$`) + coreRegExp = regexp.MustCompile(`^core id\s*:\s*([0-9]+)$`) + nodeRegExp = regexp.MustCompile(`^physical id\s*:\s*([0-9]+)$`) + nodeBusRegExp = regexp.MustCompile(`^node([0-9]+)$`) // Power systems have a different format so cater for both cpuClockSpeedMHz = regexp.MustCompile(`(?:cpu MHz|clock)\s*:\s*([0-9]+\.[0-9]+)(?:MHz)?`) memoryCapacityRegexp = regexp.MustCompile(`MemTotal:\s*([0-9]+) kB`) @@ -46,6 +48,7 @@ var ( ) const maxFreqFile = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" +const cpuBusPath = "/sys/bus/cpu/devices/" // GetClockSpeed returns the CPU clock speed, given a []byte formatted as the /proc/cpuinfo file. func GetClockSpeed(procInfo []byte) (uint64, error) { @@ -127,6 +130,67 @@ func parseCapacity(b []byte, r *regexp.Regexp) (uint64, error) { return m * 1024, err } +/* Look for sysfs cpu path containing core_id */ +/* Such as: sys/bus/cpu/devices/cpu0/topology/core_id */ +func getCoreIdFromCpuBus(cpuBusPath string, threadId int) (int, error) { + path := filepath.Join(cpuBusPath, fmt.Sprintf("cpu%d/topology", threadId)) + file := filepath.Join(path, "core_id") + + num, err := ioutil.ReadFile(file) + if err != nil { + return threadId, err + } + + coreId, err := strconv.ParseInt(string(bytes.TrimSpace(num)), 10, 32) + if err != nil { + return threadId, err + } + + if coreId < 0 { + // report threadId if found coreId < 0 + coreId = int64(threadId) + } + + return int(coreId), nil +} + +/* Look for sysfs cpu path containing node id */ +/* Such as: /sys/bus/cpu/devices/cpu0/node%d */ +func getNodeIdFromCpuBus(cpuBusPath string, threadId int) (int, error) { + path := filepath.Join(cpuBusPath, fmt.Sprintf("cpu%d", threadId)) + + files, err := ioutil.ReadDir(path) + if err != nil { + return 0, err + } + + nodeId := 0 + for _, file := range files { + filename := file.Name() + + isNode, error := regexp.MatchString("^node([0-9]+)$", filename) + if error != nil { + continue + } + if !isNode { + continue + } + + ok, val, _ := extractValue(filename, nodeBusRegExp) + if err != nil { + continue + } + if ok { + if val < 0 { + continue + } + nodeId = val + } + } + + return nodeId, nil +} + func GetTopology(sysFs sysfs.SysFs, cpuinfo string) ([]info.Node, int, error) { nodes := []info.Node{} @@ -161,8 +225,36 @@ func GetTopology(sysFs sysfs.SysFs, cpuinfo string) ([]info.Node, int, error) { lastNode = -1 } lastThread = thread + + /* On Arm platform, no 'core id' and 'physical id' in '/proc/cpuinfo'. */ + /* So we search sysfs cpu path directly. */ + /* This method can also be used on other platforms, such as x86, ppc64le... */ + /* /sys/bus/cpu/devices/cpu%d contains the information of 'core_id' & 'node_id'. */ + /* Such as: /sys/bus/cpu/devices/cpu0/topology/core_id */ + /* Such as: /sys/bus/cpu/devices/cpu0/node0 */ + if isAArch64() { + val, err = getCoreIdFromCpuBus(cpuBusPath, lastThread) + if err != nil { + // Report thread id if no NUMA + val = lastThread + } + lastCore = val + + val, err = getNodeIdFromCpuBus(cpuBusPath, lastThread) + if err != nil { + // Report node 0 if no NUMA + val = 0 + } + lastNode = val + } continue } + + if isAArch64() { + /* On Arm platform, no 'core id' and 'physical id' in '/proc/cpuinfo'. */ + continue + } + ok, val, err = extractValue(line, coreRegExp) if err != nil { return nil, -1, fmt.Errorf("could not parse core info from %q: %v", line, err) @@ -171,6 +263,7 @@ func GetTopology(sysFs sysfs.SysFs, cpuinfo string) ([]info.Node, int, error) { lastCore = val continue } + ok, val, err = extractValue(line, nodeRegExp) if err != nil { return nil, -1, fmt.Errorf("could not parse node info from %q: %v", line, err) @@ -180,6 +273,7 @@ func GetTopology(sysFs sysfs.SysFs, cpuinfo string) ([]info.Node, int, error) { continue } } + nodeIdx, err := addNode(&nodes, lastNode) if err != nil { return nil, -1, fmt.Errorf("failed to add node %d: %v", lastNode, err) diff --git a/vendor/github.com/google/cadvisor/manager/manager.go b/vendor/github.com/google/cadvisor/manager/manager.go index 5c62bd66eb..2fae119012 100644 --- a/vendor/github.com/google/cadvisor/manager/manager.go +++ b/vendor/github.com/google/cadvisor/manager/manager.go @@ -56,6 +56,7 @@ import ( ) var globalHousekeepingInterval = flag.Duration("global_housekeeping_interval", 1*time.Minute, "Interval between global housekeepings") +var updateMachineInfoInterval = flag.Duration("update_machine_info_interval", 5*time.Minute, "Interval between machine info updates.") var logCadvisorUsage = flag.Bool("log_cadvisor_usage", false, "Whether to log the usage of the cAdvisor container") var eventStorageAgeLimit = flag.String("event_storage_age_limit", "default=24h", "Max length of time for which to store events (per type). Value is a comma separated list of key values, where the keys are event types (e.g.: creation, oom) or \"default\" and the value is a duration. Default is applied to all non-specified event types") var eventStorageEventLimit = flag.String("event_storage_event_limit", "default=100000", "Max number of events to store (per type). Value is a comma separated list of key values, where the keys are event types (e.g.: creation, oom) or \"default\" and the value is an integer. Default is applied to all non-specified event types") @@ -208,6 +209,7 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, maxHousekeepingIn quitChannels: make([]chan error, 0, 2), memoryCache: memoryCache, fsInfo: fsInfo, + sysFs: sysfs, cadvisorContainer: selfContainer, inHostNamespace: inHostNamespace, startupTime: time.Now(), @@ -277,6 +279,8 @@ type manager struct { containersLock sync.RWMutex memoryCache *memory.InMemoryCache fsInfo fs.FsInfo + sysFs sysfs.SysFs + machineMu sync.RWMutex // protects machineInfo machineInfo info.MachineInfo quitChannels []chan error cadvisorContainer string @@ -382,6 +386,10 @@ func (self *manager) Start() error { self.quitChannels = append(self.quitChannels, quitGlobalHousekeeping) go self.globalHousekeeping(quitGlobalHousekeeping) + quitUpdateMachineInfo := make(chan error) + self.quitChannels = append(self.quitChannels, quitUpdateMachineInfo) + go self.updateMachineInfo(quitUpdateMachineInfo) + return nil } @@ -402,6 +410,28 @@ func (self *manager) Stop() error { return nil } +func (self *manager) updateMachineInfo(quit chan error) { + ticker := time.NewTicker(*updateMachineInfoInterval) + for { + select { + case <-ticker.C: + info, err := machine.Info(self.sysFs, self.fsInfo, self.inHostNamespace) + if err != nil { + klog.Errorf("Could not get machine info: %v", err) + break + } + self.machineMu.Lock() + self.machineInfo = *info + self.machineMu.Unlock() + klog.V(5).Infof("Update machine info: %+v", *info) + case <-quit: + ticker.Stop() + quit <- nil + return + } + } +} + func (self *manager) globalHousekeeping(quit chan error) { // Long housekeeping is either 100ms or half of the housekeeping interval. longHousekeeping := 100 * time.Millisecond @@ -501,7 +531,9 @@ func (self *manager) getAdjustedSpec(cinfo *containerInfo) info.ContainerSpec { if spec.HasMemory { // Memory.Limit is 0 means there's no limit if spec.Memory.Limit == 0 { + self.machineMu.RLock() spec.Memory.Limit = uint64(self.machineInfo.MemoryCapacity) + self.machineMu.RUnlock() } } return spec @@ -834,6 +866,8 @@ func (self *manager) GetFsInfo(label string) ([]v2.FsInfo, error) { } func (m *manager) GetMachineInfo() (*info.MachineInfo, error) { + m.machineMu.RLock() + defer m.machineMu.RUnlock() // Copy and return the MachineInfo. return &m.machineInfo, nil } diff --git a/vendor/github.com/google/cadvisor/manager/watcher/raw/raw.go b/vendor/github.com/google/cadvisor/manager/watcher/raw/raw.go index 76983cbe00..9dee46b658 100644 --- a/vendor/github.com/google/cadvisor/manager/watcher/raw/raw.go +++ b/vendor/github.com/google/cadvisor/manager/watcher/raw/raw.go @@ -45,7 +45,7 @@ type rawContainerWatcher struct { } func NewRawContainerWatcher() (watcher.ContainerWatcher, error) { - cgroupSubsystems, err := libcontainer.GetCgroupSubsystems() + cgroupSubsystems, err := libcontainer.GetAllCgroupSubsystems() if err != nil { return nil, fmt.Errorf("failed to get cgroup subsystems: %v", err) } diff --git a/vendor/github.com/google/cadvisor/metrics/prometheus.go b/vendor/github.com/google/cadvisor/metrics/prometheus.go index 38502743ed..a74039fdb6 100644 --- a/vendor/github.com/google/cadvisor/metrics/prometheus.go +++ b/vendor/github.com/google/cadvisor/metrics/prometheus.go @@ -21,7 +21,6 @@ import ( "github.com/google/cadvisor/container" info "github.com/google/cadvisor/info/v1" - "github.com/prometheus/client_golang/prometheus" "k8s.io/klog" ) @@ -40,8 +39,9 @@ type infoProvider interface { // metricValue describes a single metric value for a given set of label values // within a parent containerMetric. type metricValue struct { - value float64 - labels []string + value float64 + labels []string + timestamp time.Time } type metricValues []metricValue @@ -55,30 +55,35 @@ func asNanosecondsToSeconds(v uint64) float64 { } // fsValues is a helper method for assembling per-filesystem stats. -func fsValues(fsStats []info.FsStats, valueFn func(*info.FsStats) float64) metricValues { +func fsValues(fsStats []info.FsStats, valueFn func(*info.FsStats) float64, timestamp time.Time) metricValues { values := make(metricValues, 0, len(fsStats)) for _, stat := range fsStats { values = append(values, metricValue{ - value: valueFn(&stat), - labels: []string{stat.Device}, + value: valueFn(&stat), + labels: []string{stat.Device}, + timestamp: timestamp, }) } return values } // ioValues is a helper method for assembling per-disk and per-filesystem stats. -func ioValues(ioStats []info.PerDiskStats, ioType string, ioValueFn func(uint64) float64, fsStats []info.FsStats, valueFn func(*info.FsStats) float64) metricValues { +func ioValues(ioStats []info.PerDiskStats, ioType string, ioValueFn func(uint64) float64, + fsStats []info.FsStats, valueFn func(*info.FsStats) float64, timestamp time.Time) metricValues { + values := make(metricValues, 0, len(ioStats)+len(fsStats)) for _, stat := range ioStats { values = append(values, metricValue{ - value: ioValueFn(stat.Stats[ioType]), - labels: []string{stat.Device}, + value: ioValueFn(stat.Stats[ioType]), + labels: []string{stat.Device}, + timestamp: timestamp, }) } for _, stat := range fsStats { values = append(values, metricValue{ - value: valueFn(&stat), - labels: []string{stat.Device}, + value: valueFn(&stat), + labels: []string{stat.Device}, + timestamp: timestamp, }) } return values @@ -134,7 +139,10 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri help: "Last time a container was seen by the exporter", valueType: prometheus.GaugeValue, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(time.Now().Unix())}} + return metricValues{{ + value: float64(time.Now().Unix()), + timestamp: time.Now(), + }} }, }, }, @@ -147,14 +155,24 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri help: "Cumulative user cpu time consumed in seconds.", valueType: prometheus.CounterValue, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Cpu.Usage.User) / float64(time.Second)}} + return metricValues{ + { + value: float64(s.Cpu.Usage.User) / float64(time.Second), + timestamp: s.Timestamp, + }, + } }, }, { name: "container_cpu_system_seconds_total", help: "Cumulative system cpu time consumed in seconds.", valueType: prometheus.CounterValue, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Cpu.Usage.System) / float64(time.Second)}} + return metricValues{ + { + value: float64(s.Cpu.Usage.System) / float64(time.Second), + timestamp: s.Timestamp, + }, + } }, }, { name: "container_cpu_usage_seconds_total", @@ -165,8 +183,9 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri if len(s.Cpu.Usage.PerCpu) == 0 { if s.Cpu.Usage.Total > 0 { return metricValues{{ - value: float64(s.Cpu.Usage.Total) / float64(time.Second), - labels: []string{"total"}, + value: float64(s.Cpu.Usage.Total) / float64(time.Second), + labels: []string{"total"}, + timestamp: s.Timestamp, }} } } @@ -174,8 +193,9 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri for i, value := range s.Cpu.Usage.PerCpu { if value > 0 { values = append(values, metricValue{ - value: float64(value) / float64(time.Second), - labels: []string{fmt.Sprintf("cpu%02d", i)}, + value: float64(value) / float64(time.Second), + labels: []string{fmt.Sprintf("cpu%02d", i)}, + timestamp: s.Timestamp, }) } } @@ -187,7 +207,11 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri valueType: prometheus.CounterValue, condition: func(s info.ContainerSpec) bool { return s.Cpu.Quota != 0 }, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Cpu.CFS.Periods)}} + return metricValues{ + { + value: float64(s.Cpu.CFS.Periods), + timestamp: s.Timestamp, + }} }, }, { name: "container_cpu_cfs_throttled_periods_total", @@ -195,7 +219,11 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri valueType: prometheus.CounterValue, condition: func(s info.ContainerSpec) bool { return s.Cpu.Quota != 0 }, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Cpu.CFS.ThrottledPeriods)}} + return metricValues{ + { + value: float64(s.Cpu.CFS.ThrottledPeriods), + timestamp: s.Timestamp, + }} }, }, { name: "container_cpu_cfs_throttled_seconds_total", @@ -203,7 +231,11 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri valueType: prometheus.CounterValue, condition: func(s info.ContainerSpec) bool { return s.Cpu.Quota != 0 }, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Cpu.CFS.ThrottledTime) / float64(time.Second)}} + return metricValues{ + { + value: float64(s.Cpu.CFS.ThrottledTime) / float64(time.Second), + timestamp: s.Timestamp, + }} }, }, }...) @@ -215,21 +247,30 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri help: "Time duration the processes of the container have run on the CPU.", valueType: prometheus.CounterValue, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Cpu.Schedstat.RunTime) / float64(time.Second)}} + return metricValues{{ + value: float64(s.Cpu.Schedstat.RunTime) / float64(time.Second), + timestamp: s.Timestamp, + }} }, }, { name: "container_cpu_schedstat_runqueue_seconds_total", help: "Time duration processes of the container have been waiting on a runqueue.", valueType: prometheus.CounterValue, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Cpu.Schedstat.RunqueueTime) / float64(time.Second)}} + return metricValues{{ + value: float64(s.Cpu.Schedstat.RunqueueTime) / float64(time.Second), + timestamp: s.Timestamp, + }} }, }, { name: "container_cpu_schedstat_run_periods_total", help: "Number of times processes of the cgroup have run on the cpu", valueType: prometheus.CounterValue, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Cpu.Schedstat.RunPeriods)}} + return metricValues{{ + value: float64(s.Cpu.Schedstat.RunPeriods), + timestamp: s.Timestamp, + }} }, }, }...) @@ -241,7 +282,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri help: "Value of container cpu load average over the last 10 seconds.", valueType: prometheus.GaugeValue, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Cpu.LoadAverage)}} + return metricValues{{value: float64(s.Cpu.LoadAverage), timestamp: s.Timestamp}} }, }, { name: "container_tasks_state", @@ -251,24 +292,29 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri getValues: func(s *info.ContainerStats) metricValues { return metricValues{ { - value: float64(s.TaskStats.NrSleeping), - labels: []string{"sleeping"}, + value: float64(s.TaskStats.NrSleeping), + labels: []string{"sleeping"}, + timestamp: s.Timestamp, }, { - value: float64(s.TaskStats.NrRunning), - labels: []string{"running"}, + value: float64(s.TaskStats.NrRunning), + labels: []string{"running"}, + timestamp: s.Timestamp, }, { - value: float64(s.TaskStats.NrStopped), - labels: []string{"stopped"}, + value: float64(s.TaskStats.NrStopped), + labels: []string{"stopped"}, + timestamp: s.Timestamp, }, { - value: float64(s.TaskStats.NrUninterruptible), - labels: []string{"uninterruptible"}, + value: float64(s.TaskStats.NrUninterruptible), + labels: []string{"uninterruptible"}, + timestamp: s.Timestamp, }, { - value: float64(s.TaskStats.NrIoWait), - labels: []string{"iowaiting"}, + value: float64(s.TaskStats.NrIoWait), + labels: []string{"iowaiting"}, + timestamp: s.Timestamp, }, } }, @@ -282,42 +328,45 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri help: "Number of bytes of page cache memory.", valueType: prometheus.GaugeValue, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Memory.Cache)}} + return metricValues{{value: float64(s.Memory.Cache), timestamp: s.Timestamp}} }, }, { name: "container_memory_rss", help: "Size of RSS in bytes.", valueType: prometheus.GaugeValue, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Memory.RSS)}} + return metricValues{{value: float64(s.Memory.RSS), timestamp: s.Timestamp}} }, }, { name: "container_memory_mapped_file", help: "Size of memory mapped files in bytes.", valueType: prometheus.GaugeValue, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Memory.MappedFile)}} + return metricValues{{value: float64(s.Memory.MappedFile), timestamp: s.Timestamp}} }, }, { name: "container_memory_swap", help: "Container swap usage in bytes.", valueType: prometheus.GaugeValue, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Memory.Swap)}} + return metricValues{{value: float64(s.Memory.Swap), timestamp: s.Timestamp}} }, }, { name: "container_memory_failcnt", help: "Number of memory usage hits limits", valueType: prometheus.CounterValue, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Memory.Failcnt)}} + return metricValues{{ + value: float64(s.Memory.Failcnt), + timestamp: s.Timestamp, + }} }, }, { name: "container_memory_usage_bytes", help: "Current memory usage in bytes, including all memory regardless of when it was accessed", valueType: prometheus.GaugeValue, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Memory.Usage)}} + return metricValues{{value: float64(s.Memory.Usage), timestamp: s.Timestamp}} }, }, { @@ -325,14 +374,14 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri help: "Maximum memory usage recorded in bytes", valueType: prometheus.GaugeValue, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Memory.MaxUsage)}} + return metricValues{{value: float64(s.Memory.MaxUsage), timestamp: s.Timestamp}} }, }, { name: "container_memory_working_set_bytes", help: "Current working set in bytes.", valueType: prometheus.GaugeValue, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Memory.WorkingSet)}} + return metricValues{{value: float64(s.Memory.WorkingSet), timestamp: s.Timestamp}} }, }, { name: "container_memory_failures_total", @@ -342,20 +391,24 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri getValues: func(s *info.ContainerStats) metricValues { return metricValues{ { - value: float64(s.Memory.ContainerData.Pgfault), - labels: []string{"pgfault", "container"}, + value: float64(s.Memory.ContainerData.Pgfault), + labels: []string{"pgfault", "container"}, + timestamp: s.Timestamp, }, { - value: float64(s.Memory.ContainerData.Pgmajfault), - labels: []string{"pgmajfault", "container"}, + value: float64(s.Memory.ContainerData.Pgmajfault), + labels: []string{"pgmajfault", "container"}, + timestamp: s.Timestamp, }, { - value: float64(s.Memory.HierarchicalData.Pgfault), - labels: []string{"pgfault", "hierarchy"}, + value: float64(s.Memory.HierarchicalData.Pgfault), + labels: []string{"pgfault", "hierarchy"}, + timestamp: s.Timestamp, }, { - value: float64(s.Memory.HierarchicalData.Pgmajfault), - labels: []string{"pgmajfault", "hierarchy"}, + value: float64(s.Memory.HierarchicalData.Pgmajfault), + labels: []string{"pgmajfault", "hierarchy"}, + timestamp: s.Timestamp, }, } }, @@ -373,8 +426,9 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri values := make(metricValues, 0, len(s.Accelerators)) for _, value := range s.Accelerators { values = append(values, metricValue{ - value: float64(value.MemoryTotal), - labels: []string{value.Make, value.Model, value.ID}, + value: float64(value.MemoryTotal), + labels: []string{value.Make, value.Model, value.ID}, + timestamp: s.Timestamp, }) } return values @@ -388,8 +442,9 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri values := make(metricValues, 0, len(s.Accelerators)) for _, value := range s.Accelerators { values = append(values, metricValue{ - value: float64(value.MemoryUsed), - labels: []string{value.Make, value.Model, value.ID}, + value: float64(value.MemoryUsed), + labels: []string{value.Make, value.Model, value.ID}, + timestamp: s.Timestamp, }) } return values @@ -403,8 +458,9 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri values := make(metricValues, 0, len(s.Accelerators)) for _, value := range s.Accelerators { values = append(values, metricValue{ - value: float64(value.DutyCycle), - labels: []string{value.Make, value.Model, value.ID}, + value: float64(value.DutyCycle), + labels: []string{value.Make, value.Model, value.ID}, + timestamp: s.Timestamp, }) } return values @@ -422,7 +478,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri getValues: func(s *info.ContainerStats) metricValues { return fsValues(s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.InodesFree) - }) + }, s.Timestamp) }, }, { name: "container_fs_inodes_total", @@ -432,7 +488,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri getValues: func(s *info.ContainerStats) metricValues { return fsValues(s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.Inodes) - }) + }, s.Timestamp) }, }, { name: "container_fs_limit_bytes", @@ -442,7 +498,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri getValues: func(s *info.ContainerStats) metricValues { return fsValues(s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.Limit) - }) + }, s.Timestamp) }, }, { name: "container_fs_usage_bytes", @@ -452,7 +508,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri getValues: func(s *info.ContainerStats) metricValues { return fsValues(s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.Usage) - }) + }, s.Timestamp) }, }, }...) @@ -468,6 +524,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri return ioValues( s.DiskIo.IoServiceBytes, "Read", asFloat64, nil, nil, + s.Timestamp, ) }, }, { @@ -481,6 +538,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.ReadsCompleted) }, + s.Timestamp, ) }, }, { @@ -494,6 +552,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.SectorsRead) }, + s.Timestamp, ) }, }, { @@ -507,6 +566,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.ReadsMerged) }, + s.Timestamp, ) }, }, { @@ -520,6 +580,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.ReadTime) / float64(time.Second) }, + s.Timestamp, ) }, }, { @@ -531,6 +592,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri return ioValues( s.DiskIo.IoServiceBytes, "Write", asFloat64, nil, nil, + s.Timestamp, ) }, }, { @@ -544,6 +606,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.WritesCompleted) }, + s.Timestamp, ) }, }, { @@ -557,6 +620,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.SectorsWritten) }, + s.Timestamp, ) }, }, { @@ -570,6 +634,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.WritesMerged) }, + s.Timestamp, ) }, }, { @@ -583,6 +648,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.WriteTime) / float64(time.Second) }, + s.Timestamp, ) }, }, { @@ -596,6 +662,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.IoInProgress) }, + s.Timestamp, ) }, }, { @@ -609,6 +676,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri s.Filesystem, func(fs *info.FsStats) float64 { return float64(float64(fs.IoTime) / float64(time.Second)) }, + s.Timestamp, ) }, }, { @@ -619,7 +687,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri getValues: func(s *info.ContainerStats) metricValues { return fsValues(s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.WeightedIoTime) / float64(time.Second) - }) + }, s.Timestamp) }, }, }...) @@ -635,8 +703,9 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri values := make(metricValues, 0, len(s.Network.Interfaces)) for _, value := range s.Network.Interfaces { values = append(values, metricValue{ - value: float64(value.RxBytes), - labels: []string{value.Name}, + value: float64(value.RxBytes), + labels: []string{value.Name}, + timestamp: s.Timestamp, }) } return values @@ -650,8 +719,9 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri values := make(metricValues, 0, len(s.Network.Interfaces)) for _, value := range s.Network.Interfaces { values = append(values, metricValue{ - value: float64(value.RxPackets), - labels: []string{value.Name}, + value: float64(value.RxPackets), + labels: []string{value.Name}, + timestamp: s.Timestamp, }) } return values @@ -665,8 +735,9 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri values := make(metricValues, 0, len(s.Network.Interfaces)) for _, value := range s.Network.Interfaces { values = append(values, metricValue{ - value: float64(value.RxDropped), - labels: []string{value.Name}, + value: float64(value.RxDropped), + labels: []string{value.Name}, + timestamp: s.Timestamp, }) } return values @@ -680,8 +751,9 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri values := make(metricValues, 0, len(s.Network.Interfaces)) for _, value := range s.Network.Interfaces { values = append(values, metricValue{ - value: float64(value.RxErrors), - labels: []string{value.Name}, + value: float64(value.RxErrors), + labels: []string{value.Name}, + timestamp: s.Timestamp, }) } return values @@ -695,8 +767,9 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri values := make(metricValues, 0, len(s.Network.Interfaces)) for _, value := range s.Network.Interfaces { values = append(values, metricValue{ - value: float64(value.TxBytes), - labels: []string{value.Name}, + value: float64(value.TxBytes), + labels: []string{value.Name}, + timestamp: s.Timestamp, }) } return values @@ -710,8 +783,9 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri values := make(metricValues, 0, len(s.Network.Interfaces)) for _, value := range s.Network.Interfaces { values = append(values, metricValue{ - value: float64(value.TxPackets), - labels: []string{value.Name}, + value: float64(value.TxPackets), + labels: []string{value.Name}, + timestamp: s.Timestamp, }) } return values @@ -725,8 +799,9 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri values := make(metricValues, 0, len(s.Network.Interfaces)) for _, value := range s.Network.Interfaces { values = append(values, metricValue{ - value: float64(value.TxDropped), - labels: []string{value.Name}, + value: float64(value.TxDropped), + labels: []string{value.Name}, + timestamp: s.Timestamp, }) } return values @@ -740,8 +815,9 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri values := make(metricValues, 0, len(s.Network.Interfaces)) for _, value := range s.Network.Interfaces { values = append(values, metricValue{ - value: float64(value.TxErrors), - labels: []string{value.Name}, + value: float64(value.TxErrors), + labels: []string{value.Name}, + timestamp: s.Timestamp, }) } return values @@ -759,48 +835,126 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri getValues: func(s *info.ContainerStats) metricValues { return metricValues{ { - value: float64(s.Network.Tcp.Established), - labels: []string{"established"}, + value: float64(s.Network.Tcp.Established), + labels: []string{"established"}, + timestamp: s.Timestamp, }, { - value: float64(s.Network.Tcp.SynSent), - labels: []string{"synsent"}, + value: float64(s.Network.Tcp.SynSent), + labels: []string{"synsent"}, + timestamp: s.Timestamp, }, { - value: float64(s.Network.Tcp.SynRecv), - labels: []string{"synrecv"}, + value: float64(s.Network.Tcp.SynRecv), + labels: []string{"synrecv"}, + timestamp: s.Timestamp, }, { - value: float64(s.Network.Tcp.FinWait1), - labels: []string{"finwait1"}, + value: float64(s.Network.Tcp.FinWait1), + labels: []string{"finwait1"}, + timestamp: s.Timestamp, }, { - value: float64(s.Network.Tcp.FinWait2), - labels: []string{"finwait2"}, + value: float64(s.Network.Tcp.FinWait2), + labels: []string{"finwait2"}, + timestamp: s.Timestamp, }, { - value: float64(s.Network.Tcp.TimeWait), - labels: []string{"timewait"}, + value: float64(s.Network.Tcp.TimeWait), + labels: []string{"timewait"}, + timestamp: s.Timestamp, }, { - value: float64(s.Network.Tcp.Close), - labels: []string{"close"}, + value: float64(s.Network.Tcp.Close), + labels: []string{"close"}, + timestamp: s.Timestamp, }, { - value: float64(s.Network.Tcp.CloseWait), - labels: []string{"closewait"}, + value: float64(s.Network.Tcp.CloseWait), + labels: []string{"closewait"}, + timestamp: s.Timestamp, }, { - value: float64(s.Network.Tcp.LastAck), - labels: []string{"lastack"}, + value: float64(s.Network.Tcp.LastAck), + labels: []string{"lastack"}, + timestamp: s.Timestamp, }, { - value: float64(s.Network.Tcp.Listen), - labels: []string{"listen"}, + value: float64(s.Network.Tcp.Listen), + labels: []string{"listen"}, + timestamp: s.Timestamp, }, { - value: float64(s.Network.Tcp.Closing), - labels: []string{"closing"}, + value: float64(s.Network.Tcp.Closing), + labels: []string{"closing"}, + timestamp: s.Timestamp, + }, + } + }, + }, + }...) + c.containerMetrics = append(c.containerMetrics, []containerMetric{ + { + name: "container_network_tcp6_usage_total", + help: "tcp6 connection usage statistic for container", + valueType: prometheus.GaugeValue, + extraLabels: []string{"tcp_state"}, + getValues: func(s *info.ContainerStats) metricValues { + return metricValues{ + { + value: float64(s.Network.Tcp6.Established), + labels: []string{"established"}, + timestamp: s.Timestamp, + }, + { + value: float64(s.Network.Tcp6.SynSent), + labels: []string{"synsent"}, + timestamp: s.Timestamp, + }, + { + value: float64(s.Network.Tcp6.SynRecv), + labels: []string{"synrecv"}, + timestamp: s.Timestamp, + }, + { + value: float64(s.Network.Tcp6.FinWait1), + labels: []string{"finwait1"}, + timestamp: s.Timestamp, + }, + { + value: float64(s.Network.Tcp6.FinWait2), + labels: []string{"finwait2"}, + timestamp: s.Timestamp, + }, + { + value: float64(s.Network.Tcp6.TimeWait), + labels: []string{"timewait"}, + timestamp: s.Timestamp, + }, + { + value: float64(s.Network.Tcp6.Close), + labels: []string{"close"}, + timestamp: s.Timestamp, + }, + { + value: float64(s.Network.Tcp6.CloseWait), + labels: []string{"closewait"}, + timestamp: s.Timestamp, + }, + { + value: float64(s.Network.Tcp6.LastAck), + labels: []string{"lastack"}, + timestamp: s.Timestamp, + }, + { + value: float64(s.Network.Tcp6.Listen), + labels: []string{"listen"}, + timestamp: s.Timestamp, + }, + { + value: float64(s.Network.Tcp6.Closing), + labels: []string{"closing"}, + timestamp: s.Timestamp, }, } }, @@ -808,6 +962,38 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri }...) } if includedMetrics.Has(container.NetworkUdpUsageMetrics) { + c.containerMetrics = append(c.containerMetrics, []containerMetric{ + { + name: "container_network_udp6_usage_total", + help: "udp6 connection usage statistic for container", + valueType: prometheus.GaugeValue, + extraLabels: []string{"udp_state"}, + getValues: func(s *info.ContainerStats) metricValues { + return metricValues{ + { + value: float64(s.Network.Udp6.Listen), + labels: []string{"listen"}, + timestamp: s.Timestamp, + }, + { + value: float64(s.Network.Udp6.Dropped), + labels: []string{"dropped"}, + timestamp: s.Timestamp, + }, + { + value: float64(s.Network.Udp6.RxQueued), + labels: []string{"rxqueued"}, + timestamp: s.Timestamp, + }, + { + value: float64(s.Network.Udp6.TxQueued), + labels: []string{"txqueued"}, + timestamp: s.Timestamp, + }, + } + }, + }, + }...) c.containerMetrics = append(c.containerMetrics, []containerMetric{ { name: "container_network_udp_usage_total", @@ -817,20 +1003,24 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri getValues: func(s *info.ContainerStats) metricValues { return metricValues{ { - value: float64(s.Network.Udp.Listen), - labels: []string{"listen"}, + value: float64(s.Network.Udp.Listen), + labels: []string{"listen"}, + timestamp: s.Timestamp, }, { - value: float64(s.Network.Udp.Dropped), - labels: []string{"dropped"}, + value: float64(s.Network.Udp.Dropped), + labels: []string{"dropped"}, + timestamp: s.Timestamp, }, { - value: float64(s.Network.Udp.RxQueued), - labels: []string{"rxqueued"}, + value: float64(s.Network.Udp.RxQueued), + labels: []string{"rxqueued"}, + timestamp: s.Timestamp, }, { - value: float64(s.Network.Udp.TxQueued), - labels: []string{"txqueued"}, + value: float64(s.Network.Udp.TxQueued), + labels: []string{"txqueued"}, + timestamp: s.Timestamp, }, } }, @@ -844,7 +1034,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri help: "Number of processes running inside the container.", valueType: prometheus.GaugeValue, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Processes.ProcessCount)}} + return metricValues{{value: float64(s.Processes.ProcessCount), timestamp: s.Timestamp}} }, }, { @@ -852,7 +1042,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri help: "Number of open file descriptors for the container.", valueType: prometheus.GaugeValue, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.Processes.FdCount)}} + return metricValues{{value: float64(s.Processes.FdCount), timestamp: s.Timestamp}} }, }, }...) @@ -922,17 +1112,29 @@ func DefaultContainerLabels(container *info.ContainerInfo) map[string]string { return set } -// BaseContainerLabels implements ContainerLabelsFunc. It only exports the -// container name, first alias, and image name. -func BaseContainerLabels(container *info.ContainerInfo) map[string]string { - set := map[string]string{LabelID: container.Name} - if len(container.Aliases) > 0 { - set[LabelName] = container.Aliases[0] +// BaseContainerLabels returns a ContainerLabelsFunc that exports the container +// name, first alias, image name as well as white listed label values. +func BaseContainerLabels(whiteList []string) func(container *info.ContainerInfo) map[string]string { + whiteListMap := make(map[string]struct{}, len(whiteList)) + for _, k := range whiteList { + whiteListMap[k] = struct{}{} } - if image := container.Spec.Image; len(image) > 0 { - set[LabelImage] = image + + return func(container *info.ContainerInfo) map[string]string { + set := map[string]string{LabelID: container.Name} + if len(container.Aliases) > 0 { + set[LabelName] = container.Aliases[0] + } + if image := container.Spec.Image; len(image) > 0 { + set[LabelImage] = image + } + for k, v := range container.Spec.Labels { + if _, ok := whiteListMap[k]; ok { + set[ContainerLabelPrefix+k] = v + } + } + return set } - return set } func (c *PrometheusCollector) collectContainersInfo(ch chan<- prometheus.Metric) { @@ -993,7 +1195,10 @@ func (c *PrometheusCollector) collectContainersInfo(ch chan<- prometheus.Metric) } desc := cm.desc(labels) for _, metricValue := range cm.getValues(stats) { - ch <- prometheus.MustNewConstMetric(desc, cm.valueType, float64(metricValue.value), append(values, metricValue.labels...)...) + ch <- prometheus.NewMetricWithTimestamp( + metricValue.timestamp, + prometheus.MustNewConstMetric(desc, cm.valueType, float64(metricValue.value), append(values, metricValue.labels...)...), + ) } } } diff --git a/vendor/github.com/google/cadvisor/utils/cloudinfo/aws.go b/vendor/github.com/google/cadvisor/utils/cloudinfo/aws.go index fadadd719e..f3cdfb31f0 100644 --- a/vendor/github.com/google/cadvisor/utils/cloudinfo/aws.go +++ b/vendor/github.com/google/cadvisor/utils/cloudinfo/aws.go @@ -19,6 +19,7 @@ import ( "github.com/aws/aws-sdk-go/aws/ec2metadata" "github.com/aws/aws-sdk-go/aws/session" "io/ioutil" + "os" "strings" info "github.com/google/cadvisor/info/v1" @@ -26,15 +27,28 @@ import ( const ( ProductVerFileName = "/sys/class/dmi/id/product_version" + BiosVerFileName = "/sys/class/dmi/id/bios_vendor" Amazon = "amazon" ) func onAWS() bool { - data, err := ioutil.ReadFile(ProductVerFileName) - if err != nil { - return false + var dataProduct []byte + var dataBios []byte + if _, err := os.Stat(ProductVerFileName); err == nil { + dataProduct, err = ioutil.ReadFile(ProductVerFileName) + if err != nil { + return false + } } - return strings.Contains(string(data), Amazon) + + if _, err := os.Stat(BiosVerFileName); err == nil { + dataBios, err = ioutil.ReadFile(BiosVerFileName) + if err != nil { + return false + } + } + + return strings.Contains(string(dataProduct), Amazon) || strings.Contains(strings.ToLower(string(dataBios)), Amazon) } func getAwsMetadata(name string) string { diff --git a/vendor/github.com/google/cadvisor/utils/oomparser/oomparser.go b/vendor/github.com/google/cadvisor/utils/oomparser/oomparser.go index 039baa30be..ea50c46308 100644 --- a/vendor/github.com/google/cadvisor/utils/oomparser/oomparser.go +++ b/vendor/github.com/google/cadvisor/utils/oomparser/oomparser.go @@ -101,8 +101,9 @@ func (self *OomParser) StreamOoms(outStream chan<- *OomInstance) { in_oom_kernel_log := checkIfStartOfOomMessages(msg.Message) if in_oom_kernel_log { oomCurrentInstance := &OomInstance{ - ContainerName: "/", - TimeOfDeath: msg.Timestamp, + ContainerName: "/", + VictimContainerName: "/", + TimeOfDeath: msg.Timestamp, } for msg := range kmsgEntries { err := getContainerName(msg.Message, oomCurrentInstance)