Skip to content

Commit 8c0666a

Browse files
committed
Added support for filesystem metrics on Docker
Added support for filesystem metrics on Docker Added support for filesystem metrics on Docker Added support for filesystem metrics on Docker Added support for filesystem metrics on Docker Added support for filesystem metrics on Docker Added support for filesystem metrics on Docker Added support for filesystem metrics on Docker Added support for filesystem metrics on Docker Added support for filesystem metrics on Docker Added support for filesystem metrics on Docker Added support for filesystem metrics on Docker
1 parent 7a9ceab commit 8c0666a

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
@@ -483,6 +483,17 @@ func getDiskStatsMap(diskStatsFile string) (map[string]DiskStats, error) {
483483
return nil, error
484484
}
485485
}
486+
487+
major64, err := strconv.ParseUint(words[0], 10, 64)
488+
if err != nil {
489+
return nil, err
490+
}
491+
492+
minor64, err := strconv.ParseUint(words[1], 10, 64)
493+
if err != nil {
494+
return nil, err
495+
}
496+
486497
diskStats := DiskStats{
487498
MajorNum: devInfo[0],
488499
MinorNum: devInfo[1],
@@ -497,6 +508,8 @@ func getDiskStatsMap(diskStatsFile string) (map[string]DiskStats, error) {
497508
IoInProgress: stats[8],
498509
IoTime: stats[9],
499510
WeightedIoTime: stats[10],
511+
Major: major64,
512+
Minor: minor64,
500513
}
501514
diskStatsMap[deviceName] = diskStats
502515
}

fs/fs_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func TestMountInfoFromDir(t *testing.T) {
4444
func TestGetDiskStatsMap(t *testing.T) {
4545
diskStatsMap, err := getDiskStatsMap("test_resources/diskstats")
4646
if err != nil {
47-
t.Errorf("Error calling getDiskStatMap %s", err)
47+
t.Errorf("Error calling getDiskStatsMap %s", err)
4848
}
4949
if len(diskStatsMap) != 30 {
5050
t.Errorf("diskStatsMap %+v not valid", diskStatsMap)
@@ -96,7 +96,7 @@ func TestGetDiskStatsMap(t *testing.T) {
9696
func TestGetDiskStatsMapMajorMinorNum(t *testing.T) {
9797
diskStatsMap, err := getDiskStatsMap("test_resources/diskstats")
9898
if err != nil {
99-
t.Errorf("Error calling getDiskStatMap %s", err)
99+
t.Errorf("Error calling getDiskStatsMap %s", err)
100100
}
101101
if len(diskStatsMap) != 30 {
102102
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)