- scanner := bufio.NewScanner(stats)
- Iface: for scanner.Scan() {
- var ifName string
- var rx, tx int64
- words := bufio.NewScanner(strings.NewReader(scanner.Text()))
- words.Split(bufio.ScanWords)
- wordIndex := 0
- for words.Scan() {
- word := words.Text()
- switch wordIndex {
- case 0:
- ifName = strings.TrimRight(word, ":")
- case 1:
- if _, err := fmt.Sscanf(word, "%d", &rx); err != nil {
- continue Iface
- }
- case 9:
- if _, err := fmt.Sscanf(word, "%d", &tx); err != nil {
- continue Iface
- }
- }
- wordIndex++
- }
- if ifName == "lo" || ifName == "" || wordIndex != 17 {
- // Skip loopback interface and lines with wrong format
- continue
- }
- nextSample := NetSample{}
- nextSample.sampleTime = sampleTime
- nextSample.txBytes = tx
- nextSample.rxBytes = rx
- var delta string
- if lastSample, ok := lastStat[ifName]; ok {
- interval := nextSample.sampleTime.Sub(lastSample.sampleTime).Seconds()
- delta = fmt.Sprintf(" -- interval %.4f seconds %d tx %d rx",
- interval,
- tx - lastSample.txBytes,
- rx - lastSample.rxBytes)
- }
- stderr <- fmt.Sprintf("crunchstat: net:%s %d tx %d rx%s",
- ifName, tx, rx, delta)
- lastStat[ifName] = nextSample
- }
- return lastStat
-}
-
-func PollCgroupStats(cgroup Cgroup, stderr chan string, poll int64, stop_poll_chan <-chan bool) {
- var last_user int64 = -1
- var last_sys int64 = -1
- var last_cpucount int64 = 0
-
- user_hz := float64(C.sysconf(C._SC_CLK_TCK))
-
- var lastNetStat map[string]NetSample = nil
-
- poll_chan := make(chan bool, 1)
- go func() {
- // Send periodic poll events.
- poll_chan <- true
- for {
- time.Sleep(time.Duration(poll) * time.Millisecond)
- poll_chan <- true
- }
- }()
- for {
- bedtime := time.Now()
- select {
- case <-stop_poll_chan:
- return
- case <-poll_chan:
- // Emit stats, then select again.
- }
- morning := time.Now()
- elapsed := morning.Sub(bedtime).Seconds()
- cpuset_cpus := FindStat(stderr, cgroup, "cpuset", "cpuset.cpus")
- if cpuset_cpus != "" {
- b, err := OpenAndReadAll(cpuset_cpus, stderr)
- if err != nil {
- // cgroup probably gone -- skip other stats too.
- continue
- }
- sp := strings.Split(string(b), ",")
- cpus := int64(0)
- for _, v := range sp {
- var min, max int64
- n, _ := fmt.Sscanf(v, "%d-%d", &min, &max)
- if n == 2 {
- cpus += (max - min) + 1
- } else {
- cpus += 1
- }
- }
- last_cpucount = cpus
- }
- cpuacct_stat := FindStat(stderr, cgroup, "cpuacct", "cpuacct.stat")
- if cpuacct_stat != "" {
- b, err := OpenAndReadAll(cpuacct_stat, stderr)
- if err != nil {
- // Next time around, last_user would
- // be >1 interval old, so stats will
- // be incorrect. Start over instead.
- last_user = -1