Update to new cadvisor v0.48.1
Signed-off-by: Davanum Srinivas <davanum@gmail.com>
This commit is contained in:
4
vendor/github.com/google/cadvisor/client/v2/client.go
generated
vendored
4
vendor/github.com/google/cadvisor/client/v2/client.go
generated
vendored
@@ -19,7 +19,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
@@ -147,7 +147,7 @@ func (c *Client) httpGetResponse(postData interface{}, urlPath, infoName string)
|
||||
return nil, fmt.Errorf("received empty response for %q from %q", infoName, urlPath)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("unable to read all %q from %q: %v", infoName, urlPath, err)
|
||||
return nil, err
|
||||
|
4
vendor/github.com/google/cadvisor/collector/generic_collector.go
generated
vendored
4
vendor/github.com/google/cadvisor/collector/generic_collector.go
generated
vendored
@@ -17,7 +17,7 @@ package collector
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@@ -145,7 +145,7 @@ func (collector *GenericCollector) Collect(metrics map[string][]v1.MetricVal) (t
|
||||
|
||||
defer response.Body.Close()
|
||||
|
||||
pageContent, err := ioutil.ReadAll(response.Body)
|
||||
pageContent, err := io.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return nextCollectionTime, nil, err
|
||||
}
|
||||
|
3
vendor/github.com/google/cadvisor/container/common/container_hints.go
generated
vendored
3
vendor/github.com/google/cadvisor/container/common/container_hints.go
generated
vendored
@@ -21,7 +21,6 @@ package common
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
@@ -48,7 +47,7 @@ type networkInterface struct {
|
||||
}
|
||||
|
||||
func GetContainerHintsFromFile(containerHintsFile string) (ContainerHints, error) {
|
||||
dat, err := ioutil.ReadFile(containerHintsFile)
|
||||
dat, err := os.ReadFile(containerHintsFile)
|
||||
if os.IsNotExist(err) {
|
||||
return ContainerHints{}, nil
|
||||
}
|
||||
|
24
vendor/github.com/google/cadvisor/container/common/helpers.go
generated
vendored
24
vendor/github.com/google/cadvisor/container/common/helpers.go
generated
vendored
@@ -16,7 +16,6 @@ package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
"path"
|
||||
@@ -76,7 +75,11 @@ func getSpecInternal(cgroupPaths map[string]string, machineInfoFactory info.Mach
|
||||
dir, err := os.Stat(cgroupPathDir)
|
||||
if err == nil && dir.ModTime().Before(lowestTime) {
|
||||
lowestTime = dir.ModTime()
|
||||
} else if os.IsNotExist(err) {
|
||||
// Directory does not exist, skip checking for files within.
|
||||
continue
|
||||
}
|
||||
|
||||
// The modified time of the cgroup directory sometimes changes whenever a subcontainer is created.
|
||||
// eg. /docker will have creation time matching the creation of latest docker container.
|
||||
// Use clone_children/events as a workaround as it isn't usually modified. It is only likely changed
|
||||
@@ -235,7 +238,7 @@ func readString(dirpath string, file string) string {
|
||||
cgroupFile := path.Join(dirpath, file)
|
||||
|
||||
// Read
|
||||
out, err := ioutil.ReadFile(cgroupFile)
|
||||
out, err := os.ReadFile(cgroupFile)
|
||||
if err != nil {
|
||||
// Ignore non-existent files
|
||||
if !os.IsNotExist(err) {
|
||||
@@ -437,3 +440,20 @@ func (m deviceIdentifierMap) Find(major, minor uint64, namer DeviceNamer) string
|
||||
m[d] = s
|
||||
return s
|
||||
}
|
||||
|
||||
// RemoveNetMetrics is used to remove any network metrics from the given MetricSet.
|
||||
// It returns the original set as is if remove is false, or if there are no metrics
|
||||
// to remove.
|
||||
func RemoveNetMetrics(metrics container.MetricSet, remove bool) container.MetricSet {
|
||||
if !remove {
|
||||
return metrics
|
||||
}
|
||||
|
||||
// Check if there is anything we can remove, to avoid useless copying.
|
||||
if !metrics.HasAny(container.AllNetworkMetrics) {
|
||||
return metrics
|
||||
}
|
||||
|
||||
// A copy of all metrics except for network ones.
|
||||
return metrics.Difference(container.AllNetworkMetrics)
|
||||
}
|
||||
|
1
vendor/github.com/google/cadvisor/container/container.go
generated
vendored
1
vendor/github.com/google/cadvisor/container/container.go
generated
vendored
@@ -35,6 +35,7 @@ const (
|
||||
ContainerTypeCrio
|
||||
ContainerTypeContainerd
|
||||
ContainerTypeMesos
|
||||
ContainerTypePodman
|
||||
)
|
||||
|
||||
// Interface for container operation handlers.
|
||||
|
2
vendor/github.com/google/cadvisor/container/containerd/client.go
generated
vendored
2
vendor/github.com/google/cadvisor/container/containerd/client.go
generated
vendored
@@ -59,6 +59,7 @@ const (
|
||||
maxBackoffDelay = 3 * time.Second
|
||||
baseBackoffDelay = 100 * time.Millisecond
|
||||
connectionTimeout = 2 * time.Second
|
||||
maxMsgSize = 16 * 1024 * 1024 // 16MB
|
||||
)
|
||||
|
||||
// Client creates a containerd client
|
||||
@@ -82,6 +83,7 @@ func Client(address, namespace string) (ContainerdClient, error) {
|
||||
grpc.WithContextDialer(dialer.ContextDialer),
|
||||
grpc.WithBlock(),
|
||||
grpc.WithConnectParams(connParams),
|
||||
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(maxMsgSize)),
|
||||
}
|
||||
unary, stream := newNSInterceptors(namespace)
|
||||
gopts = append(gopts,
|
||||
|
32
vendor/github.com/google/cadvisor/container/containerd/handler.go
generated
vendored
32
vendor/github.com/google/cadvisor/container/containerd/handler.go
generated
vendored
@@ -126,7 +126,14 @@ func newContainerdContainerHandler(
|
||||
Aliases: []string{id, name},
|
||||
}
|
||||
|
||||
libcontainerHandler := containerlibcontainer.NewHandler(cgroupManager, rootfs, int(taskPid), includedMetrics)
|
||||
// Containers that don't have their own network -- this includes
|
||||
// containers running in Kubernetes pods that use the network of the
|
||||
// infrastructure container -- does not need their stats to be
|
||||
// reported. This stops metrics being reported multiple times for each
|
||||
// container in a pod.
|
||||
metrics := common.RemoveNetMetrics(includedMetrics, cntr.Labels["io.cri-containerd.kind"] != "sandbox")
|
||||
|
||||
libcontainerHandler := containerlibcontainer.NewHandler(cgroupManager, rootfs, int(taskPid), metrics)
|
||||
|
||||
handler := &containerdContainerHandler{
|
||||
machineInfoFactory: machineInfoFactory,
|
||||
@@ -134,7 +141,7 @@ func newContainerdContainerHandler(
|
||||
fsInfo: fsInfo,
|
||||
envs: make(map[string]string),
|
||||
labels: cntr.Labels,
|
||||
includedMetrics: includedMetrics,
|
||||
includedMetrics: metrics,
|
||||
reference: containerReference,
|
||||
libcontainerHandler: libcontainerHandler,
|
||||
}
|
||||
@@ -164,22 +171,12 @@ func (h *containerdContainerHandler) ContainerReference() (info.ContainerReferen
|
||||
return h.reference, nil
|
||||
}
|
||||
|
||||
func (h *containerdContainerHandler) needNet() bool {
|
||||
// Since containerd does not handle networking ideally we need to return based
|
||||
// on includedMetrics list. Here the assumption is the presence of cri-containerd
|
||||
// label
|
||||
if h.includedMetrics.Has(container.NetworkUsageMetrics) {
|
||||
//TODO change it to exported cri-containerd constants
|
||||
return h.labels["io.cri-containerd.kind"] == "sandbox"
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *containerdContainerHandler) GetSpec() (info.ContainerSpec, error) {
|
||||
// TODO: Since we dont collect disk usage stats for containerd, we set hasFilesystem
|
||||
// to false. Revisit when we support disk usage stats for containerd
|
||||
hasFilesystem := false
|
||||
spec, err := common.GetSpec(h.cgroupPaths, h.machineInfoFactory, h.needNet(), hasFilesystem)
|
||||
hasNet := h.includedMetrics.Has(container.NetworkUsageMetrics)
|
||||
spec, err := common.GetSpec(h.cgroupPaths, h.machineInfoFactory, hasNet, hasFilesystem)
|
||||
spec.Labels = h.labels
|
||||
spec.Envs = h.envs
|
||||
spec.Image = h.image
|
||||
@@ -204,13 +201,6 @@ func (h *containerdContainerHandler) GetStats() (*info.ContainerStats, error) {
|
||||
if err != nil {
|
||||
return stats, err
|
||||
}
|
||||
// Clean up stats for containers that don't have their own network - this
|
||||
// includes containers running in Kubernetes pods that use the network of the
|
||||
// infrastructure container. This stops metrics being reported multiple times
|
||||
// for each container in a pod.
|
||||
if !h.needNet() {
|
||||
stats.Network = info.NetworkStats{}
|
||||
}
|
||||
|
||||
// Get filesystem stats.
|
||||
err = h.getFsStats(stats)
|
||||
|
8
vendor/github.com/google/cadvisor/container/crio/client.go
generated
vendored
8
vendor/github.com/google/cadvisor/container/crio/client.go
generated
vendored
@@ -17,8 +17,9 @@ package crio
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"sync"
|
||||
@@ -26,6 +27,8 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var crioClientTimeout = flag.Duration("crio_client_timeout", time.Duration(0), "CRI-O client timeout. Default is no timeout.")
|
||||
|
||||
const (
|
||||
CrioSocket = "/var/run/crio/crio.sock"
|
||||
maxUnixSocketPathSize = len(syscall.RawSockaddrUnix{}.Path)
|
||||
@@ -89,6 +92,7 @@ func Client() (CrioClient, error) {
|
||||
theClient = &crioClientImpl{
|
||||
client: &http.Client{
|
||||
Transport: tr,
|
||||
Timeout: *crioClientTimeout,
|
||||
},
|
||||
}
|
||||
})
|
||||
@@ -142,7 +146,7 @@ func (c *crioClientImpl) ContainerInfo(id string) (*ContainerInfo, error) {
|
||||
// golang's http.Do doesn't return an error if non 200 response code is returned
|
||||
// handle this case here, rather than failing to decode the body
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
respBody, err := ioutil.ReadAll(resp.Body)
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error finding container %s: Status %d", id, resp.StatusCode)
|
||||
}
|
||||
|
30
vendor/github.com/google/cadvisor/container/crio/handler.go
generated
vendored
30
vendor/github.com/google/cadvisor/container/crio/handler.go
generated
vendored
@@ -148,7 +148,15 @@ func newCrioContainerHandler(
|
||||
Namespace: CrioNamespace,
|
||||
}
|
||||
|
||||
libcontainerHandler := containerlibcontainer.NewHandler(cgroupManager, rootFs, cInfo.Pid, includedMetrics)
|
||||
// Find out if we need network metrics reported for this container.
|
||||
// Containers that don't have their own network -- this includes
|
||||
// containers running in Kubernetes pods that use the network of the
|
||||
// infrastructure container -- does not need their stats to be
|
||||
// reported. This stops metrics being reported multiple times for each
|
||||
// container in a pod.
|
||||
metrics := common.RemoveNetMetrics(includedMetrics, cInfo.Labels["io.kubernetes.container.name"] != "POD")
|
||||
|
||||
libcontainerHandler := containerlibcontainer.NewHandler(cgroupManager, rootFs, cInfo.Pid, metrics)
|
||||
|
||||
// TODO: extract object mother method
|
||||
handler := &crioContainerHandler{
|
||||
@@ -161,7 +169,7 @@ func newCrioContainerHandler(
|
||||
rootfsStorageDir: rootfsStorageDir,
|
||||
envs: make(map[string]string),
|
||||
labels: cInfo.Labels,
|
||||
includedMetrics: includedMetrics,
|
||||
includedMetrics: metrics,
|
||||
reference: containerReference,
|
||||
libcontainerHandler: libcontainerHandler,
|
||||
cgroupManager: cgroupManager,
|
||||
@@ -210,16 +218,10 @@ func (h *crioContainerHandler) ContainerReference() (info.ContainerReference, er
|
||||
return h.reference, nil
|
||||
}
|
||||
|
||||
func (h *crioContainerHandler) needNet() bool {
|
||||
if h.includedMetrics.Has(container.NetworkUsageMetrics) {
|
||||
return h.labels["io.kubernetes.container.name"] == "POD"
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *crioContainerHandler) GetSpec() (info.ContainerSpec, error) {
|
||||
hasFilesystem := h.includedMetrics.Has(container.DiskUsageMetrics)
|
||||
spec, err := common.GetSpec(h.cgroupPaths, h.machineInfoFactory, h.needNet(), hasFilesystem)
|
||||
hasNet := h.includedMetrics.Has(container.NetworkUsageMetrics)
|
||||
spec, err := common.GetSpec(h.cgroupPaths, h.machineInfoFactory, hasNet, hasFilesystem)
|
||||
|
||||
spec.Labels = h.labels
|
||||
spec.Envs = h.envs
|
||||
@@ -306,13 +308,7 @@ func (h *crioContainerHandler) GetStats() (*info.ContainerStats, error) {
|
||||
return stats, err
|
||||
}
|
||||
|
||||
if !h.needNet() {
|
||||
// Clean up stats for containers that don't have their own network - this
|
||||
// includes containers running in Kubernetes pods that use the network of the
|
||||
// infrastructure container. This stops metrics being reported multiple times
|
||||
// for each container in a pod.
|
||||
stats.Network = info.NetworkStats{}
|
||||
} else if len(stats.Network.Interfaces) == 0 {
|
||||
if h.includedMetrics.Has(container.NetworkUsageMetrics) && len(stats.Network.Interfaces) == 0 {
|
||||
// No network related information indicates that the pid of the
|
||||
// container is not longer valid and we need to ask crio to
|
||||
// provide the pid of another container from that pod
|
||||
|
21
vendor/github.com/google/cadvisor/container/factory.go
generated
vendored
21
vendor/github.com/google/cadvisor/container/factory.go
generated
vendored
@@ -93,6 +93,14 @@ var AllMetrics = MetricSet{
|
||||
OOMMetrics: struct{}{},
|
||||
}
|
||||
|
||||
// AllNetworkMetrics represents all network metrics that cAdvisor supports.
|
||||
var AllNetworkMetrics = MetricSet{
|
||||
NetworkUsageMetrics: struct{}{},
|
||||
NetworkTcpUsageMetrics: struct{}{},
|
||||
NetworkAdvancedTcpUsageMetrics: struct{}{},
|
||||
NetworkUdpUsageMetrics: struct{}{},
|
||||
}
|
||||
|
||||
func (mk MetricKind) String() string {
|
||||
return string(mk)
|
||||
}
|
||||
@@ -104,6 +112,15 @@ func (ms MetricSet) Has(mk MetricKind) bool {
|
||||
return exists
|
||||
}
|
||||
|
||||
func (ms MetricSet) HasAny(ms1 MetricSet) bool {
|
||||
for m := range ms1 {
|
||||
if _, ok := ms[m]; ok {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (ms MetricSet) add(mk MetricKind) {
|
||||
ms[mk] = struct{}{}
|
||||
}
|
||||
@@ -199,7 +216,9 @@ func InitializePlugins(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includ
|
||||
for name, plugin := range plugins {
|
||||
watcher, err := plugin.Register(factory, fsInfo, includedMetrics)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Registration of the %s container factory failed: %v", name, err)
|
||||
klog.Infof("Registration of the %s container factory failed: %v", name, err)
|
||||
} else {
|
||||
klog.Infof("Registration of the %s container factory successfully", name)
|
||||
}
|
||||
if watcher != nil {
|
||||
containerWatchers = append(containerWatchers, watcher)
|
||||
|
91
vendor/github.com/google/cadvisor/container/libcontainer/handler.go
generated
vendored
91
vendor/github.com/google/cadvisor/container/libcontainer/handler.go
generated
vendored
@@ -21,7 +21,6 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
@@ -40,7 +39,6 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
whitelistedUlimits = [...]string{"max_open_files"}
|
||||
referencedResetInterval = flag.Uint64("referenced_reset_interval", 0,
|
||||
"Reset interval for referenced bytes (container_referenced_bytes metric), number of measurement cycles after which referenced bytes are cleared, if set to 0 referenced bytes are never cleared (default: 0)")
|
||||
|
||||
@@ -206,54 +204,56 @@ func parseUlimit(value string) (int64, error) {
|
||||
return num, nil
|
||||
}
|
||||
|
||||
func isUlimitWhitelisted(name string) bool {
|
||||
for _, whitelist := range whitelistedUlimits {
|
||||
if name == whitelist {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func processLimitsFile(fileData string) []info.UlimitSpec {
|
||||
const maxOpenFilesLinePrefix = "Max open files"
|
||||
|
||||
limits := strings.Split(fileData, "\n")
|
||||
ulimits := make([]info.UlimitSpec, 0, len(limits))
|
||||
for _, lim := range limits {
|
||||
// Skip any headers/footers
|
||||
if strings.HasPrefix(lim, "Max") {
|
||||
|
||||
// Line format: Max open files 16384 16384 files
|
||||
fields := regexp.MustCompile(`[\s]{2,}`).Split(lim, -1)
|
||||
name := strings.Replace(strings.ToLower(strings.TrimSpace(fields[0])), " ", "_", -1)
|
||||
|
||||
found := isUlimitWhitelisted(name)
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
soft := strings.TrimSpace(fields[1])
|
||||
softNum, softErr := parseUlimit(soft)
|
||||
|
||||
hard := strings.TrimSpace(fields[2])
|
||||
hardNum, hardErr := parseUlimit(hard)
|
||||
|
||||
// Omit metric if there were any parsing errors
|
||||
if softErr == nil && hardErr == nil {
|
||||
ulimitSpec := info.UlimitSpec{
|
||||
Name: name,
|
||||
SoftLimit: int64(softNum),
|
||||
HardLimit: int64(hardNum),
|
||||
}
|
||||
ulimits = append(ulimits, ulimitSpec)
|
||||
if strings.HasPrefix(lim, "Max open files") {
|
||||
// Remove line prefix
|
||||
ulimit, err := processMaxOpenFileLimitLine(
|
||||
"max_open_files",
|
||||
lim[len(maxOpenFilesLinePrefix):],
|
||||
)
|
||||
if err == nil {
|
||||
ulimits = append(ulimits, ulimit)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ulimits
|
||||
}
|
||||
|
||||
// Any caller of processMaxOpenFileLimitLine must ensure that the name prefix is already removed from the limit line.
|
||||
// with the "Max open files" prefix.
|
||||
func processMaxOpenFileLimitLine(name, line string) (info.UlimitSpec, error) {
|
||||
// Remove any leading whitespace
|
||||
line = strings.TrimSpace(line)
|
||||
// Split on whitespace
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) != 3 {
|
||||
return info.UlimitSpec{}, fmt.Errorf("unable to parse max open files line: %s", line)
|
||||
}
|
||||
// The first field is the soft limit, the second is the hard limit
|
||||
soft, err := parseUlimit(fields[0])
|
||||
if err != nil {
|
||||
return info.UlimitSpec{}, err
|
||||
}
|
||||
hard, err := parseUlimit(fields[1])
|
||||
if err != nil {
|
||||
return info.UlimitSpec{}, err
|
||||
}
|
||||
return info.UlimitSpec{
|
||||
Name: name,
|
||||
SoftLimit: soft,
|
||||
HardLimit: hard,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func processRootProcUlimits(rootFs string, rootPid int) []info.UlimitSpec {
|
||||
filePath := path.Join(rootFs, "/proc", strconv.Itoa(rootPid), "limits")
|
||||
out, err := ioutil.ReadFile(filePath)
|
||||
out, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
klog.V(4).Infof("error while listing directory %q to read ulimits: %v", filePath, err)
|
||||
return []info.UlimitSpec{}
|
||||
@@ -264,14 +264,14 @@ func processRootProcUlimits(rootFs string, rootPid int) []info.UlimitSpec {
|
||||
func processStatsFromProcs(rootFs string, cgroupPath string, rootPid int) (info.ProcessStats, error) {
|
||||
var fdCount, socketCount uint64
|
||||
filePath := path.Join(cgroupPath, "cgroup.procs")
|
||||
out, err := ioutil.ReadFile(filePath)
|
||||
out, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return info.ProcessStats{}, fmt.Errorf("couldn't open cpu cgroup procs file %v : %v", filePath, err)
|
||||
}
|
||||
|
||||
pids := strings.Split(string(out), "\n")
|
||||
|
||||
// EOL is also treated as a new line while reading "cgroup.procs" file with ioutil.ReadFile.
|
||||
// EOL is also treated as a new line while reading "cgroup.procs" file with os.ReadFile.
|
||||
// The last value is an empty string "". Ex: pids = ["22", "1223", ""]
|
||||
// Trim the last value
|
||||
if len(pids) != 0 && pids[len(pids)-1] == "" {
|
||||
@@ -280,7 +280,7 @@ func processStatsFromProcs(rootFs string, cgroupPath string, rootPid int) (info.
|
||||
|
||||
for _, pid := range pids {
|
||||
dirPath := path.Join(rootFs, "/proc", pid, "fd")
|
||||
fds, err := ioutil.ReadDir(dirPath)
|
||||
fds, err := os.ReadDir(dirPath)
|
||||
if err != nil {
|
||||
klog.V(4).Infof("error while listing directory %q to measure fd count: %v", dirPath, err)
|
||||
continue
|
||||
@@ -324,7 +324,7 @@ func (h *Handler) schedulerStatsFromProcs() (info.CpuSchedstat, error) {
|
||||
return info.CpuSchedstat{}, fmt.Errorf("couldn't open scheduler statistics for process %d: %v", pid, err)
|
||||
}
|
||||
defer f.Close()
|
||||
contents, err := ioutil.ReadAll(f)
|
||||
contents, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return info.CpuSchedstat{}, fmt.Errorf("couldn't read scheduler statistics for process %d: %v", pid, err)
|
||||
}
|
||||
@@ -392,7 +392,7 @@ func getReferencedKBytes(pids []int) (uint64, error) {
|
||||
foundMatch := false
|
||||
for _, pid := range pids {
|
||||
smapsFilePath := fmt.Sprintf(smapsFilePathPattern, pid)
|
||||
smapsContent, err := ioutil.ReadFile(smapsFilePath)
|
||||
smapsContent, err := os.ReadFile(smapsFilePath)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Cannot read %s file, err: %s", smapsFilePath, err)
|
||||
if os.IsNotExist(err) {
|
||||
@@ -468,7 +468,7 @@ func networkStatsFromProc(rootFs string, pid int) ([]info.InterfaceStats, error)
|
||||
return ifaceStats, nil
|
||||
}
|
||||
|
||||
var ignoredDevicePrefixes = []string{"lo", "veth", "docker"}
|
||||
var ignoredDevicePrefixes = []string{"lo", "veth", "docker", "nerdctl"}
|
||||
|
||||
func isIgnoredDevice(ifName string) bool {
|
||||
for _, prefix := range ignoredDevicePrefixes {
|
||||
@@ -575,7 +575,7 @@ func advancedTCPStatsFromProc(rootFs string, pid int, file1, file2 string) (info
|
||||
}
|
||||
|
||||
func scanAdvancedTCPStats(advancedStats *info.TcpAdvancedStat, advancedTCPStatsFile string) error {
|
||||
data, err := ioutil.ReadFile(advancedTCPStatsFile)
|
||||
data, err := os.ReadFile(advancedTCPStatsFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failure opening %s: %v", advancedTCPStatsFile, err)
|
||||
}
|
||||
@@ -631,7 +631,7 @@ func scanAdvancedTCPStats(advancedStats *info.TcpAdvancedStat, advancedTCPStatsF
|
||||
func scanTCPStats(tcpStatsFile string) (info.TcpStat, error) {
|
||||
var stats info.TcpStat
|
||||
|
||||
data, err := ioutil.ReadFile(tcpStatsFile)
|
||||
data, err := os.ReadFile(tcpStatsFile)
|
||||
if err != nil {
|
||||
return stats, fmt.Errorf("failure opening %s: %v", tcpStatsFile, err)
|
||||
}
|
||||
@@ -802,6 +802,7 @@ func setMemoryStats(s *cgroups.Stats, ret *info.ContainerStats) {
|
||||
ret.Memory.Usage = s.MemoryStats.Usage.Usage
|
||||
ret.Memory.MaxUsage = s.MemoryStats.Usage.MaxUsage
|
||||
ret.Memory.Failcnt = s.MemoryStats.Usage.Failcnt
|
||||
ret.Memory.KernelUsage = s.MemoryStats.KernelUsage.Usage
|
||||
|
||||
if cgroups.IsCgroup2UnifiedMode() {
|
||||
ret.Memory.Cache = s.MemoryStats.Stats["file"]
|
||||
|
8
vendor/github.com/google/cadvisor/container/raw/watcher.go
generated
vendored
8
vendor/github.com/google/cadvisor/container/raw/watcher.go
generated
vendored
@@ -18,13 +18,13 @@ package raw
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
inotify "k8s.io/utils/inotify"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/container/common"
|
||||
"github.com/google/cadvisor/container/libcontainer"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
@@ -43,8 +43,8 @@ type rawContainerWatcher struct {
|
||||
stopWatcher chan error
|
||||
}
|
||||
|
||||
func NewRawContainerWatcher() (watcher.ContainerWatcher, error) {
|
||||
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(nil)
|
||||
func NewRawContainerWatcher(includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
|
||||
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get cgroup subsystems: %v", err)
|
||||
}
|
||||
@@ -139,7 +139,7 @@ func (w *rawContainerWatcher) watchDirectory(events chan watcher.ContainerEvent,
|
||||
|
||||
// TODO(vmarmol): We should re-do this once we're done to ensure directories were not added in the meantime.
|
||||
// Watch subdirectories as well.
|
||||
entries, err := ioutil.ReadDir(dir)
|
||||
entries, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return alreadyWatching, err
|
||||
}
|
||||
|
28
vendor/github.com/google/cadvisor/fs/fs.go
generated
vendored
28
vendor/github.com/google/cadvisor/fs/fs.go
generated
vendored
@@ -21,7 +21,6 @@ package fs
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
@@ -146,7 +145,7 @@ func getFsUUIDToDeviceNameMap() (map[string]string, error) {
|
||||
return make(map[string]string), nil
|
||||
}
|
||||
|
||||
files, err := ioutil.ReadDir(dir)
|
||||
files, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -387,6 +386,7 @@ func (i *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nfsInfo := make(map[string]Fs, 0)
|
||||
for device, partition := range i.partitions {
|
||||
_, hasMount := mountSet[partition.mountpoint]
|
||||
_, hasDevice := deviceSet[device]
|
||||
@@ -395,7 +395,11 @@ func (i *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, error
|
||||
err error
|
||||
fs Fs
|
||||
)
|
||||
switch partition.fsType {
|
||||
fsType := partition.fsType
|
||||
if strings.HasPrefix(partition.fsType, "nfs") {
|
||||
fsType = "nfs"
|
||||
}
|
||||
switch fsType {
|
||||
case DeviceMapper.String():
|
||||
fs.Capacity, fs.Free, fs.Available, err = getDMStats(device, partition.blockSize)
|
||||
klog.V(5).Infof("got devicemapper fs capacity stats: capacity: %v free: %v available: %v:", fs.Capacity, fs.Free, fs.Available)
|
||||
@@ -408,6 +412,22 @@ func (i *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, error
|
||||
}
|
||||
// if /dev/zfs is not present default to VFS
|
||||
fallthrough
|
||||
case NFS.String():
|
||||
devId := fmt.Sprintf("%d:%d", partition.major, partition.minor)
|
||||
if v, ok := nfsInfo[devId]; ok {
|
||||
fs = v
|
||||
break
|
||||
}
|
||||
var inodes, inodesFree uint64
|
||||
fs.Capacity, fs.Free, fs.Available, inodes, inodesFree, err = getVfsStats(partition.mountpoint)
|
||||
if err != nil {
|
||||
klog.V(4).Infof("the file system type is %s, partition mountpoint does not exist: %v, error: %v", partition.fsType, partition.mountpoint, err)
|
||||
break
|
||||
}
|
||||
fs.Inodes = &inodes
|
||||
fs.InodesFree = &inodesFree
|
||||
fs.Type = VFS
|
||||
nfsInfo[devId] = fs
|
||||
default:
|
||||
var inodes, inodesFree uint64
|
||||
if utils.FileExists(partition.mountpoint) {
|
||||
@@ -616,7 +636,7 @@ func GetDirUsage(dir string) (UsageInfo, error) {
|
||||
|
||||
rootStat, ok := rootInfo.Sys().(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return usage, fmt.Errorf("unsuported fileinfo for getting inode usage of %q", dir)
|
||||
return usage, fmt.Errorf("unsupported fileinfo for getting inode usage of %q", dir)
|
||||
}
|
||||
|
||||
rootDevID := rootStat.Dev
|
||||
|
8
vendor/github.com/google/cadvisor/fs/types.go
generated
vendored
8
vendor/github.com/google/cadvisor/fs/types.go
generated
vendored
@@ -22,6 +22,7 @@ type Context struct {
|
||||
// docker root directory.
|
||||
Docker DockerContext
|
||||
Crio CrioContext
|
||||
Podman PodmanContext
|
||||
}
|
||||
|
||||
type DockerContext struct {
|
||||
@@ -30,6 +31,12 @@ type DockerContext struct {
|
||||
DriverStatus map[string]string
|
||||
}
|
||||
|
||||
type PodmanContext struct {
|
||||
Root string
|
||||
Driver string
|
||||
DriverStatus map[string]string
|
||||
}
|
||||
|
||||
type CrioContext struct {
|
||||
Root string
|
||||
}
|
||||
@@ -50,6 +57,7 @@ const (
|
||||
ZFS FsType = "zfs"
|
||||
DeviceMapper FsType = "devicemapper"
|
||||
VFS FsType = "vfs"
|
||||
NFS FsType = "nfs"
|
||||
)
|
||||
|
||||
type Fs struct {
|
||||
|
4
vendor/github.com/google/cadvisor/info/v1/container.go
generated
vendored
4
vendor/github.com/google/cadvisor/info/v1/container.go
generated
vendored
@@ -395,6 +395,10 @@ type MemoryStats struct {
|
||||
|
||||
Failcnt uint64 `json:"failcnt"`
|
||||
|
||||
// Size of kernel memory allocated in bytes.
|
||||
// Units: Bytes.
|
||||
KernelUsage uint64 `json:"kernel"`
|
||||
|
||||
ContainerData MemoryStatsMemoryData `json:"container_data,omitempty"`
|
||||
HierarchicalData MemoryStatsMemoryData `json:"hierarchical_data,omitempty"`
|
||||
}
|
||||
|
1
vendor/github.com/google/cadvisor/info/v2/container.go
generated
vendored
1
vendor/github.com/google/cadvisor/info/v2/container.go
generated
vendored
@@ -25,6 +25,7 @@ import (
|
||||
const (
|
||||
TypeName = "name"
|
||||
TypeDocker = "docker"
|
||||
TypePodman = "podman"
|
||||
)
|
||||
|
||||
type CpuSpec struct {
|
||||
|
6
vendor/github.com/google/cadvisor/machine/info.go
generated
vendored
6
vendor/github.com/google/cadvisor/machine/info.go
generated
vendored
@@ -17,7 +17,7 @@ package machine
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -45,7 +45,7 @@ func getInfoFromFiles(filePaths string) string {
|
||||
return ""
|
||||
}
|
||||
for _, file := range strings.Split(filePaths, ",") {
|
||||
id, err := ioutil.ReadFile(file)
|
||||
id, err := os.ReadFile(file)
|
||||
if err == nil {
|
||||
return strings.TrimSpace(string(id))
|
||||
}
|
||||
@@ -60,7 +60,7 @@ func Info(sysFs sysfs.SysFs, fsInfo fs.FsInfo, inHostNamespace bool) (*info.Mach
|
||||
rootFs = "/rootfs"
|
||||
}
|
||||
|
||||
cpuinfo, err := ioutil.ReadFile(filepath.Join(rootFs, "/proc/cpuinfo"))
|
||||
cpuinfo, err := os.ReadFile(filepath.Join(rootFs, "/proc/cpuinfo"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
23
vendor/github.com/google/cadvisor/machine/machine.go
generated
vendored
23
vendor/github.com/google/cadvisor/machine/machine.go
generated
vendored
@@ -17,7 +17,6 @@ package machine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
@@ -46,7 +45,7 @@ var (
|
||||
swapCapacityRegexp = regexp.MustCompile(`SwapTotal:\s*([0-9]+) kB`)
|
||||
vendorIDRegexp = regexp.MustCompile(`vendor_id\s*:\s*(\w+)`)
|
||||
|
||||
cpuBusPath = "/sys/bus/cpu/devices/"
|
||||
cpuAttributesPath = "/sys/devices/system/cpu/"
|
||||
isMemoryController = regexp.MustCompile("mc[0-9]+")
|
||||
isDimm = regexp.MustCompile("dimm[0-9]+")
|
||||
machineArch = getMachineArch()
|
||||
@@ -62,7 +61,7 @@ func GetCPUVendorID(procInfo []byte) string {
|
||||
|
||||
matches := vendorIDRegexp.FindSubmatch(procInfo)
|
||||
if len(matches) != 2 {
|
||||
klog.Warning("Cannot read vendor id correctly, set empty.")
|
||||
klog.V(4).Info("Cannot read vendor id correctly, set empty.")
|
||||
return vendorID
|
||||
}
|
||||
|
||||
@@ -77,7 +76,7 @@ func GetPhysicalCores(procInfo []byte) int {
|
||||
if numCores == 0 {
|
||||
// read number of cores from /sys/bus/cpu/devices/cpu*/topology/core_id to deal with processors
|
||||
// for which 'core id' is not available in /proc/cpuinfo
|
||||
numCores = sysfs.GetUniqueCPUPropertyCount(cpuBusPath, sysfs.CPUCoreID)
|
||||
numCores = sysfs.GetUniqueCPUPropertyCount(cpuAttributesPath, sysfs.CPUCoreID)
|
||||
}
|
||||
if numCores == 0 {
|
||||
klog.Errorf("Cannot read number of physical cores correctly, number of cores set to %d", numCores)
|
||||
@@ -91,7 +90,7 @@ func GetSockets(procInfo []byte) int {
|
||||
if numSocket == 0 {
|
||||
// read number of sockets from /sys/bus/cpu/devices/cpu*/topology/physical_package_id to deal with processors
|
||||
// for which 'physical id' is not available in /proc/cpuinfo
|
||||
numSocket = sysfs.GetUniqueCPUPropertyCount(cpuBusPath, sysfs.CPUPhysicalPackageID)
|
||||
numSocket = sysfs.GetUniqueCPUPropertyCount(cpuAttributesPath, sysfs.CPUPhysicalPackageID)
|
||||
}
|
||||
if numSocket == 0 {
|
||||
klog.Errorf("Cannot read number of sockets correctly, number of sockets set to %d", numSocket)
|
||||
@@ -103,7 +102,7 @@ func GetSockets(procInfo []byte) int {
|
||||
func GetClockSpeed(procInfo []byte) (uint64, error) {
|
||||
// First look through sys to find a max supported cpu frequency.
|
||||
if utils.FileExists(maxFreqFile) {
|
||||
val, err := ioutil.ReadFile(maxFreqFile)
|
||||
val, err := os.ReadFile(maxFreqFile)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -136,7 +135,7 @@ func GetClockSpeed(procInfo []byte) (uint64, error) {
|
||||
// GetMachineMemoryCapacity returns the machine's total memory from /proc/meminfo.
|
||||
// Returns the total memory capacity as an uint64 (number of bytes).
|
||||
func GetMachineMemoryCapacity() (uint64, error) {
|
||||
out, err := ioutil.ReadFile("/proc/meminfo")
|
||||
out, err := os.ReadFile("/proc/meminfo")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -156,7 +155,7 @@ func GetMachineMemoryCapacity() (uint64, error) {
|
||||
// (https://github.com/torvalds/linux/blob/v5.5/drivers/edac/edac_mc.c#L198)
|
||||
func GetMachineMemoryByType(edacPath string) (map[string]*info.MemoryInfo, error) {
|
||||
memory := map[string]*info.MemoryInfo{}
|
||||
names, err := ioutil.ReadDir(edacPath)
|
||||
names, err := os.ReadDir(edacPath)
|
||||
// On some architectures (such as ARM) memory controller device may not exist.
|
||||
// If this is the case then we ignore error and return empty slice.
|
||||
_, ok := err.(*os.PathError)
|
||||
@@ -170,7 +169,7 @@ func GetMachineMemoryByType(edacPath string) (map[string]*info.MemoryInfo, error
|
||||
if !isMemoryController.MatchString(controller) {
|
||||
continue
|
||||
}
|
||||
dimms, err := ioutil.ReadDir(path.Join(edacPath, controllerDir.Name()))
|
||||
dimms, err := os.ReadDir(path.Join(edacPath, controllerDir.Name()))
|
||||
if err != nil {
|
||||
return map[string]*info.MemoryInfo{}, err
|
||||
}
|
||||
@@ -179,7 +178,7 @@ func GetMachineMemoryByType(edacPath string) (map[string]*info.MemoryInfo, error
|
||||
if !isDimm.MatchString(dimm) {
|
||||
continue
|
||||
}
|
||||
memType, err := ioutil.ReadFile(path.Join(edacPath, controller, dimm, memTypeFileName))
|
||||
memType, err := os.ReadFile(path.Join(edacPath, controller, dimm, memTypeFileName))
|
||||
if err != nil {
|
||||
return map[string]*info.MemoryInfo{}, err
|
||||
}
|
||||
@@ -187,7 +186,7 @@ func GetMachineMemoryByType(edacPath string) (map[string]*info.MemoryInfo, error
|
||||
if _, exists := memory[readableMemType]; !exists {
|
||||
memory[readableMemType] = &info.MemoryInfo{}
|
||||
}
|
||||
size, err := ioutil.ReadFile(path.Join(edacPath, controller, dimm, sizeFileName))
|
||||
size, err := os.ReadFile(path.Join(edacPath, controller, dimm, sizeFileName))
|
||||
if err != nil {
|
||||
return map[string]*info.MemoryInfo{}, err
|
||||
}
|
||||
@@ -210,7 +209,7 @@ func mbToBytes(megabytes int) int {
|
||||
// GetMachineSwapCapacity returns the machine's total swap from /proc/meminfo.
|
||||
// Returns the total swap capacity as an uint64 (number of bytes).
|
||||
func GetMachineSwapCapacity() (uint64, error) {
|
||||
out, err := ioutil.ReadFile("/proc/meminfo")
|
||||
out, err := os.ReadFile("/proc/meminfo")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
5
vendor/github.com/google/cadvisor/machine/operatingsystem_unix.go
generated
vendored
5
vendor/github.com/google/cadvisor/machine/operatingsystem_unix.go
generated
vendored
@@ -19,7 +19,6 @@ package machine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
@@ -39,10 +38,10 @@ func getOperatingSystem() (string, error) {
|
||||
}
|
||||
return string(osName), nil
|
||||
}
|
||||
bytes, err := ioutil.ReadFile("/etc/os-release")
|
||||
bytes, err := os.ReadFile("/etc/os-release")
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
// /usr/lib/os-release in stateless systems like Clear Linux
|
||||
bytes, err = ioutil.ReadFile("/usr/lib/os-release")
|
||||
bytes, err = os.ReadFile("/usr/lib/os-release")
|
||||
}
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error opening file : %v", err)
|
||||
|
8
vendor/github.com/google/cadvisor/manager/container.go
generated
vendored
8
vendor/github.com/google/cadvisor/manager/container.go
generated
vendored
@@ -17,9 +17,9 @@ package manager
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"math/rand"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"regexp"
|
||||
@@ -243,7 +243,7 @@ func (cd *containerData) ReadFile(filepath string, inHostNamespace bool) ([]byte
|
||||
for _, pid := range pids {
|
||||
filePath := path.Join(rootfs, "/proc", pid, "/root", filepath)
|
||||
klog.V(3).Infof("Trying path %q", filePath)
|
||||
data, err := ioutil.ReadFile(filePath)
|
||||
data, err := os.ReadFile(filePath)
|
||||
if err == nil {
|
||||
return data, err
|
||||
}
|
||||
@@ -323,7 +323,7 @@ func (cd *containerData) parseProcessList(cadvisorContainer string, inHostNamesp
|
||||
|
||||
var fdCount int
|
||||
dirPath := path.Join(rootfs, "/proc", strconv.Itoa(processInfo.Pid), "fd")
|
||||
fds, err := ioutil.ReadDir(dirPath)
|
||||
fds, err := os.ReadDir(dirPath)
|
||||
if err != nil {
|
||||
klog.V(4).Infof("error while listing directory %q to measure fd count: %v", dirPath, err)
|
||||
continue
|
||||
@@ -482,7 +482,7 @@ func (cd *containerData) nextHousekeepingInterval() time.Duration {
|
||||
stats, err := cd.memoryCache.RecentStats(cd.info.Name, empty, empty, 2)
|
||||
if err != nil {
|
||||
if cd.allowErrorLogging() {
|
||||
klog.Warningf("Failed to get RecentStats(%q) while determining the next housekeeping: %v", cd.info.Name, err)
|
||||
klog.V(4).Infof("Failed to get RecentStats(%q) while determining the next housekeeping: %v", cd.info.Name, err)
|
||||
}
|
||||
} else if len(stats) == 2 {
|
||||
// TODO(vishnuk): Use no processes as a signal.
|
||||
|
110
vendor/github.com/google/cadvisor/manager/manager.go
generated
vendored
110
vendor/github.com/google/cadvisor/manager/manager.go
generated
vendored
@@ -58,10 +58,13 @@ var eventStorageAgeLimit = flag.String("event_storage_age_limit", "default=24h",
|
||||
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")
|
||||
var applicationMetricsCountLimit = flag.Int("application_metrics_count_limit", 100, "Max number of application metrics to store (per container)")
|
||||
|
||||
// The namespace under which Docker aliases are unique.
|
||||
const DockerNamespace = "docker"
|
||||
// The namespace under which aliases are unique.
|
||||
const (
|
||||
DockerNamespace = "docker"
|
||||
PodmanNamespace = "podman"
|
||||
)
|
||||
|
||||
var HousekeepingConfigFlags = HouskeepingConfig{
|
||||
var HousekeepingConfigFlags = HousekeepingConfig{
|
||||
flag.Duration("max_housekeeping_interval", 60*time.Second, "Largest interval to allow between container housekeepings"),
|
||||
flag.Bool("allow_dynamic_housekeeping", true, "Whether to allow the housekeeping interval to be dynamic"),
|
||||
}
|
||||
@@ -136,16 +139,20 @@ type Manager interface {
|
||||
|
||||
// Returns debugging information. Map of lines per category.
|
||||
DebugInfo() map[string][]string
|
||||
|
||||
AllPodmanContainers(c *info.ContainerInfoRequest) (map[string]info.ContainerInfo, error)
|
||||
|
||||
PodmanContainer(containerName string, query *info.ContainerInfoRequest) (info.ContainerInfo, error)
|
||||
}
|
||||
|
||||
// Housekeeping configuration for the manager
|
||||
type HouskeepingConfig = struct {
|
||||
type HousekeepingConfig = struct {
|
||||
Interval *time.Duration
|
||||
AllowDynamic *bool
|
||||
}
|
||||
|
||||
// New takes a memory storage and returns a new manager.
|
||||
func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, houskeepingConfig HouskeepingConfig, includedMetricsSet container.MetricSet, collectorHTTPClient *http.Client, rawContainerCgroupPathPrefixWhiteList, containerEnvMetadataWhiteList []string, perfEventsFile string, resctrlInterval time.Duration) (Manager, error) {
|
||||
func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, HousekeepingConfig HousekeepingConfig, includedMetricsSet container.MetricSet, collectorHTTPClient *http.Client, rawContainerCgroupPathPrefixWhiteList, containerEnvMetadataWhiteList []string, perfEventsFile string, resctrlInterval time.Duration) (Manager, error) {
|
||||
if memoryCache == nil {
|
||||
return nil, fmt.Errorf("manager requires memory storage")
|
||||
}
|
||||
@@ -192,8 +199,8 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, houskeepingConfig
|
||||
cadvisorContainer: selfContainer,
|
||||
inHostNamespace: inHostNamespace,
|
||||
startupTime: time.Now(),
|
||||
maxHousekeepingInterval: *houskeepingConfig.Interval,
|
||||
allowDynamicHousekeeping: *houskeepingConfig.AllowDynamic,
|
||||
maxHousekeepingInterval: *HousekeepingConfig.Interval,
|
||||
allowDynamicHousekeeping: *HousekeepingConfig.AllowDynamic,
|
||||
includedMetrics: includedMetricsSet,
|
||||
containerWatchers: []watcher.ContainerWatcher{},
|
||||
eventsChannel: eventsChannel,
|
||||
@@ -265,6 +272,19 @@ type manager struct {
|
||||
containerEnvMetadataWhiteList []string
|
||||
}
|
||||
|
||||
func (m *manager) PodmanContainer(containerName string, query *info.ContainerInfoRequest) (info.ContainerInfo, error) {
|
||||
container, err := m.namespacedContainer(containerName, PodmanNamespace)
|
||||
if err != nil {
|
||||
return info.ContainerInfo{}, err
|
||||
}
|
||||
|
||||
inf, err := m.containerDataToContainerInfo(container, query)
|
||||
if err != nil {
|
||||
return info.ContainerInfo{}, err
|
||||
}
|
||||
return *inf, nil
|
||||
}
|
||||
|
||||
// Start the container manager.
|
||||
func (m *manager) Start() error {
|
||||
m.containerWatchers = container.InitializePlugins(m, m.fsInfo, m.includedMetrics)
|
||||
@@ -274,7 +294,7 @@ func (m *manager) Start() error {
|
||||
klog.Errorf("Registration of the raw container factory failed: %v", err)
|
||||
}
|
||||
|
||||
rawWatcher, err := raw.NewRawContainerWatcher()
|
||||
rawWatcher, err := raw.NewRawContainerWatcher(m.includedMetrics)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -581,14 +601,14 @@ func (m *manager) SubcontainersInfo(containerName string, query *info.ContainerI
|
||||
return m.containerDataSliceToContainerInfoSlice(containers, query)
|
||||
}
|
||||
|
||||
func (m *manager) getAllDockerContainers() map[string]*containerData {
|
||||
func (m *manager) getAllNamespacedContainers(ns string) map[string]*containerData {
|
||||
m.containersLock.RLock()
|
||||
defer m.containersLock.RUnlock()
|
||||
containers := make(map[string]*containerData, len(m.containers))
|
||||
|
||||
// Get containers in the Docker namespace.
|
||||
// Get containers in a namespace.
|
||||
for name, cont := range m.containers {
|
||||
if name.Namespace == DockerNamespace {
|
||||
if name.Namespace == ns {
|
||||
containers[cont.info.Name] = cont
|
||||
}
|
||||
}
|
||||
@@ -596,48 +616,34 @@ func (m *manager) getAllDockerContainers() map[string]*containerData {
|
||||
}
|
||||
|
||||
func (m *manager) AllDockerContainers(query *info.ContainerInfoRequest) (map[string]info.ContainerInfo, error) {
|
||||
containers := m.getAllDockerContainers()
|
||||
|
||||
output := make(map[string]info.ContainerInfo, len(containers))
|
||||
for name, cont := range containers {
|
||||
inf, err := m.containerDataToContainerInfo(cont, query)
|
||||
if err != nil {
|
||||
// Ignore the error because of race condition and return best-effort result.
|
||||
if err == memory.ErrDataNotFound {
|
||||
klog.Warningf("Error getting data for container %s because of race condition", name)
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
output[name] = *inf
|
||||
}
|
||||
return output, nil
|
||||
containers := m.getAllNamespacedContainers(DockerNamespace)
|
||||
return m.containersInfo(containers, query)
|
||||
}
|
||||
|
||||
func (m *manager) getDockerContainer(containerName string) (*containerData, error) {
|
||||
func (m *manager) namespacedContainer(containerName string, ns string) (*containerData, error) {
|
||||
m.containersLock.RLock()
|
||||
defer m.containersLock.RUnlock()
|
||||
|
||||
// Check for the container in the Docker container namespace.
|
||||
// Check for the container in the namespace.
|
||||
cont, ok := m.containers[namespacedContainerName{
|
||||
Namespace: DockerNamespace,
|
||||
Namespace: ns,
|
||||
Name: containerName,
|
||||
}]
|
||||
|
||||
// Look for container by short prefix name if no exact match found.
|
||||
if !ok {
|
||||
for contName, c := range m.containers {
|
||||
if contName.Namespace == DockerNamespace && strings.HasPrefix(contName.Name, containerName) {
|
||||
if contName.Namespace == ns && strings.HasPrefix(contName.Name, containerName) {
|
||||
if cont == nil {
|
||||
cont = c
|
||||
} else {
|
||||
return nil, fmt.Errorf("unable to find container. Container %q is not unique", containerName)
|
||||
return nil, fmt.Errorf("unable to find container in %q namespace. Container %q is not unique", ns, containerName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if cont == nil {
|
||||
return nil, fmt.Errorf("unable to find Docker container %q", containerName)
|
||||
return nil, fmt.Errorf("unable to find container %q in %q namespace", containerName, ns)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -645,7 +651,7 @@ func (m *manager) getDockerContainer(containerName string) (*containerData, erro
|
||||
}
|
||||
|
||||
func (m *manager) DockerContainer(containerName string, query *info.ContainerInfoRequest) (info.ContainerInfo, error) {
|
||||
container, err := m.getDockerContainer(containerName)
|
||||
container, err := m.namespacedContainer(containerName, DockerNamespace)
|
||||
if err != nil {
|
||||
return info.ContainerInfo{}, err
|
||||
}
|
||||
@@ -691,7 +697,7 @@ func (m *manager) GetRequestedContainersInfo(containerName string, options v2.Re
|
||||
info, err := m.containerDataToContainerInfo(data, &query)
|
||||
if err != nil {
|
||||
if err == memory.ErrDataNotFound {
|
||||
klog.Warningf("Error getting data for container %s because of race condition", name)
|
||||
klog.V(4).Infof("Error getting data for container %s because of race condition", name)
|
||||
continue
|
||||
}
|
||||
errs.append(name, "containerDataToContainerInfo", err)
|
||||
@@ -717,19 +723,23 @@ func (m *manager) getRequestedContainers(containerName string, options v2.Reques
|
||||
return containersMap, fmt.Errorf("unknown container: %q", containerName)
|
||||
}
|
||||
}
|
||||
case v2.TypeDocker:
|
||||
case v2.TypeDocker, v2.TypePodman:
|
||||
namespace := map[string]string{
|
||||
v2.TypeDocker: DockerNamespace,
|
||||
v2.TypePodman: PodmanNamespace,
|
||||
}[options.IdType]
|
||||
if !options.Recursive {
|
||||
containerName = strings.TrimPrefix(containerName, "/")
|
||||
cont, err := m.getDockerContainer(containerName)
|
||||
cont, err := m.namespacedContainer(containerName, namespace)
|
||||
if err != nil {
|
||||
return containersMap, err
|
||||
}
|
||||
containersMap[cont.info.Name] = cont
|
||||
} else {
|
||||
if containerName != "/" {
|
||||
return containersMap, fmt.Errorf("invalid request for docker container %q with subcontainers", containerName)
|
||||
return containersMap, fmt.Errorf("invalid request for %s container %q with subcontainers", options.IdType, containerName)
|
||||
}
|
||||
containersMap = m.getAllDockerContainers()
|
||||
containersMap = m.getAllNamespacedContainers(namespace)
|
||||
}
|
||||
default:
|
||||
return containersMap, fmt.Errorf("invalid request type %q", options.IdType)
|
||||
@@ -1357,6 +1367,28 @@ func (m *manager) getFsInfoByDeviceName(deviceName string) (v2.FsInfo, error) {
|
||||
return v2.FsInfo{}, fmt.Errorf("cannot find filesystem info for device %q", deviceName)
|
||||
}
|
||||
|
||||
func (m *manager) containersInfo(containers map[string]*containerData, query *info.ContainerInfoRequest) (map[string]info.ContainerInfo, error) {
|
||||
output := make(map[string]info.ContainerInfo, len(containers))
|
||||
for name, cont := range containers {
|
||||
inf, err := m.containerDataToContainerInfo(cont, query)
|
||||
if err != nil {
|
||||
// Ignore the error because of race condition and return best-effort result.
|
||||
if err == memory.ErrDataNotFound {
|
||||
klog.V(4).Infof("Error getting data for container %s because of race condition", name)
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
output[name] = *inf
|
||||
}
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func (m *manager) AllPodmanContainers(query *info.ContainerInfoRequest) (map[string]info.ContainerInfo, error) {
|
||||
containers := m.getAllNamespacedContainers(PodmanNamespace)
|
||||
return m.containersInfo(containers, query)
|
||||
}
|
||||
|
||||
func getVersionInfo() (*info.VersionInfo, error) {
|
||||
|
||||
kernelVersion := machine.KernelVersion()
|
||||
|
7
vendor/github.com/google/cadvisor/metrics/prometheus.go
generated
vendored
7
vendor/github.com/google/cadvisor/metrics/prometheus.go
generated
vendored
@@ -377,6 +377,13 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri
|
||||
getValues: func(s *info.ContainerStats) metricValues {
|
||||
return metricValues{{value: float64(s.Memory.RSS), timestamp: s.Timestamp}}
|
||||
},
|
||||
}, {
|
||||
name: "container_memory_kernel_usage",
|
||||
help: "Size of kernel memory allocated in bytes.",
|
||||
valueType: prometheus.GaugeValue,
|
||||
getValues: func(s *info.ContainerStats) metricValues {
|
||||
return metricValues{{value: float64(s.Memory.KernelUsage), timestamp: s.Timestamp}}
|
||||
},
|
||||
}, {
|
||||
name: "container_memory_mapped_file",
|
||||
help: "Size of memory mapped files in bytes.",
|
||||
|
9
vendor/github.com/google/cadvisor/metrics/prometheus_fake.go
generated
vendored
9
vendor/github.com/google/cadvisor/metrics/prometheus_fake.go
generated
vendored
@@ -350,10 +350,11 @@ func (p testSubcontainersInfoProvider) GetRequestedContainersInfo(string, v2.Req
|
||||
Unevictable: map[uint8]uint64{0: 8900, 1: 20000},
|
||||
},
|
||||
},
|
||||
Cache: 14,
|
||||
RSS: 15,
|
||||
MappedFile: 16,
|
||||
Swap: 8192,
|
||||
Cache: 14,
|
||||
RSS: 15,
|
||||
MappedFile: 16,
|
||||
KernelUsage: 17,
|
||||
Swap: 8192,
|
||||
},
|
||||
Hugetlb: map[string]info.HugetlbStats{
|
||||
"2Mi": {
|
||||
|
8
vendor/github.com/google/cadvisor/metrics/prometheus_machine.go
generated
vendored
8
vendor/github.com/google/cadvisor/metrics/prometheus_machine.go
generated
vendored
@@ -111,6 +111,14 @@ func NewPrometheusMachineCollector(i infoProvider, includedMetrics container.Met
|
||||
return metricValues{{value: float64(machineInfo.MemoryCapacity), timestamp: machineInfo.Timestamp}}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "machine_swap_bytes",
|
||||
help: "Amount of swap memory available on the machine.",
|
||||
valueType: prometheus.GaugeValue,
|
||||
getValues: func(machineInfo *info.MachineInfo) metricValues {
|
||||
return metricValues{{value: float64(machineInfo.SwapCapacity), timestamp: machineInfo.Timestamp}}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "machine_dimm_count",
|
||||
help: "Number of RAM DIMM (all types memory modules) value labeled by dimm type.",
|
||||
|
4
vendor/github.com/google/cadvisor/nvm/machine_libipmctl.go
generated
vendored
4
vendor/github.com/google/cadvisor/nvm/machine_libipmctl.go
generated
vendored
@@ -48,7 +48,7 @@ func init() {
|
||||
}
|
||||
|
||||
// getAvgPowerBudget retrieves configured power budget
|
||||
// (in watts) for NVM devices. When libipmct is not available
|
||||
// (in watts) for NVM devices. When libipmctl is not available
|
||||
// zero is returned.
|
||||
func getAvgPowerBudget() (uint, error) {
|
||||
// Get number of devices on the platform
|
||||
@@ -61,7 +61,7 @@ func getAvgPowerBudget() (uint, error) {
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
klog.Warningf("There are no NVM devices!")
|
||||
klog.V(4).Infof("There are no NVM devices.")
|
||||
return uint(0), nil
|
||||
}
|
||||
|
||||
|
12
vendor/github.com/google/cadvisor/perf/collector_libpfm.go
generated
vendored
12
vendor/github.com/google/cadvisor/perf/collector_libpfm.go
generated
vendored
@@ -62,7 +62,7 @@ type group struct {
|
||||
|
||||
var (
|
||||
isLibpfmInitialized = false
|
||||
libpmfMutex = sync.Mutex{}
|
||||
libpfmMutex = sync.Mutex{}
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -70,8 +70,8 @@ const (
|
||||
)
|
||||
|
||||
func init() {
|
||||
libpmfMutex.Lock()
|
||||
defer libpmfMutex.Unlock()
|
||||
libpfmMutex.Lock()
|
||||
defer libpfmMutex.Unlock()
|
||||
pErr := C.pfm_initialize()
|
||||
if pErr != C.PFM_SUCCESS {
|
||||
klog.Errorf("unable to initialize libpfm: %d", int(pErr))
|
||||
@@ -266,10 +266,12 @@ func readPerfEventAttr(name string, pfmGetOsEventEncoding func(string, unsafe.Po
|
||||
func pfmGetOsEventEncoding(name string, perfEventAttrMemory unsafe.Pointer) error {
|
||||
event := pfmPerfEncodeArgT{}
|
||||
fstr := C.CString("")
|
||||
defer C.free(unsafe.Pointer(fstr))
|
||||
event.fstr = unsafe.Pointer(fstr)
|
||||
event.attr = perfEventAttrMemory
|
||||
event.size = C.ulong(unsafe.Sizeof(event))
|
||||
cSafeName := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cSafeName))
|
||||
pErr := C.pfm_get_os_event_encoding(cSafeName, C.PFM_PLM0|C.PFM_PLM3, C.PFM_OS_PERF_EVENT, unsafe.Pointer(&event))
|
||||
if pErr != C.PFM_SUCCESS {
|
||||
return fmt.Errorf("unable to transform event name %s to perf_event_attr: %d", name, int(pErr))
|
||||
@@ -409,8 +411,8 @@ func (c *collector) Destroy() {
|
||||
|
||||
// Finalize terminates libpfm4 to free resources.
|
||||
func Finalize() {
|
||||
libpmfMutex.Lock()
|
||||
defer libpmfMutex.Unlock()
|
||||
libpfmMutex.Lock()
|
||||
defer libpfmMutex.Unlock()
|
||||
|
||||
klog.V(1).Info("Attempting to terminate libpfm4")
|
||||
if !isLibpfmInitialized {
|
||||
|
5
vendor/github.com/google/cadvisor/perf/uncore_libpfm.go
generated
vendored
5
vendor/github.com/google/cadvisor/perf/uncore_libpfm.go
generated
vendored
@@ -25,7 +25,6 @@ package perf
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
@@ -70,7 +69,7 @@ func getPMU(pmus uncorePMUs, gotType uint32) (*pmu, error) {
|
||||
type uncorePMUs map[string]pmu
|
||||
|
||||
func readUncorePMU(path string, name string, cpumaskRegexp *regexp.Regexp) (*pmu, error) {
|
||||
buf, err := ioutil.ReadFile(filepath.Join(path, pmuTypeFilename))
|
||||
buf, err := os.ReadFile(filepath.Join(path, pmuTypeFilename))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -80,7 +79,7 @@ func readUncorePMU(path string, name string, cpumaskRegexp *regexp.Regexp) (*pmu
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf, err = ioutil.ReadFile(filepath.Join(path, pmuCpumaskFilename))
|
||||
buf, err = os.ReadFile(filepath.Join(path, pmuCpumaskFilename))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
11
vendor/github.com/google/cadvisor/resctrl/utils.go
generated
vendored
11
vendor/github.com/google/cadvisor/resctrl/utils.go
generated
vendored
@@ -22,7 +22,6 @@ import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
@@ -42,6 +41,8 @@ const (
|
||||
cpusListFileName = "cpus_list"
|
||||
schemataFileName = "schemata"
|
||||
tasksFileName = "tasks"
|
||||
modeFileName = "mode"
|
||||
sizeFileName = "size"
|
||||
infoDirName = "info"
|
||||
monDataDirName = "mon_data"
|
||||
monGroupsDirName = "mon_groups"
|
||||
@@ -72,6 +73,8 @@ var (
|
||||
monGroupsDirName: {},
|
||||
schemataFileName: {},
|
||||
tasksFileName: {},
|
||||
modeFileName: {},
|
||||
sizeFileName: {},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -189,7 +192,7 @@ func getPids(containerName string) ([]int, error) {
|
||||
func getAllProcessThreads(path string) ([]int, error) {
|
||||
processThreads := make([]int, 0)
|
||||
|
||||
threadDirs, err := ioutil.ReadDir(path)
|
||||
threadDirs, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
return processThreads, err
|
||||
}
|
||||
@@ -216,7 +219,7 @@ func findGroup(group string, pids []string, includeGroup bool, exclusive bool) (
|
||||
availablePaths = append(availablePaths, group)
|
||||
}
|
||||
|
||||
files, err := ioutil.ReadDir(group)
|
||||
files, err := os.ReadDir(group)
|
||||
for _, file := range files {
|
||||
if _, ok := groupDirectories[file.Name()]; !ok {
|
||||
availablePaths = append(availablePaths, filepath.Join(group, file.Name()))
|
||||
@@ -296,7 +299,7 @@ func readTasksFile(tasksPath string) (map[string]struct{}, error) {
|
||||
}
|
||||
|
||||
func readStatFrom(path string, vendorID string) (uint64, error) {
|
||||
context, err := ioutil.ReadFile(path)
|
||||
context, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
2
vendor/github.com/google/cadvisor/summary/summary.go
generated
vendored
2
vendor/github.com/google/cadvisor/summary/summary.go
generated
vendored
@@ -78,7 +78,7 @@ func (s *StatsSummary) AddSample(stat v1.ContainerStats) error {
|
||||
}
|
||||
if elapsed > 60*time.Second {
|
||||
// Make a minute sample. This works with dynamic housekeeping as long
|
||||
// as we keep max dynamic houskeeping period close to a minute.
|
||||
// as we keep max dynamic housekeeping period close to a minute.
|
||||
minuteSample := GetMinutePercentiles(s.secondSamples)
|
||||
// Clear seconds samples. Keep the latest sample for continuity.
|
||||
// Copying and resizing helps avoid slice re-allocation.
|
||||
|
6
vendor/github.com/google/cadvisor/utils/cloudinfo/azure/azure.go
generated
vendored
6
vendor/github.com/google/cadvisor/utils/cloudinfo/azure/azure.go
generated
vendored
@@ -15,7 +15,7 @@
|
||||
package cloudinfo
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
@@ -37,7 +37,7 @@ type provider struct{}
|
||||
var _ cloudinfo.CloudProvider = provider{}
|
||||
|
||||
func (provider) IsActiveProvider() bool {
|
||||
data, err := ioutil.ReadFile(sysVendorFileName)
|
||||
data, err := os.ReadFile(sysVendorFileName)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -50,7 +50,7 @@ func (provider) GetInstanceType() info.InstanceType {
|
||||
}
|
||||
|
||||
func (provider) GetInstanceID() info.InstanceID {
|
||||
data, err := ioutil.ReadFile(biosUUIDFileName)
|
||||
data, err := os.ReadFile(biosUUIDFileName)
|
||||
if err != nil {
|
||||
return info.UnNamedInstance
|
||||
}
|
||||
|
4
vendor/github.com/google/cadvisor/utils/cloudinfo/gce/gce.go
generated
vendored
4
vendor/github.com/google/cadvisor/utils/cloudinfo/gce/gce.go
generated
vendored
@@ -15,7 +15,7 @@
|
||||
package gce
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
@@ -39,7 +39,7 @@ type provider struct{}
|
||||
var _ cloudinfo.CloudProvider = provider{}
|
||||
|
||||
func (provider) IsActiveProvider() bool {
|
||||
data, err := ioutil.ReadFile(gceProductName)
|
||||
data, err := os.ReadFile(gceProductName)
|
||||
if err != nil {
|
||||
klog.V(2).Infof("Error while reading product_name: %v", err)
|
||||
return false
|
||||
|
151
vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go
generated
vendored
151
vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go
generated
vendored
@@ -17,7 +17,6 @@ package sysfs
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -102,6 +101,9 @@ type SysFs interface {
|
||||
GetBlockDeviceScheduler(string) (string, error)
|
||||
// Get device major:minor number string.
|
||||
GetBlockDeviceNumbers(string) (string, error)
|
||||
// Is the device "hidden" (meaning will not have a device handle)
|
||||
// This is the case with native nvme multipathing.
|
||||
IsBlockDeviceHidden(string) (bool, error)
|
||||
|
||||
GetNetworkDevices() ([]os.FileInfo, error)
|
||||
GetNetworkAddress(string) (string, error)
|
||||
@@ -124,10 +126,14 @@ type SysFs interface {
|
||||
IsCPUOnline(dir string) bool
|
||||
}
|
||||
|
||||
type realSysFs struct{}
|
||||
type realSysFs struct {
|
||||
cpuPath string
|
||||
}
|
||||
|
||||
func NewRealSysFs() SysFs {
|
||||
return &realSysFs{}
|
||||
return &realSysFs{
|
||||
cpuPath: "/sys/devices/system/cpu",
|
||||
}
|
||||
}
|
||||
|
||||
func (fs *realSysFs) GetNodesPaths() ([]string, error) {
|
||||
@@ -142,7 +148,7 @@ func (fs *realSysFs) GetCPUsPaths(cpusPath string) ([]string, error) {
|
||||
|
||||
func (fs *realSysFs) GetCoreID(cpuPath string) (string, error) {
|
||||
coreIDFilePath := fmt.Sprintf("%s%s", cpuPath, coreIDFilePath)
|
||||
coreID, err := ioutil.ReadFile(coreIDFilePath)
|
||||
coreID, err := os.ReadFile(coreIDFilePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -151,7 +157,7 @@ func (fs *realSysFs) GetCoreID(cpuPath string) (string, error) {
|
||||
|
||||
func (fs *realSysFs) GetCPUPhysicalPackageID(cpuPath string) (string, error) {
|
||||
packageIDFilePath := fmt.Sprintf("%s%s", cpuPath, packageIDFilePath)
|
||||
packageID, err := ioutil.ReadFile(packageIDFilePath)
|
||||
packageID, err := os.ReadFile(packageIDFilePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -160,7 +166,7 @@ func (fs *realSysFs) GetCPUPhysicalPackageID(cpuPath string) (string, error) {
|
||||
|
||||
func (fs *realSysFs) GetMemInfo(nodePath string) (string, error) {
|
||||
meminfoPath := fmt.Sprintf("%s/%s", nodePath, meminfoFile)
|
||||
meminfo, err := ioutil.ReadFile(meminfoPath)
|
||||
meminfo, err := os.ReadFile(meminfoPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -169,7 +175,7 @@ func (fs *realSysFs) GetMemInfo(nodePath string) (string, error) {
|
||||
|
||||
func (fs *realSysFs) GetDistances(nodePath string) (string, error) {
|
||||
distancePath := fmt.Sprintf("%s/%s", nodePath, distanceFile)
|
||||
distance, err := ioutil.ReadFile(distancePath)
|
||||
distance, err := os.ReadFile(distancePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -177,12 +183,16 @@ func (fs *realSysFs) GetDistances(nodePath string) (string, error) {
|
||||
}
|
||||
|
||||
func (fs *realSysFs) GetHugePagesInfo(hugePagesDirectory string) ([]os.FileInfo, error) {
|
||||
return ioutil.ReadDir(hugePagesDirectory)
|
||||
dirs, err := os.ReadDir(hugePagesDirectory)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toFileInfo(dirs)
|
||||
}
|
||||
|
||||
func (fs *realSysFs) GetHugePagesNr(hugepagesDirectory string, hugePageName string) (string, error) {
|
||||
hugePageFilePath := fmt.Sprintf("%s%s/%s", hugepagesDirectory, hugePageName, HugePagesNrFile)
|
||||
hugePageFile, err := ioutil.ReadFile(hugePageFilePath)
|
||||
hugePageFile, err := os.ReadFile(hugePageFilePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -190,19 +200,43 @@ func (fs *realSysFs) GetHugePagesNr(hugepagesDirectory string, hugePageName stri
|
||||
}
|
||||
|
||||
func (fs *realSysFs) GetBlockDevices() ([]os.FileInfo, error) {
|
||||
return ioutil.ReadDir(blockDir)
|
||||
dirs, err := os.ReadDir(blockDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toFileInfo(dirs)
|
||||
}
|
||||
|
||||
func (fs *realSysFs) GetBlockDeviceNumbers(name string) (string, error) {
|
||||
dev, err := ioutil.ReadFile(path.Join(blockDir, name, "/dev"))
|
||||
dev, err := os.ReadFile(path.Join(blockDir, name, "/dev"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(dev), nil
|
||||
}
|
||||
|
||||
func (fs *realSysFs) IsBlockDeviceHidden(name string) (bool, error) {
|
||||
// See: https://www.kernel.org/doc/Documentation/ABI/stable/sysfs-block
|
||||
// https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git
|
||||
// - c8487d854ba5 ("lsblk: Ignore hidden devices")
|
||||
devHiddenPath := path.Join(blockDir, name, "/hidden")
|
||||
hidden, err := os.ReadFile(devHiddenPath)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
// older OS may not have /hidden sysfs entry, so for sure
|
||||
// it is not a hidden device...
|
||||
return false, nil
|
||||
}
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to read %s: %w", devHiddenPath, err)
|
||||
}
|
||||
if string(hidden) == "1" {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (fs *realSysFs) GetBlockDeviceScheduler(name string) (string, error) {
|
||||
sched, err := ioutil.ReadFile(path.Join(blockDir, name, "/queue/scheduler"))
|
||||
sched, err := os.ReadFile(path.Join(blockDir, name, "/queue/scheduler"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -210,7 +244,7 @@ func (fs *realSysFs) GetBlockDeviceScheduler(name string) (string, error) {
|
||||
}
|
||||
|
||||
func (fs *realSysFs) GetBlockDeviceSize(name string) (string, error) {
|
||||
size, err := ioutil.ReadFile(path.Join(blockDir, name, "/size"))
|
||||
size, err := os.ReadFile(path.Join(blockDir, name, "/size"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -218,13 +252,17 @@ func (fs *realSysFs) GetBlockDeviceSize(name string) (string, error) {
|
||||
}
|
||||
|
||||
func (fs *realSysFs) GetNetworkDevices() ([]os.FileInfo, error) {
|
||||
files, err := ioutil.ReadDir(netDir)
|
||||
dirs, err := os.ReadDir(netDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
files, err := toFileInfo(dirs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Filter out non-directory & non-symlink files
|
||||
var dirs []os.FileInfo
|
||||
filtered := []os.FileInfo{}
|
||||
for _, f := range files {
|
||||
if f.Mode()|os.ModeSymlink != 0 {
|
||||
f, err = os.Stat(path.Join(netDir, f.Name()))
|
||||
@@ -233,14 +271,14 @@ func (fs *realSysFs) GetNetworkDevices() ([]os.FileInfo, error) {
|
||||
}
|
||||
}
|
||||
if f.IsDir() {
|
||||
dirs = append(dirs, f)
|
||||
filtered = append(filtered, f)
|
||||
}
|
||||
}
|
||||
return dirs, nil
|
||||
return filtered, nil
|
||||
}
|
||||
|
||||
func (fs *realSysFs) GetNetworkAddress(name string) (string, error) {
|
||||
address, err := ioutil.ReadFile(path.Join(netDir, name, "/address"))
|
||||
address, err := os.ReadFile(path.Join(netDir, name, "/address"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -248,7 +286,7 @@ func (fs *realSysFs) GetNetworkAddress(name string) (string, error) {
|
||||
}
|
||||
|
||||
func (fs *realSysFs) GetNetworkMtu(name string) (string, error) {
|
||||
mtu, err := ioutil.ReadFile(path.Join(netDir, name, "/mtu"))
|
||||
mtu, err := os.ReadFile(path.Join(netDir, name, "/mtu"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -256,7 +294,7 @@ func (fs *realSysFs) GetNetworkMtu(name string) (string, error) {
|
||||
}
|
||||
|
||||
func (fs *realSysFs) GetNetworkSpeed(name string) (string, error) {
|
||||
speed, err := ioutil.ReadFile(path.Join(netDir, name, "/speed"))
|
||||
speed, err := os.ReadFile(path.Join(netDir, name, "/speed"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -265,7 +303,7 @@ func (fs *realSysFs) GetNetworkSpeed(name string) (string, error) {
|
||||
|
||||
func (fs *realSysFs) GetNetworkStatValue(dev string, stat string) (uint64, error) {
|
||||
statPath := path.Join(netDir, dev, "/statistics", stat)
|
||||
out, err := ioutil.ReadFile(statPath)
|
||||
out, err := os.ReadFile(statPath)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to read stat from %q for device %q", statPath, dev)
|
||||
}
|
||||
@@ -279,7 +317,23 @@ func (fs *realSysFs) GetNetworkStatValue(dev string, stat string) (uint64, error
|
||||
|
||||
func (fs *realSysFs) GetCaches(id int) ([]os.FileInfo, error) {
|
||||
cpuPath := fmt.Sprintf("%s%d/cache", cacheDir, id)
|
||||
return ioutil.ReadDir(cpuPath)
|
||||
dir, err := os.ReadDir(cpuPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toFileInfo(dir)
|
||||
}
|
||||
|
||||
func toFileInfo(dirs []os.DirEntry) ([]os.FileInfo, error) {
|
||||
info := []os.FileInfo{}
|
||||
for _, dir := range dirs {
|
||||
fI, err := dir.Info()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
info = append(info, fI)
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func bitCount(i uint64) (count int) {
|
||||
@@ -293,7 +347,7 @@ func bitCount(i uint64) (count int) {
|
||||
}
|
||||
|
||||
func getCPUCount(cache string) (count int, err error) {
|
||||
out, err := ioutil.ReadFile(path.Join(cache, "/shared_cpu_map"))
|
||||
out, err := os.ReadFile(path.Join(cache, "/shared_cpu_map"))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -311,7 +365,7 @@ func getCPUCount(cache string) (count int, err error) {
|
||||
|
||||
func (fs *realSysFs) GetCacheInfo(cpu int, name string) (CacheInfo, error) {
|
||||
cachePath := fmt.Sprintf("%s%d/cache/%s", cacheDir, cpu, name)
|
||||
out, err := ioutil.ReadFile(path.Join(cachePath, "/id"))
|
||||
out, err := os.ReadFile(path.Join(cachePath, "/id"))
|
||||
if err != nil {
|
||||
return CacheInfo{}, err
|
||||
}
|
||||
@@ -321,7 +375,7 @@ func (fs *realSysFs) GetCacheInfo(cpu int, name string) (CacheInfo, error) {
|
||||
return CacheInfo{}, err
|
||||
}
|
||||
|
||||
out, err = ioutil.ReadFile(path.Join(cachePath, "/size"))
|
||||
out, err = os.ReadFile(path.Join(cachePath, "/size"))
|
||||
if err != nil {
|
||||
return CacheInfo{}, err
|
||||
}
|
||||
@@ -332,7 +386,7 @@ func (fs *realSysFs) GetCacheInfo(cpu int, name string) (CacheInfo, error) {
|
||||
}
|
||||
// convert to bytes
|
||||
size = size * 1024
|
||||
out, err = ioutil.ReadFile(path.Join(cachePath, "/level"))
|
||||
out, err = os.ReadFile(path.Join(cachePath, "/level"))
|
||||
if err != nil {
|
||||
return CacheInfo{}, err
|
||||
}
|
||||
@@ -342,7 +396,7 @@ func (fs *realSysFs) GetCacheInfo(cpu int, name string) (CacheInfo, error) {
|
||||
return CacheInfo{}, err
|
||||
}
|
||||
|
||||
out, err = ioutil.ReadFile(path.Join(cachePath, "/type"))
|
||||
out, err = os.ReadFile(path.Join(cachePath, "/type"))
|
||||
if err != nil {
|
||||
return CacheInfo{}, err
|
||||
}
|
||||
@@ -361,13 +415,13 @@ func (fs *realSysFs) GetCacheInfo(cpu int, name string) (CacheInfo, error) {
|
||||
}
|
||||
|
||||
func (fs *realSysFs) GetSystemUUID() (string, error) {
|
||||
if id, err := ioutil.ReadFile(path.Join(dmiDir, "id", "product_uuid")); err == nil {
|
||||
if id, err := os.ReadFile(path.Join(dmiDir, "id", "product_uuid")); err == nil {
|
||||
return strings.TrimSpace(string(id)), nil
|
||||
} else if id, err = ioutil.ReadFile(path.Join(ppcDevTree, "system-id")); err == nil {
|
||||
} else if id, err = os.ReadFile(path.Join(ppcDevTree, "system-id")); err == nil {
|
||||
return strings.TrimSpace(strings.TrimRight(string(id), "\000")), nil
|
||||
} else if id, err = ioutil.ReadFile(path.Join(ppcDevTree, "vm,uuid")); err == nil {
|
||||
} else if id, err = os.ReadFile(path.Join(ppcDevTree, "vm,uuid")); err == nil {
|
||||
return strings.TrimSpace(strings.TrimRight(string(id), "\000")), nil
|
||||
} else if id, err = ioutil.ReadFile(path.Join(s390xDevTree, "machine-id")); err == nil {
|
||||
} else if id, err = os.ReadFile(path.Join(s390xDevTree, "machine-id")); err == nil {
|
||||
return strings.TrimSpace(string(id)), nil
|
||||
} else {
|
||||
return "", err
|
||||
@@ -375,19 +429,19 @@ func (fs *realSysFs) GetSystemUUID() (string, error) {
|
||||
}
|
||||
|
||||
func (fs *realSysFs) IsCPUOnline(cpuPath string) bool {
|
||||
onlinePath, err := filepath.Abs(cpuPath + "/../online")
|
||||
cpuOnlinePath, err := filepath.Abs(fs.cpuPath + "/online")
|
||||
if err != nil {
|
||||
klog.V(1).Infof("Unable to get absolute path for %s", cpuPath)
|
||||
return false
|
||||
}
|
||||
|
||||
// Quick check to determine if file exists: if it does not then kernel CPU hotplug is disabled and all CPUs are online.
|
||||
_, err = os.Stat(onlinePath)
|
||||
_, err = os.Stat(cpuOnlinePath)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
return true
|
||||
}
|
||||
if err != nil {
|
||||
klog.V(1).Infof("Unable to stat %s: %s", onlinePath, err)
|
||||
klog.V(1).Infof("Unable to stat %s: %s", cpuOnlinePath, err)
|
||||
}
|
||||
|
||||
cpuID, err := getCPUID(cpuPath)
|
||||
@@ -396,7 +450,7 @@ func (fs *realSysFs) IsCPUOnline(cpuPath string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
isOnline, err := isCPUOnline(onlinePath, cpuID)
|
||||
isOnline, err := isCPUOnline(cpuOnlinePath, cpuID)
|
||||
if err != nil {
|
||||
klog.V(1).Infof("Unable to get online CPUs list: %s", err)
|
||||
return false
|
||||
@@ -422,7 +476,7 @@ func getCPUID(dir string) (uint16, error) {
|
||||
// It parses CPU list (such as: 0,3-5,10) into a struct that allows to determine quickly if CPU or particular ID is online.
|
||||
// see: https://github.com/opencontainers/runc/blob/ab27e12cebf148aa5d1ee3ad13d9fc7ae12bf0b6/libcontainer/cgroups/fs/cpuset.go#L45
|
||||
func isCPUOnline(path string, cpuID uint16) (bool, error) {
|
||||
fileContent, err := ioutil.ReadFile(path)
|
||||
fileContent, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -448,10 +502,9 @@ func isCPUOnline(path string, cpuID uint16) (bool, error) {
|
||||
if min > max {
|
||||
return false, fmt.Errorf("invalid values in %s", path)
|
||||
}
|
||||
for i := min; i <= max; i++ {
|
||||
if uint16(i) == cpuID {
|
||||
return true, nil
|
||||
}
|
||||
// Return true, if the CPU under consideration is in the range of online CPUs.
|
||||
if cpuID >= uint16(min) && cpuID <= uint16(max) {
|
||||
return true, nil
|
||||
}
|
||||
case 1:
|
||||
value, err := strconv.ParseUint(s, 10, 16)
|
||||
@@ -469,21 +522,21 @@ func isCPUOnline(path string, cpuID uint16) (bool, error) {
|
||||
|
||||
// Looks for sysfs cpu path containing given CPU property, e.g. core_id or physical_package_id
|
||||
// and returns number of unique values of given property, exemplary usage: getting number of CPU physical cores
|
||||
func GetUniqueCPUPropertyCount(cpuBusPath string, propertyName string) int {
|
||||
absCPUBusPath, err := filepath.Abs(cpuBusPath)
|
||||
func GetUniqueCPUPropertyCount(cpuAttributesPath string, propertyName string) int {
|
||||
absCPUAttributesPath, err := filepath.Abs(cpuAttributesPath)
|
||||
if err != nil {
|
||||
klog.Errorf("Cannot make %s absolute", cpuBusPath)
|
||||
klog.Errorf("Cannot make %s absolute", cpuAttributesPath)
|
||||
return 0
|
||||
}
|
||||
pathPattern := absCPUBusPath + "/cpu*[0-9]"
|
||||
pathPattern := absCPUAttributesPath + "/cpu*[0-9]"
|
||||
sysCPUPaths, err := filepath.Glob(pathPattern)
|
||||
if err != nil {
|
||||
klog.Errorf("Cannot find files matching pattern (pathPattern: %s), number of unique %s set to 0", pathPattern, propertyName)
|
||||
return 0
|
||||
}
|
||||
onlinePath, err := filepath.Abs(cpuBusPath + "/online")
|
||||
cpuOnlinePath, err := filepath.Abs(cpuAttributesPath + "/online")
|
||||
if err != nil {
|
||||
klog.V(1).Infof("Unable to get absolute path for %s", cpuBusPath+"/../online")
|
||||
klog.V(1).Infof("Unable to get absolute path for %s", cpuAttributesPath+"/../online")
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -498,7 +551,7 @@ func GetUniqueCPUPropertyCount(cpuBusPath string, propertyName string) int {
|
||||
klog.V(1).Infof("Unable to get CPU ID from path %s: %s", sysCPUPath, err)
|
||||
return 0
|
||||
}
|
||||
isOnline, err := isCPUOnline(onlinePath, cpuID)
|
||||
isOnline, err := isCPUOnline(cpuOnlinePath, cpuID)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
klog.V(1).Infof("Unable to determine CPU online state: %s", err)
|
||||
continue
|
||||
@@ -507,13 +560,13 @@ func GetUniqueCPUPropertyCount(cpuBusPath string, propertyName string) int {
|
||||
continue
|
||||
}
|
||||
propertyPath := filepath.Join(sysCPUPath, sysFsCPUTopology, propertyName)
|
||||
propertyVal, err := ioutil.ReadFile(propertyPath)
|
||||
propertyVal, err := os.ReadFile(propertyPath)
|
||||
if err != nil {
|
||||
klog.Warningf("Cannot open %s, assuming 0 for %s of CPU %d", propertyPath, propertyName, cpuID)
|
||||
propertyVal = []byte("0")
|
||||
}
|
||||
packagePath := filepath.Join(sysCPUPath, sysFsCPUTopology, CPUPhysicalPackageID)
|
||||
packageVal, err := ioutil.ReadFile(packagePath)
|
||||
packageVal, err := os.ReadFile(packagePath)
|
||||
if err != nil {
|
||||
klog.Warningf("Cannot open %s, assuming 0 %s of CPU %d", packagePath, CPUPhysicalPackageID, cpuID)
|
||||
packageVal = []byte("0")
|
||||
|
14
vendor/github.com/google/cadvisor/utils/sysinfo/sysinfo.go
generated
vendored
14
vendor/github.com/google/cadvisor/utils/sysinfo/sysinfo.go
generated
vendored
@@ -57,6 +57,16 @@ func GetBlockDeviceInfo(sysfs sysfs.SysFs) (map[string]info.DiskInfo, error) {
|
||||
if strings.HasPrefix(name, "loop") || strings.HasPrefix(name, "ram") || strings.HasPrefix(name, "sr") {
|
||||
continue
|
||||
}
|
||||
// Ignore "hidden" devices (i.e. nvme path device sysfs entries).
|
||||
// These devices are in the form of /dev/nvme$Xc$Yn$Z and will
|
||||
// not have a device handle (i.e. "hidden")
|
||||
isHidden, err := sysfs.IsBlockDeviceHidden(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if isHidden {
|
||||
continue
|
||||
}
|
||||
diskInfo := info.DiskInfo{
|
||||
Name: name,
|
||||
}
|
||||
@@ -104,7 +114,7 @@ func GetNetworkDevices(sysfs sysfs.SysFs) ([]info.NetInfo, error) {
|
||||
for _, dev := range devs {
|
||||
name := dev.Name()
|
||||
// Ignore docker, loopback, and veth devices.
|
||||
ignoredDevices := []string{"lo", "veth", "docker"}
|
||||
ignoredDevices := []string{"lo", "veth", "docker", "nerdctl"}
|
||||
ignored := false
|
||||
for _, prefix := range ignoredDevices {
|
||||
if strings.HasPrefix(name, prefix) {
|
||||
@@ -200,7 +210,7 @@ func GetNodesInfo(sysFs sysfs.SysFs) ([]info.Node, int, error) {
|
||||
}
|
||||
|
||||
if len(nodesDirs) == 0 {
|
||||
klog.Warningf("Nodes topology is not available, providing CPU topology")
|
||||
klog.V(4).Info("Nodes topology is not available, providing CPU topology")
|
||||
return getCPUTopology(sysFs)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user