[ARVADOS] updated: 8aeba61dc1cf17b680d6cd3e6bcc4c01f40ff5a3

git at public.curoverse.com git at public.curoverse.com
Tue Oct 14 15:05:21 EDT 2014


Summary of changes:
 services/crunchstat/crunchstat.go | 139 ++++++++++++++++++++++----------------
 1 file changed, 82 insertions(+), 57 deletions(-)

       via  8aeba61dc1cf17b680d6cd3e6bcc4c01f40ff5a3 (commit)
       via  5bce0483011b58a97dded8874491c7b266a850fc (commit)
       via  fd8ed1da05708932eb3e654e333053e1940dc29c (commit)
      from  ee45ddfb506f72a021f772af6477bfeab1204b3a (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 8aeba61dc1cf17b680d6cd3e6bcc4c01f40ff5a3
Author: Tom Clegg <tom at curoverse.com>
Date:   Tue Oct 14 15:00:28 2014 -0400

    3826: Add TODO comment on FindStat.

diff --git a/services/crunchstat/crunchstat.go b/services/crunchstat/crunchstat.go
index 9590bbb..0b3920c 100644
--- a/services/crunchstat/crunchstat.go
+++ b/services/crunchstat/crunchstat.go
@@ -67,6 +67,13 @@ func OpenAndReadAll(filename string, log_chan chan<- string) ([]byte, error) {
 var reportedStatFile map[string]bool
 var reportedNoStatFile map[string]bool
 
+// Find the cgroup stats file in /sys/fs corresponding to the target
+// cgroup.
+//
+// TODO: Instead of trying all options, choose a process in the
+// container, and read /proc/PID/cgroup to determine the appropriate
+// cgroup root for the given statgroup. (This will avoid falling back
+// to host-level stats during container setup and teardown.)
 func FindStat(stderr chan<- string, cgroup Cgroup, statgroup string, stat string) string {
 	if reportedStatFile == nil {
 		reportedStatFile = make(map[string]bool)

commit 5bce0483011b58a97dded8874491c7b266a850fc
Author: Tom Clegg <tom at curoverse.com>
Date:   Tue Oct 14 14:44:01 2014 -0400

    3826: Fix up block IO stats.

diff --git a/services/crunchstat/crunchstat.go b/services/crunchstat/crunchstat.go
index 80bf62d..9590bbb 100644
--- a/services/crunchstat/crunchstat.go
+++ b/services/crunchstat/crunchstat.go
@@ -2,6 +2,7 @@ package main
 
 import (
 	"bufio"
+	"bytes"
 	"flag"
 	"errors"
 	"fmt"
@@ -84,9 +85,9 @@ func FindStat(stderr chan<- string, cgroup Cgroup, statgroup string, stat string
 		path = fmt.Sprintf("%s/%s", cgroup.root, stat)
 	}
 	if _, err := os.Stat(path); err != nil {
-		if _, ok := reportedNoStatFile[path]; !ok {
+		if _, ok := reportedNoStatFile[stat]; !ok {
 			stderr <- fmt.Sprintf("crunchstat: did not find stats file (root %s, parent %s, cid %s, statgroup %s, stat %s)", cgroup.root, cgroup.parent, cgroup.cid, statgroup, stat)
-			reportedNoStatFile[path] = true
+			reportedNoStatFile[stat] = true
 		}
 		return ""
 	}
@@ -118,55 +119,69 @@ func GetContainerNetStats(stderr chan<- string, cgroup Cgroup) (io.Reader, error
 	return nil, errors.New("Could not read stats for any proc in container")
 }
 
-type Disk struct {
-	last_read  int64
-	next_read  int64
-	last_write int64
-	next_write int64
+type IoSample struct {
+	sampleTime time.Time
+	txBytes    int64
+	rxBytes    int64
 }
-var disk map[string]*Disk
 
-func DoBlkIoStats(stderr chan<- string, cgroup Cgroup) {
+func DoBlkIoStats(stderr chan<- string, cgroup Cgroup, lastSample map[string]IoSample) (map[string]IoSample) {
 	blkio_io_service_bytes := FindStat(stderr, cgroup, "blkio", "blkio.io_service_bytes")
 	if blkio_io_service_bytes == "" {
-		return
-	}
-
-	if disk == nil {
-		disk = make(map[string]*Disk)
+		return lastSample
 	}
 
 	c, err := os.Open(blkio_io_service_bytes)
 	if err != nil {
-		stderr <- fmt.Sprintf("open %s: %s", blkio_io_service_bytes, err)
-		return
+		stderr <- fmt.Sprintf("crunchstat: open %s: %s", blkio_io_service_bytes, err)
+		return lastSample
 	}
 	defer c.Close()
 	b := bufio.NewScanner(c)
-	var device, op string
-	var next int64
+	var sampleTime = time.Now()
+	newSamples := make(map[string]IoSample)
 	for b.Scan() {
-		if _, err := fmt.Sscanf(string(b.Text()), "%s %s %d", &device, &op, &next); err != nil {
+		var device, op string
+		var val int64
+		if _, err := fmt.Sscanf(string(b.Text()), "%s %s %d", &device, &op, &val); err != nil {
 			continue
 		}
-		if disk[device] == nil {
-			disk[device] = new(Disk)
+		var thisSample IoSample
+		var ok bool
+		if thisSample, ok = newSamples[device]; !ok {
+			thisSample = IoSample{sampleTime, -1, -1}
 		}
-		if op == "Read" {
-			disk[device].last_read = disk[device].next_read
-			disk[device].next_read = next
-			if disk[device].last_read > 0 && (disk[device].next_read != disk[device].last_read) {
-				stderr <- fmt.Sprintf("crunchstat: blkio.io_service_bytes %s read %v", device, disk[device].next_read-disk[device].last_read)
-			}
+		switch op {
+		case "Read":
+			thisSample.rxBytes = val
+		case "Write":
+			thisSample.txBytes = val
 		}
-		if op == "Write" {
-			disk[device].last_write = disk[device].next_write
-			disk[device].next_write = next
-			if disk[device].last_write > 0 && (disk[device].next_write != disk[device].last_write) {
-				stderr <- fmt.Sprintf("crunchstat: blkio.io_service_bytes %s write %v", device, disk[device].next_write-disk[device].last_write)
-			}
+		newSamples[device] = thisSample
+	}
+	if lastSample == nil {
+		lastSample = make(map[string]IoSample)
+	}
+	for dev, sample := range newSamples {
+		if sample.txBytes < 0 || sample.rxBytes < 0 {
+			continue
+		}
+		delta := ""
+		if prev, ok := lastSample[dev]; ok {
+			delta = fmt.Sprintf(" -- interval %.4f seconds %d write %d read",
+				sample.sampleTime.Sub(prev.sampleTime).Seconds(),
+				sample.txBytes - prev.txBytes,
+				sample.rxBytes - prev.rxBytes)
 		}
+		stderr <- fmt.Sprintf("crunchstat: blkio:%s %d write %d read%s", dev, sample.txBytes, sample.rxBytes, delta)
+		lastSample[dev] = sample
 	}
+	return lastSample
+}
+
+type MemSample struct {
+	sampleTime time.Time
+	memStat    map[string]int64
 }
 
 func DoMemoryStats(stderr chan<- string, cgroup Cgroup) {
@@ -176,36 +191,37 @@ func DoMemoryStats(stderr chan<- string, cgroup Cgroup) {
 	}
 	c, err := os.Open(memory_stat)
 	if err != nil {
-		stderr <- fmt.Sprintf("open %s: %s", memory_stat, err)
+		stderr <- fmt.Sprintf("crunchstat: open %s: %s", memory_stat, err)
 		return
 	}
 	defer c.Close()
 	b := bufio.NewScanner(c)
-	var stat string
-	var val int64
+	thisSample := MemSample{time.Now(), make(map[string]int64)}
+	wantStats := [...]string{"cache", "pgmajfault", "rss"}
 	for b.Scan() {
+		var stat string
+		var val int64
 		if _, err := fmt.Sscanf(string(b.Text()), "%s %d", &stat, &val); err != nil {
 			continue
 		}
-		if stat == "rss" {
-			stderr <- fmt.Sprintf("crunchstat: mem %d rss", val)
+		thisSample.memStat[stat] = val
+	}
+	var outstat bytes.Buffer
+	for _, key := range wantStats {
+		if val, ok := thisSample.memStat[key]; ok {
+			outstat.WriteString(fmt.Sprintf(" %d %s", val, key))
 		}
 	}
+	stderr <- fmt.Sprintf("crunchstat: mem%s", outstat.String())
 }
 
-type NetSample struct {
-	sampleTime time.Time
-	txBytes    int64
-	rxBytes    int64
-}
-
-func DoNetworkStats(stderr chan<- string, cgroup Cgroup, lastStat map[string]NetSample) (map[string]NetSample) {
+func DoNetworkStats(stderr chan<- string, cgroup Cgroup, lastSample map[string]IoSample) (map[string]IoSample) {
 	sampleTime := time.Now()
 	stats, err := GetContainerNetStats(stderr, cgroup)
-	if err != nil { return lastStat }
+	if err != nil { return lastSample }
 
-	if lastStat == nil {
-		lastStat = make(map[string]NetSample)
+	if lastSample == nil {
+		lastSample = make(map[string]IoSample)
 	}
 	scanner := bufio.NewScanner(stats)
 	Iface: for scanner.Scan() {
@@ -234,12 +250,12 @@ func DoNetworkStats(stderr chan<- string, cgroup Cgroup, lastStat map[string]Net
 			// Skip loopback interface and lines with wrong format
 			continue
 		}
-		nextSample := NetSample{}
+		nextSample := IoSample{}
 		nextSample.sampleTime = sampleTime
 		nextSample.txBytes = tx
 		nextSample.rxBytes = rx
 		var delta string
-		if lastSample, ok := lastStat[ifName]; ok {
+		if lastSample, ok := lastSample[ifName]; ok {
 			interval := nextSample.sampleTime.Sub(lastSample.sampleTime).Seconds()
 			delta = fmt.Sprintf(" -- interval %.4f seconds %d tx %d rx",
 				interval,
@@ -248,9 +264,9 @@ func DoNetworkStats(stderr chan<- string, cgroup Cgroup, lastStat map[string]Net
 		}
 		stderr <- fmt.Sprintf("crunchstat: net:%s %d tx %d rx%s",
 			ifName, tx, rx, delta)
-		lastStat[ifName] = nextSample
+		lastSample[ifName] = nextSample
 	}
-	return lastStat
+	return lastSample
 }
 
 func PollCgroupStats(cgroup Cgroup, stderr chan string, poll int64, stop_poll_chan <-chan bool) {
@@ -260,7 +276,8 @@ func PollCgroupStats(cgroup Cgroup, stderr chan string, poll int64, stop_poll_ch
 
 	user_hz := float64(C.sysconf(C._SC_CLK_TCK))
 
-	var lastNetStat map[string]NetSample = nil
+	var lastNetSample map[string]IoSample = nil
+	var lastDiskSample map[string]IoSample = nil
 
 	poll_chan := make(chan bool, 1)
 	go func() {
@@ -333,9 +350,9 @@ func PollCgroupStats(cgroup Cgroup, stderr chan string, poll int64, stop_poll_ch
 			last_sys = next_sys
 		}
 
-		DoBlkIoStats(stderr, cgroup)
 		DoMemoryStats(stderr, cgroup)
-		lastNetStat = DoNetworkStats(stderr, cgroup, lastNetStat)
+		lastDiskSample = DoBlkIoStats(stderr, cgroup, lastDiskSample)
+		lastNetSample = DoNetworkStats(stderr, cgroup, lastNetSample)
 	}
 }
 

commit fd8ed1da05708932eb3e654e333053e1940dc29c
Author: Tom Clegg <tom at curoverse.com>
Date:   Tue Oct 14 11:16:51 2014 -0400

    3826: Tweak memory stat log format to match cpu and net.

diff --git a/services/crunchstat/crunchstat.go b/services/crunchstat/crunchstat.go
index aee3162..80bf62d 100644
--- a/services/crunchstat/crunchstat.go
+++ b/services/crunchstat/crunchstat.go
@@ -184,10 +184,11 @@ func DoMemoryStats(stderr chan<- string, cgroup Cgroup) {
 	var stat string
 	var val int64
 	for b.Scan() {
-		if _, err := fmt.Sscanf(string(b.Text()), "%s %d", &stat, &val); err == nil {
-			if stat == "rss" {
-				stderr <- fmt.Sprintf("crunchstat: memory.stat rss %v", val)
-			}
+		if _, err := fmt.Sscanf(string(b.Text()), "%s %d", &stat, &val); err != nil {
+			continue
+		}
+		if stat == "rss" {
+			stderr <- fmt.Sprintf("crunchstat: mem %d rss", val)
 		}
 	}
 }

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list