github.com/openshift/moby-moby@v1.13.2-0.20170601211448-f5ec1e2936dc/daemon/stats_collector_unix.go (about) 1 // +build !windows,!solaris 2 3 package daemon 4 5 import ( 6 "fmt" 7 "os" 8 "strconv" 9 "strings" 10 11 sysinfo "github.com/docker/docker/pkg/system" 12 "github.com/opencontainers/runc/libcontainer/system" 13 ) 14 15 /* 16 #include <unistd.h> 17 */ 18 import "C" 19 20 // platformNewStatsCollector performs platform specific initialisation of the 21 // statsCollector structure. 22 func platformNewStatsCollector(s *statsCollector) { 23 s.clockTicksPerSecond = uint64(system.GetClockTicks()) 24 meminfo, err := sysinfo.ReadMemInfo() 25 if err == nil && meminfo.MemTotal > 0 { 26 s.machineMemory = uint64(meminfo.MemTotal) 27 } 28 } 29 30 const nanoSecondsPerSecond = 1e9 31 32 // getSystemCPUUsage returns the host system's cpu usage in 33 // nanoseconds. An error is returned if the format of the underlying 34 // file does not match. 35 // 36 // Uses /proc/stat defined by POSIX. Looks for the cpu 37 // statistics line and then sums up the first seven fields 38 // provided. See `man 5 proc` for details on specific field 39 // information. 40 func (s *statsCollector) getSystemCPUUsage() (uint64, error) { 41 var line string 42 f, err := os.Open("/proc/stat") 43 if err != nil { 44 return 0, err 45 } 46 defer func() { 47 s.bufReader.Reset(nil) 48 f.Close() 49 }() 50 s.bufReader.Reset(f) 51 err = nil 52 for err == nil { 53 line, err = s.bufReader.ReadString('\n') 54 if err != nil { 55 break 56 } 57 parts := strings.Fields(line) 58 switch parts[0] { 59 case "cpu": 60 if len(parts) < 8 { 61 return 0, fmt.Errorf("invalid number of cpu fields") 62 } 63 var totalClockTicks uint64 64 for _, i := range parts[1:8] { 65 v, err := strconv.ParseUint(i, 10, 64) 66 if err != nil { 67 return 0, fmt.Errorf("Unable to convert value %s to int: %s", i, err) 68 } 69 totalClockTicks += v 70 } 71 return (totalClockTicks * nanoSecondsPerSecond) / 72 s.clockTicksPerSecond, nil 73 } 74 } 75 return 0, fmt.Errorf("invalid stat format. Error trying to parse the '/proc/stat' file") 76 } 77 78 func (s *statsCollector) getNumberOnlineCPUs() (uint32, error) { 79 i, err := C.sysconf(C._SC_NPROCESSORS_ONLN) 80 if err != nil { 81 return 0, err 82 } 83 return uint32(i), nil 84 }