I took some time to beat on this a little bit. Tested this way:
./crunchstat -cgroup-root=/sys/fs/cgroup -poll=1 bash -c "cat ~/ff4a131626aa0883c715d3c5abf394a6 1>&2" 2> out
(ff4a131626aa0883c715d3c5abf394a6 is 28 MiB of manifest on a single line I had lying around from something else..)
Works great!
Also: Get rid of the "log channel" and use Go's own logging library instead: it guarantees goroutine safety and allows you to specify a prefix ("crunchstat: "), which were the two things our logChan code was doing.
You're creating separate "statLog" and "childLog" Loggers that both write to Stderr, and (from looking at the actual log.go code) each one has its own mutex, which means writes to "statLog" are serialized, but this has no effect on writes to "childLog". In practice this doesn't seem to be an issue, but I think we're just getting lucky that Write()
on the underlying stderr stream is effectively atomic for small writes.
Just one thing puzzled me in the tests:
t.Fatalf("sent %d bytes, got %d different bytes", len(sentBytes)+1, len(receivedBytes))
Why does it report len(sentBytes)+1
when the test is bytes.Compare(receivedBytes, sentBytes)
?