Skip to content

Commit 1a019d7

Browse files
authored
Merge pull request #2768 from JohnnyG235711/docker-0filesystem-fix
Added support for filesystem metrics on Docker
2 parents a09fb87 + 8c0666a commit 1a019d7

File tree

5 files changed

+130
-2
lines changed

5 files changed

+130
-2
lines changed

container/docker/handler.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,14 @@ func (h *dockerContainerHandler) getFsStats(stats *info.ContainerStats) error {
398398
fsType string
399399
)
400400

401+
var fsInfo *info.FsInfo
402+
401403
// Docker does not impose any filesystem limits for containers. So use capacity as limit.
402404
for _, fs := range mi.Filesystems {
403405
if fs.Device == device {
404406
limit = fs.Capacity
405407
fsType = fs.Type
408+
fsInfo = &fs
406409
break
407410
}
408411
}
@@ -413,11 +416,45 @@ func (h *dockerContainerHandler) getFsStats(stats *info.ContainerStats) error {
413416
fsStat.Usage = usage.TotalUsageBytes
414417
fsStat.Inodes = usage.InodeUsage
415418

419+
if fsInfo != nil {
420+
fileSystems, err := h.fsInfo.GetGlobalFsInfo()
421+
422+
if err == nil {
423+
addDiskStats(fileSystems, fsInfo, &fsStat)
424+
} else {
425+
klog.Errorf("Unable to obtain diskstats for filesystem %s: %v", fsStat.Device, err)
426+
}
427+
}
428+
416429
stats.Filesystem = append(stats.Filesystem, fsStat)
417430

418431
return nil
419432
}
420433

