Skip to content
Open
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
00bf8a8
Added IO data read/written to struct definition
Aug 3, 2020
0114836
Elaborated doc of ResourceUsageFromFinishedCmd
Aug 3, 2020
5e7268d
Data collected in ResourceUsageForPID
Aug 3, 2020
f6825c3
Added ClientIOReadCount and ClientIOWriteCount
Aug 3, 2020
18d6410
Delete IO Count
Aug 4, 2020
e70b347
Add aggregated fields to resource msg proto
Aug 4, 2020
1da76b7
Changed unit from bytes to mib
Aug 4, 2020
7fa2f9e
Added fields to unix struct
Aug 4, 2020
85908a5
Changed resource proto & compiled proto
Aug 4, 2020
1d2c64a
Added new fields to resource proto & compiled proto
Aug 4, 2020
8cea970
Changed max_io_read_mib and max_io_write_mib to int64
Aug 4, 2020
4f02c9e
Added code to initialize ClientIORead where needed
Aug 4, 2020
56b2493
Fixed variables & ammended comment
Aug 4, 2020
b6f2c8f
Merge branch 'master' of https://github.com/google/fleetspeak into ad…
Aug 5, 2020
bc2b658
Modified all relevant SQL statements
Aug 5, 2020
9870bba
Make sure aggregateIOResourceUsage is called
Aug 5, 2020
3a4d7a4
Added full support for ClientIOWrite
Aug 5, 2020
d046a3f
Added space in SQL INSERT statement
Aug 5, 2020
0298851
Scan SQL rows with IO data
Aug 5, 2020
813cec0
Separate memory from IO usage
Aug 5, 2020
285cb99
Merge branch 'master' of https://github.com/google/fleetspeak into ad…
Aug 5, 2020
1a4299a
Added more SQL statements to support IORead/write
Aug 6, 2020
5d798f4
Added gopsutil/process and calculate IO with it in unix
Aug 6, 2020
d1005d3
Fixed SQL query for SQLite
Aug 6, 2020
ad0e1cf
Merge branch 'master' of https://github.com/google/fleetspeak into ad…
Aug 6, 2020
ea8a4cc
tests and logs
Aug 7, 2020
7fb2f84
Merge branch 'master' of https://github.com/google/fleetspeak into ad…
Aug 10, 2020
5e179be
Changed format of proto message
Aug 12, 2020
a0534eb
Recompiled relevant proto file
Aug 12, 2020
52c1aae
Removed logs
Aug 12, 2020
8e39438
Changed relevant code to fit new proto fields
Aug 12, 2020
f22524b
Merge with main branch
Sep 23, 2020
ecd7483
Merge leftover generated proto from main branch
Sep 23, 2020
416b7bf
Recompiled protos with new fields
Sep 23, 2020
8439bac
Fixed SQL syntax
Sep 23, 2020
abe9c5f
Added tests for new RUD fields
Sep 23, 2020
86b6124
Changed variable names
Sep 23, 2020
a3f3629
Added tests for IOReadBytes and IOWriteBytes
Sep 23, 2020
784f31c
Changed new aggregated RUD fields to KiB
Sep 23, 2020
7380f3d
Variable names changes
Sep 23, 2020
a569f61
Changed proto field types from int32 to int64
Sep 23, 2020
bbb716a
Round up to nearest integer and use 'int64'
Sep 23, 2020
c946d31
Trigger Travis CI
Sep 23, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ type ResourceUsage struct {

// Resident set size for a process, in bytes.
ResidentMemory int64

// Client IO data read so far, in bytes.
IORead int64

// Client IO data written so far, in bytes.
IOWrite int64
}

// ResourceUsageFetcher obtains resource-usage data for a process from the OS.
Expand All @@ -48,7 +54,8 @@ type ResourceUsageFetcher struct{}
// information from exec.Cmd.ProcessState. NOTE that this is only possible
// after the process has finished and has been waited for, and will most
// probably panic otherwise.
// This function doesn't fill in ResourceUsage.ResidentMemory.
// This function doesn't fill in ResourceUsage.ResidentMemory, ResourceUsage.IORead
// and ResourceUsage.IOWrite.
func (f ResourceUsageFetcher) ResourceUsageFromFinishedCmd(cmd *exec.Cmd) *ResourceUsage {
return &ResourceUsage{
Timestamp: time.Now(),
Expand Down Expand Up @@ -78,11 +85,17 @@ func (f ResourceUsageFetcher) ResourceUsageForPID(pid int) (*ResourceUsage, erro
return nil, err
}

ioCounters, err := process.IOCounters()
if err != nil {
return nil, err
}
return &ResourceUsage{
Timestamp: timestamp,
UserCPUMillis: times.User * 1e3,
SystemCPUMillis: times.System * 1e3,
ResidentMemory: int64(memoryInfo.RSS),
IORead: int64(ioCounters.ReadBytes),
IOWrite: int64(ioCounters.WriteBytes),
}, nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (
"strconv"
"strings"
"time"

"github.com/shirou/gopsutil/process"
)

// TODO: Support monitoring on other platforms.
Expand All @@ -42,6 +44,12 @@ type ResourceUsage struct {

// Resident set size for a process.
ResidentMemory int64

// Client IO data read so far, in bytes.
IORead int64

// Client IO data written so far, in bytes.
IOWrite int64
}

// ResourceUsageFetcher obtains resource-usage data for a process from the OS.
Expand Down Expand Up @@ -125,11 +133,22 @@ func (f ResourceUsageFetcher) ResourceUsageForPID(pid int) (*ResourceUsage, erro
return nil, fmt.Errorf("error while parsing resident from %s: %v", statmFilename, err)
}

process, err := process.NewProcess(int32(pid))
if err != nil {
return nil, err
}

ioCounters, err := process.IOCounters()
if err != nil {
return nil, err
}
return &ResourceUsage{
Timestamp: timestamp,
UserCPUMillis: float64((utime + cutime) * 10), // Assume rate of 100 ticks/second
SystemCPUMillis: float64((stime + cstime) * 10), // Assume rate of 100 ticks/second
ResidentMemory: resident * pageSize,
IORead: int64(ioCounters.ReadBytes),
IOWrite: int64(ioCounters.WriteBytes),
}, nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ func AggregateResourceUsage(prevRU *ResourceUsage, currRU *ResourceUsage, numRUC
}
aggRU.MeanResidentMemory = float64(currRU.ResidentMemory) / float64(numRUCalls)
aggRU.MaxResidentMemory = currRU.ResidentMemory
aggRU.MeanIoRead = float64(currRU.IORead) / float64(numRUCalls)
aggRU.MaxIoRead = currRU.IORead
aggRU.MeanIoWrite = float64(currRU.IOWrite) / float64(numRUCalls)
aggRU.MaxIoWrite = currRU.IOWrite
return nil
}

Expand All @@ -80,6 +84,10 @@ func AggregateResourceUsage(prevRU *ResourceUsage, currRU *ResourceUsage, numRUC
return nil
}

if err := aggregateIOResourceUsage(currRU, numRUCalls, aggRU); err != nil {
return err
}

return aggregateMemoryResourceUsage(currRU, numRUCalls, aggRU)
}

