readSystemCPUUsage parses CPU usage information from a reader providing proc/stat format data. It returns the total CPU usage in nanoseconds and the number of CPUs. More: https://github.com/moby/moby/blob/26db31fdab628a2345ed8f179e575099384166a9/daemon/stats_unix.go#L327-L368
(r io.Reader)
| 148 | // and the number of CPUs. More: |
| 149 | // https://github.com/moby/moby/blob/26db31fdab628a2345ed8f179e575099384166a9/daemon/stats_unix.go#L327-L368 |
| 150 | func readSystemCPUUsage(r io.Reader) (cpuUsage uint64, cpuNum uint32, _ error) { |
| 151 | rdr := bufio.NewReaderSize(r, 1024) |
| 152 | |
| 153 | for { |
| 154 | data, isPartial, err := rdr.ReadLine() |
| 155 | |
| 156 | if err != nil { |
| 157 | return 0, 0, fmt.Errorf("error scanning /proc/stat file: %w", err) |
| 158 | } |
| 159 | // Assume all cpu* records are at the start of the file, like glibc: |
| 160 | // https://github.com/bminor/glibc/blob/5d00c201b9a2da768a79ea8d5311f257871c0b43/sysdeps/unix/sysv/linux/getsysstats.c#L108-L135 |
| 161 | if isPartial || len(data) < 4 { |
| 162 | break |
| 163 | } |
| 164 | line := string(data) |
| 165 | if line[:3] != "cpu" { |
| 166 | break |
| 167 | } |
| 168 | if line[3] == ' ' { |
| 169 | parts := strings.Fields(line) |
| 170 | if len(parts) < 8 { |
| 171 | return 0, 0, fmt.Errorf("invalid number of cpu fields") |
| 172 | } |
| 173 | var totalClockTicks uint64 |
| 174 | for _, i := range parts[1:8] { |
| 175 | v, err := strconv.ParseUint(i, 10, 64) |
| 176 | if err != nil { |
| 177 | return 0, 0, fmt.Errorf("unable to convert value %s to int: %w", i, err) |
| 178 | } |
| 179 | totalClockTicks += v |
| 180 | } |
| 181 | cpuUsage = (totalClockTicks * nanoSecondsPerSecond) / clockTicksPerSecond |
| 182 | } |
| 183 | if '0' <= line[3] && line[3] <= '9' { |
| 184 | cpuNum++ |
| 185 | } |
| 186 | } |
| 187 | return cpuUsage, cpuNum, nil |
| 188 | } |
no outgoing calls
no test coverage detected
searching dependent graphs…