434+
func addDiskStats(fileSystems []fs.Fs, fsInfo *info.FsInfo, fsStats *info.FsStats) {
435+
if fsInfo == nil {
436+
return
437+
}
438+
439+
for _, fileSys := range fileSystems {
440+
if fsInfo.DeviceMajor == fileSys.DiskStats.Major &&
441+
fsInfo.DeviceMinor == fileSys.DiskStats.Minor {
442+
fsStats.ReadsCompleted = fileSys.DiskStats.ReadsCompleted
443+
fsStats.ReadsMerged = fileSys.DiskStats.ReadsMerged
444+
fsStats.SectorsRead = fileSys.DiskStats.SectorsRead
445+
fsStats.ReadTime = fileSys.DiskStats.ReadTime
446+
fsStats.WritesCompleted = fileSys.DiskStats.WritesCompleted
447+
fsStats.WritesMerged = fileSys.DiskStats.WritesMerged
448+
fsStats.SectorsWritten = fileSys.DiskStats.SectorsWritten
449+
fsStats.WriteTime = fileSys.DiskStats.WriteTime
450+
fsStats.IoInProgress = fileSys.DiskStats.IoInProgress
451+
fsStats.IoTime = fileSys.DiskStats.IoTime
452+
fsStats.WeightedIoTime = fileSys.DiskStats.WeightedIoTime
453+
break
454+
}
455+
}
456+
}
457+
421458
// TODO(vmarmol): Get from libcontainer API instead of cgroup manager when we don't have to support older Dockers.
422459
func (h *dockerContainerHandler) GetStats() (*info.ContainerStats, error) {
423460
stats, err := h.libcontainerHandler.GetStats()

container/docker/handler_test.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ import (
2424

2525
"github.com/docker/docker/api/types/container"
2626
"github.com/stretchr/testify/assert"
27+
28+
"github.com/google/cadvisor/fs"
29+
info "github.com/google/cadvisor/info/v1"
2730
)
2831

2932
func TestStorageDirDetectionWithOldVersions(t *testing.T) {
@@ -144,3 +147,76 @@ func TestDockerEnvWhitelist(t *testing.T) {
144147
as.Equal(rawEnvsMatchWithEmptyWhitelist, emptyExpected)
145148

146149
}
150+
151+
func TestAddDiskStatsCheck(t *testing.T) {
152+
var readsCompleted, readsMerged, sectorsRead, readTime, writesCompleted, writesMerged, sectorsWritten,
153+
writeTime, ioInProgress, ioTime, weightedIoTime uint64 = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
154+
155+
fileSystem := fs.Fs{
156+
DiskStats: fs.DiskStats{
157+
ReadsCompleted: readsCompleted,
158+
ReadsMerged: readsMerged,
159+
SectorsRead: sectorsRead,
160+
ReadTime: readTime,
161+
WritesCompleted: writesCompleted,
162+
WritesMerged: writesMerged,
163+
SectorsWritten: sectorsWritten,
164+
WriteTime: writeTime,
165+
IoInProgress: ioInProgress,
166+
IoTime: ioTime,
167+
WeightedIoTime: weightedIoTime,
168+
},
169+
}
170+
171+
fileSystems := []fs.Fs{fileSystem}
172+
173+
var fsStats info.FsStats
174+
addDiskStats(fileSystems, nil, &fsStats)
175+
}
176+
177+
func TestAddDiskStats(t *testing.T) {
178+
// Arrange
179+
as := assert.New(t)
180+
var readsCompleted, readsMerged, sectorsRead, readTime, writesCompleted, writesMerged, sectorsWritten,
181+
writeTime, ioInProgress, ioTime, weightedIoTime uint64 = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
182+
var fsStats info.FsStats
183+
184+
fsInfo := info.FsInfo{
185+
DeviceMajor: 4,
186+
DeviceMinor: 64,
187+
}
188+
189+
fileSystem := fs.Fs{
190+
DiskStats: fs.DiskStats{
191+
ReadsCompleted: readsCompleted,
192+
ReadsMerged: readsMerged,
193+
SectorsRead: sectorsRead,
194+
ReadTime: readTime,
195+
WritesCompleted: writesCompleted,
196+
WritesMerged: writesMerged,
197+
SectorsWritten: sectorsWritten,
198+
WriteTime: writeTime,
199+
IoInProgress: ioInProgress,
200+
IoTime: ioTime,
201+
WeightedIoTime: weightedIoTime,
202+
},
203+
}
204+
205+
fileSystems := []fs.Fs{fileSystem}
206+
207+
// Act
208+
addDiskStats(fileSystems, &fsInfo, &fsStats)
209+
210+
// Assert
211+
as.Equal(readsCompleted, fileSystem.DiskStats.ReadsCompleted, "ReadsCompleted metric should be %d but was %d", readsCompleted, fileSystem.DiskStats.ReadsCompleted)
212+
as.Equal(readsMerged, fileSystem.DiskStats.ReadsMerged, "ReadsMerged metric should be %d but was %d", readsMerged, fileSystem.DiskStats.ReadsMerged)
213+
as.Equal(sectorsRead, fileSystem.DiskStats.SectorsRead, "SectorsRead metric should be %d but was %d", sectorsRead, fileSystem.DiskStats.SectorsRead)
214+
as.Equal(readTime, fileSystem.DiskStats.ReadTime, "ReadTime metric should be %d but was %d", readTime, fileSystem.DiskStats.ReadTime)
215+
as.Equal(writesCompleted, fileSystem.DiskStats.WritesCompleted, "WritesCompleted metric should be %d but was %d", writesCompleted, fileSystem.DiskStats.WritesCompleted)
216+
as.Equal(writesMerged, fileSystem.DiskStats.WritesMerged, "WritesMerged metric should be %d but was %d", writesMerged, fileSystem.DiskStats.WritesMerged)
217+
as.Equal(sectorsWritten, fileSystem.DiskStats.SectorsWritten, "SectorsWritten metric should be %d but was %d", sectorsWritten, fileSystem.DiskStats.SectorsWritten)
218+
as.Equal(writeTime, fileSystem.DiskStats.WriteTime, "WriteTime metric should be %d but was %d", writeTime, fileSystem.DiskStats.WriteTime)
219+
as.Equal(ioInProgress, fileSystem.DiskStats.IoInProgress, "IoInProgress metric should be %d but was %d", ioInProgress, fileSystem.DiskStats.IoInProgress)
220+
as.Equal(ioTime, fileSystem.DiskStats.IoTime, "IoTime metric should be %d but was %d", ioTime, fileSystem.DiskStats.IoTime)
221+
as.Equal(weightedIoTime, fileSystem.DiskStats.WeightedIoTime, "WeightedIoTime metric should be %d but was %d", weightedIoTime, fileSystem.DiskStats.WeightedIoTime)
222+
}

fs/fs.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,17 @@ func getDiskStatsMap(diskStatsFile string) (map[string]DiskStats, error) {
488488
return nil, err
489489
}
490490
}
491+
492+
major64, err := strconv.ParseUint(words[0], 10, 64)
493+
if err != nil {
494+
return nil, err
495+
}
496+
497+
minor64, err := strconv.ParseUint(words[1], 10, 64)
498+
if err != nil {
499+
return nil, err
500+
}
501+
491502
diskStats := DiskStats{
492503
MajorNum: devInfo[0],
493504
MinorNum: devInfo[1],
@@ -502,6 +513,8 @@ func getDiskStatsMap(diskStatsFile string) (map[string]DiskStats, error) {
502513
IoInProgress: stats[8],
503514
IoTime: stats[9],
504515
WeightedIoTime: stats[10],
516+
Major: major64,
517+
Minor: minor64,
505518
}
506519
diskStatsMap[deviceName] = diskStats
507520
}

fs/fs_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func TestMountInfoFromDir(t *testing.T) {
4343
func TestGetDiskStatsMap(t *testing.T) {
4444
diskStatsMap, err := getDiskStatsMap("test_resources/diskstats")
4545
if err != nil {
46-
t.Errorf("Error calling getDiskStatMap %s", err)
46+
t.Errorf("Error calling getDiskStatsMap %s", err)
4747
}
4848
if len(diskStatsMap) != 30 {
4949
t.Errorf("diskStatsMap %+v not valid", diskStatsMap)
@@ -95,7 +95,7 @@ func TestGetDiskStatsMap(t *testing.T) {
9595
func TestGetDiskStatsMapMajorMinorNum(t *testing.T) {
9696
diskStatsMap, err := getDiskStatsMap("test_resources/diskstats")
9797
if err != nil {
98-
t.Errorf("Error calling getDiskStatMap %s", err)
98+
t.Errorf("Error calling getDiskStatsMap %s", err)
9999
}
100100
if len(diskStatsMap) != 30 {
101101
t.Errorf("diskStatsMap %+v not valid", diskStatsMap)

fs/types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ type DiskStats struct {
7777
IoInProgress uint64
7878
IoTime uint64
7979
WeightedIoTime uint64
80+
Major uint64
81+
Minor uint64
8082
}
8183

8284
type UsageInfo struct {

0 commit comments

Comments
 (0)