Get cgroup and networking stats of the specified container
()
| 74 | |
| 75 | // Get cgroup and networking stats of the specified container |
| 76 | func (h *Handler) GetStats() (*info.ContainerStats, error) { |
| 77 | ignoreStatsError := false |
| 78 | if cgroups.IsCgroup2UnifiedMode() { |
| 79 | // On cgroup v2 the root cgroup stats have been introduced in recent kernel versions, |
| 80 | // so not all kernel versions have all the data. This means that stat fetching can fail |
| 81 | // due to lacking cgroup stat files, but that some data is provided. |
| 82 | if h.cgroupManager.Path("") == fs2.UnifiedMountpoint { |
| 83 | ignoreStatsError = true |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | cgroupStats, err := h.cgroupManager.GetStats() |
| 88 | if err != nil { |
| 89 | if !ignoreStatsError { |
| 90 | return nil, err |
| 91 | } |
| 92 | klog.V(4).Infof("Ignoring errors when gathering stats for root cgroup since some controllers don't have stats on the root cgroup: %v", err) |
| 93 | } |
| 94 | stats := newContainerStats(cgroupStats, h.includedMetrics) |
| 95 | |
| 96 | if cgroups.IsCgroup2UnifiedMode() { |
| 97 | setMemoryEvents(h.cgroupManager.Path(""), stats) |
| 98 | } |
| 99 | |
| 100 | if h.includedMetrics.Has(container.ProcessSchedulerMetrics) { |
| 101 | stats.Cpu.Schedstat, err = h.schedulerStatsFromProcs() |
| 102 | if err != nil { |
| 103 | klog.V(4).Infof("Unable to get Process Scheduler Stats: %v", err) |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | if h.includedMetrics.Has(container.ReferencedMemoryMetrics) { |
| 108 | h.cycles++ |
| 109 | pids, err := h.cgroupManager.GetPids() |
| 110 | if err != nil { |
| 111 | klog.V(4).Infof("Could not get PIDs for container %d: %v", h.pid, err) |
| 112 | } else { |
| 113 | stats.ReferencedMemory, err = referencedBytesStat(pids, h.cycles, *referencedResetInterval) |
| 114 | if err != nil { |
| 115 | klog.V(4).Infof("Unable to get referenced bytes: %v", err) |
| 116 | } |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | // If we know the pid then get network stats from /proc/<pid>/net/dev |
| 121 | if h.pid > 0 { |
| 122 | stats.Network = &info.NetworkStats{} |
| 123 | if h.includedMetrics.Has(container.NetworkUsageMetrics) { |
| 124 | netStats, err := networkStatsFromProc(h.rootFs, h.pid) |
| 125 | if err != nil { |
| 126 | klog.V(4).Infof("Unable to get network stats from pid %d: %v", h.pid, err) |
| 127 | } else { |
| 128 | stats.Network.Interfaces = append(stats.Network.Interfaces, netStats...) |
| 129 | } |
| 130 | } |
| 131 | if h.includedMetrics.Has(container.NetworkTcpUsageMetrics) { |
| 132 | t, err := tcpStatsFromProc(h.rootFs, h.pid, "net/tcp") |
| 133 | if err != nil { |
nothing calls this directly
no test coverage detected