Nikolay Sivko 4 лет назад
Родитель
Сommit
be4bf64937

+ 2 - 0
cgroup/fixtures/cgroup/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pod8712f785_1a3e_41ec_a00b_e2dcc77431cb.slice/docker-73051af271105c07e1f493b34856a77e665e3b0b4fc72f76c807dfbffeb881bd.scope/io.stat

@@ -0,0 +1,2 @@
+252:0 rbytes=11 wbytes=630538240 rios=22 wios=57111 dbytes=0 dios=0
+253:0 rbytes=33 wbytes=630538241 rios=44 wios=57056 dbytes=0 dios=0

+ 45 - 3
cgroup/blkio.go → cgroup/io.go

@@ -8,14 +8,21 @@ import (
 	"strings"
 )
 
-type BlkioStat struct {
+type IOStat struct {
 	ReadOps      uint64
 	WriteOps     uint64
 	ReadBytes    uint64
 	WrittenBytes uint64
 }
 
-func (cg *Cgroup) BlkioStat() (map[string]BlkioStat, error) {
+func (cg *Cgroup) IOStat() (map[string]IOStat, error) {
+	if cg.Version == V1 {
+		return cg.ioStatV1()
+	}
+	return cg.ioStatV2()
+}
+
+func (cg *Cgroup) ioStatV1() (map[string]IOStat, error) {
 	ops, err := readBlkioStatFile(path.Join(cgRoot, "blkio", cg.subsystems["blkio"], "blkio.throttle.io_serviced"))
 	if err != nil {
 		return nil, err
@@ -24,7 +31,7 @@ func (cg *Cgroup) BlkioStat() (map[string]BlkioStat, error) {
 	if err != nil {
 		return nil, err
 	}
-	res := map[string]BlkioStat{}
+	res := map[string]IOStat{}
 	for _, v := range ops {
 		stat := res[v.majorMinor]
 		switch v.name {
@@ -48,6 +55,41 @@ func (cg *Cgroup) BlkioStat() (map[string]BlkioStat, error) {
 	return res, nil
 }
 
+func (cg *Cgroup) ioStatV2() (map[string]IOStat, error) {
+	payload, err := ioutil.ReadFile(path.Join(cgRoot, cg.subsystems[""], "io.stat"))
+	if err != nil {
+		return nil, err
+	}
+	res := map[string]IOStat{}
+	for _, line := range strings.Split(string(payload), "\n") {
+		parts := strings.Fields(line)
+		if len(parts) < 5 {
+			continue
+		}
+		s := IOStat{}
+		for _, value := range parts[1:] {
+			if kv := strings.SplitN(value, "=", 2); len(kv) == 2 {
+				v, err := strconv.ParseUint(kv[1], 10, 64)
+				if err != nil {
+					continue
+				}
+				switch kv[0] {
+				case "rbytes":
+					s.ReadBytes = v
+				case "wbytes":
+					s.WrittenBytes = v
+				case "rios":
+					s.ReadOps = v
+				case "wios":
+					s.WriteOps = v
+				}
+			}
+		}
+		res[parts[0]] = s
+	}
+	return res, nil
+}
+
 type blkioVariable struct {
 	majorMinor string
 	name       string

+ 14 - 3
cgroup/blkio_test.go → cgroup/io_test.go

@@ -6,14 +6,14 @@ import (
 	"testing"
 )
 
-func TestCgroup_BlkioStat(t *testing.T) {
+func TestCgroup_IOStat(t *testing.T) {
 	cgRoot = "fixtures/cgroup"
 
 	cg, _ := NewFromProcessCgroupFile(path.Join("fixtures/proc/200/cgroup"))
-	stat, err := cg.BlkioStat()
+	stat, err := cg.IOStat()
 	assert.Nil(t, err)
 	assert.Equal(t,
-		map[string]BlkioStat{
+		map[string]IOStat{
 			"8:0":  {ReadOps: 0, WriteOps: 281, ReadBytes: 0, WrittenBytes: 4603904},
 			"8:16": {ReadOps: 0, WriteOps: 39, ReadBytes: 0, WrittenBytes: 655360},
 			"8:32": {ReadOps: 23043666, WriteOps: 28906992, ReadBytes: 998632854016, WrittenBytes: 884175858688},
@@ -21,4 +21,15 @@ func TestCgroup_BlkioStat(t *testing.T) {
 			"9:1":  {ReadOps: 633949, WriteOps: 4, ReadBytes: 10238894080, WrittenBytes: 49152},
 		},
 		stat)
+
+	cg, _ = NewFromProcessCgroupFile(path.Join("fixtures/proc/400/cgroup"))
+	stat, err = cg.IOStat()
+	assert.Nil(t, err)
+	assert.Equal(t,
+		map[string]IOStat{
+			"252:0": {ReadOps: 22, WriteOps: 57111, ReadBytes: 11, WrittenBytes: 630538240},
+			"253:0": {ReadOps: 44, WriteOps: 57056, ReadBytes: 33, WrittenBytes: 630538241},
+		},
+		stat)
+
 }

+ 1 - 1
containers/container.go

@@ -187,7 +187,7 @@ func (c *Container) Collect(ch chan<- prometheus.Metric) {
 	}
 
 	if disks, err := node.GetDisks(); err == nil {
-		ioStat, _ := c.cgroup.BlkioStat()
+		ioStat, _ := c.cgroup.IOStat()
 		for majorMinor, mounts := range c.getMounts() {
 			dev := disks.GetParentBlockDevice(majorMinor)
 			if dev == nil {