Skip to content

Commit

Permalink
feat: Add container metrics to getAllContainers function
Browse files Browse the repository at this point in the history
  • Loading branch information
andrasbacsai committed May 7, 2024
1 parent 4830c42 commit c609e1a
Showing 1 changed file with 75 additions and 0 deletions.
75 changes: 75 additions & 0 deletions cmd/sentinel/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ package main
import (
"context"
"encoding/json"
"fmt"
"io"
"log"

"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
)
Expand All @@ -16,6 +19,20 @@ type Container struct {
State string `json:"state"`
Labels map[string]string `json:"labels"`
HealthStatus string `json:"health_status"`
Metrics ContainerMetrics `json:"metrics"`
}

type ContainerMetrics struct {
CPUUsagePercentage float64 `json:"cpu_usage_percentage"`
MemoryUsagePercentage float64 `json:"memory_usage_percentage"`
MemoryUsed uint64 `json:"memory_used"`
MemoryAvailable uint64 `json:"available_memory"`
NetworkUsage NetworkDevice `json:"network_usage_in"`
}
type NetworkDevice struct {
Name string `json:"name"`
RxBytes uint64 `json:"rx_bytes"`
TxBytes uint64 `json:"tx_bytes"`
}

func getAllContainers() (string, error) {
Expand All @@ -41,13 +58,53 @@ func getAllContainers() (string, error) {
if inspectData.State.Health != nil {
healthStatus = inspectData.State.Health.Status
}
// Get container stats
metrics := ContainerMetrics{
CPUUsagePercentage: 0,
MemoryUsagePercentage: 0,
MemoryUsed: 0,
MemoryAvailable: 0,
NetworkUsage: NetworkDevice{},
}
if container.State == "running" {
stats, err := apiClient.ContainerStatsOneShot(ctx, container.ID)
if err != nil {
fmt.Printf("Error getting container stats: %v\n", err)
continue
}
var v *types.StatsJSON
dec := json.NewDecoder(stats.Body)
if err := dec.Decode(&v); err != nil {
if err != io.EOF {
fmt.Printf("Error decoding container stats: %v\n", err)
}
}
network_devices := v.Networks
for _, device := range network_devices {
metrics.NetworkUsage = NetworkDevice{
Name: device.InstanceID,
RxBytes: device.RxBytes,
TxBytes: device.TxBytes,
}
}

metrics = ContainerMetrics{
CPUUsagePercentage: calculateCPUPercent(v),
MemoryUsagePercentage: calculateMmemoryPercent(v),
MemoryUsed: v.MemoryStats.Usage,
MemoryAvailable: v.MemoryStats.Limit,
NetworkUsage: metrics.NetworkUsage,
}
}

containersData = append(containersData, Container{
ID: container.ID,
Image: container.Image,
Labels: container.Labels,
Name: container.Names[0][1:],
State: container.State,
HealthStatus: healthStatus,
Metrics: metrics,
})
}
jsonData, err := json.MarshalIndent(containersData, "", " ")
Expand All @@ -57,3 +114,21 @@ func getAllContainers() (string, error) {
return string(jsonData), nil

}
func calculateCPUPercent(stat *types.StatsJSON) float64 {
cpuPercent := 0.0
cpuDelta := float64(stat.CPUStats.CPUUsage.TotalUsage) - float64(stat.PreCPUStats.CPUUsage.TotalUsage)
systemDelta := float64(stat.CPUStats.SystemUsage) - float64(stat.PreCPUStats.SystemUsage)
if systemDelta > 0.0 {
cpuPercent = (cpuDelta / systemDelta) * float64(len(stat.CPUStats.CPUUsage.PercpuUsage)) * 100.0
}
return cpuPercent
}

func calculateMmemoryPercent(stat *types.StatsJSON) float64 {
usageMemory := float64(stat.MemoryStats.Usage)
cachedMemory := float64(stat.MemoryStats.Stats["cache"])
availableMemory := float64(stat.MemoryStats.Limit)
usedMemory := usageMemory - cachedMemory
usedMemoryPercentage := (usedMemory / availableMemory) * 100
return usedMemoryPercentage
}

0 comments on commit c609e1a

Please sign in to comment.