Expand Down Expand Up @@ -119,6 +127,18 @@ func aggregateMemoryResourceUsage(currRU *ResourceUsage, numRUCalls int, aggRU *
return nil
}

func aggregateIOResourceUsage(currRU *ResourceUsage, numRUCalls int, aggRU *mpb.AggregatedResourceUsage) error {
aggRU.MeanIoRead += float64(currRU.IORead) / float64(numRUCalls)
if currRU.IORead > aggRU.MaxIoRead {
aggRU.MaxIoRead = currRU.IORead
}
aggRU.MeanIoWrite += float64(currRU.IOWrite) / float64(numRUCalls)
if currRU.IOWrite > aggRU.MaxIoWrite {
aggRU.MaxIoWrite = currRU.IOWrite
}
return nil
}

// AggregateResourceUsageForFinishedCmd computes resource-usage for a finished process, given
// resource-usage before and after the process ran.
func AggregateResourceUsageForFinishedCmd(initialRU, finalRU *ResourceUsage) (*mpb.AggregatedResourceUsage, error) {
Expand All @@ -132,13 +152,21 @@ func AggregateResourceUsageForFinishedCmd(initialRU, finalRU *ResourceUsage) (*m
return nil, err
}

// If this field is untouched, we have not aggregated memory resource usage
// If those field are untouched, we have not aggregated memory and IO resources usage
// for this process yet. We fill it in with what we have.
// TODO
if aggRU.MaxResidentMemory == 0 {
aggRU.MeanResidentMemory = float64(initialRU.ResidentMemory)
aggRU.MaxResidentMemory = initialRU.ResidentMemory
}
if aggRU.MaxIoRead == 0 {
aggRU.MeanIoRead = float64(initialRU.IORead)
aggRU.MaxIoRead = initialRU.IORead
}
if aggRU.MaxIoWrite == 0 {
aggRU.MeanIoWrite = float64(initialRU.IOWrite)
aggRU.MaxIoWrite = initialRU.IOWrite
}

return &aggRU, nil
}
Expand Down
140 changes: 90 additions & 50 deletions fleetspeak/src/common/proto/fleetspeak_monitoring/resource.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ message AggregatedResourceUsage {
double max_system_cpu_rate = 4;
double mean_resident_memory = 5;
int64 max_resident_memory = 6;
double mean_io_read = 7;
int64 max_io_read = 8;
double mean_io_write = 9;
int64 max_io_write = 10;
}

// A fleetspeak.Message with message type "ResourceUsage" is sent regularly by
Expand Down
10 changes: 10 additions & 0 deletions fleetspeak/src/server/dbtesting/clientstore_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,8 @@ func fetchResourceUsageRecordsTest(t *testing.T, ds db.Store) {
}

meanRAM, maxRAM := 190, 200
meanIoReadData, maxIoReadData := 300, 310
meanIoWriteData, maxIoWriteData := 400, 410
rud := mpb.ResourceUsageData{
Scope: "test-scope",
Pid: 1234,
Expand All @@ -373,6 +375,10 @@ func fetchResourceUsageRecordsTest(t *testing.T, ds db.Store) {
MaxSystemCpuRate: 80.0,
MeanResidentMemory: float64(meanRAM) * 1024 * 1024,
MaxResidentMemory: int64(maxRAM) * 1024 * 1024,
MeanIoRead: float64(meanIoReadData) * 1024 * 1024,
MaxIoRead: int64(maxIoReadData) * 1024 * 1024,
MeanIoWrite: float64(meanIoWriteData) * 1024 * 1024,
MaxIoWrite: int64(maxIoWriteData) * 1024 * 1024,
},
}

Expand Down Expand Up @@ -414,6 +420,10 @@ func fetchResourceUsageRecordsTest(t *testing.T, ds db.Store) {
MaxSystemCpuRate: 80.0,
MeanResidentMemoryMib: int32(meanRAM),
MaxResidentMemoryMib: int32(maxRAM),
MeanIoReadMib: int32(meanIoReadData),
MaxIoReadMib: int32(maxIoReadData),
MeanIoWriteMib: int32(meanIoWriteData),
MaxIoWriteMib: int32(maxIoWriteData),
}

if got, want := record, expected; !proto.Equal(got, want) {
Expand Down
Loading