diff --git a/clients/docker/client.go b/clients/docker/client.go index 373d8078..54df12e0 100644 --- a/clients/docker/client.go +++ b/clients/docker/client.go @@ -901,6 +901,8 @@ func (d *dockerClient) ContainerStats(ctx context.Context, id string) (*Containe CPUUsage: CPUUsage{ TotalUsage: containerResources.CPUStats.CPUUsage.TotalUsage, }, + SystemUsage: containerResources.CPUStats.SystemUsage, + OnlineCPUs: containerResources.CPUStats.OnlineCPUs, }, MemoryStats: MemoryStats{ Usage: containerResources.MemoryStats.Usage, diff --git a/clients/docker/types.go b/clients/docker/types.go index 97177849..98830e9c 100644 --- a/clients/docker/types.go +++ b/clients/docker/types.go @@ -7,7 +7,9 @@ type ContainerResources struct { } type CPUStats struct { - CPUUsage CPUUsage `json:"cpu_usage"` + CPUUsage CPUUsage `json:"cpu_usage"` + SystemUsage uint64 `json:"system_cpu_usage"` + OnlineCPUs uint32 `json:"online_cpus"` } type CPUUsage struct { diff --git a/services/components/containers/bot_client.go b/services/components/containers/bot_client.go index 4a214984..c7c7de01 100644 --- a/services/components/containers/bot_client.go +++ b/services/components/containers/bot_client.go @@ -130,6 +130,8 @@ func (bc *botClient) pollDockerResources(containerID string, agentConfig config. ticker := initTicker(DockerResourcesPollingInterval) defer ticker.Stop() + var previousResources docker.ContainerResources + for t := range ticker.C { logrus.WithField("containerID", containerID).Debug("polling docker resources") // request docker stats @@ -159,9 +161,11 @@ func (bc *botClient) pollDockerResources(containerID string, agentConfig config. WithField("resources", resources). Debug("sending docker resources metrics") + cpuPercent := calculateCPUPercentUnix(&previousResources, resources) + metrics.SendAgentMetrics(bc.msgClient, []*protocol.AgentMetric{ metrics.CreateAgentResourcesMetric( - agentConfig, t, domain.MetricDockerResourcesCPU, float64(resources.CPUStats.CPUUsage.TotalUsage)), + agentConfig, t, domain.MetricDockerResourcesCPU, cpuPercent), metrics.CreateAgentResourcesMetric( agentConfig, t, domain.MetricDockerResourcesMemory, float64(resources.MemoryStats.Usage)), metrics.CreateAgentResourcesMetric( @@ -169,7 +173,24 @@ func (bc *botClient) pollDockerResources(containerID string, agentConfig config. metrics.CreateAgentResourcesMetric( agentConfig, t, domain.MetricDockerResourcesNetworkReceive, float64(bytesRecv)), }) + + previousResources = *resources + } +} + +func calculateCPUPercentUnix(previousResources, resources *docker.ContainerResources) float64 { + var ( + cpuPercent = 0.0 + // calculate the change for the cpu usage of the container in between readings + cpuDelta = float64(resources.CPUStats.CPUUsage.TotalUsage) - float64(previousResources.CPUStats.CPUUsage.TotalUsage) + // calculate the change for the entire system between readings + systemDelta = float64(resources.CPUStats.SystemUsage) - float64(previousResources.CPUStats.SystemUsage) + ) + + if systemDelta > 0.0 && cpuDelta > 0.0 { + cpuPercent = (cpuDelta / systemDelta) * float64(resources.CPUStats.OnlineCPUs) * 100.0 } + return cpuPercent } func (bc *botClient) attachServiceContainers(ctx context.Context, botNetworkID string) error { diff --git a/services/components/containers/bot_client_test.go b/services/components/containers/bot_client_test.go index 83425631..ccb543ae 100644 --- a/services/components/containers/bot_client_test.go +++ b/services/components/containers/bot_client_test.go @@ -129,7 +129,7 @@ func (s *BotClientTestSuite) TestLaunchBot_Exists() { // CPU metric assert.Equal(s.T(), botConfig.ID, metrics.Metrics[0].AgentId) assert.Equal(s.T(), domain.MetricDockerResourcesCPU, metrics.Metrics[0].Name) - assert.Equal(s.T(), float64(33), metrics.Metrics[0].Value) + assert.Equal(s.T(), float64(0), metrics.Metrics[0].Value) // Memory metric assert.Equal(s.T(), botConfig.ID, metrics.Metrics[1].AgentId)