Skip to content

Commit

Permalink
scout/usage: add --docker flag to scout usage tool (#985)
Browse files Browse the repository at this point in the history
prints CPU and Memory usage for each running container in a docker deployment of sourcegraph
  • Loading branch information
jasonhawkharris committed May 25, 2023
1 parent 4effeda commit d9d8ca6
Showing 1 changed file with 68 additions and 9 deletions.
77 changes: 68 additions & 9 deletions internal/scout/usage/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,86 @@ package usage

import (
"context"
"encoding/json"
"fmt"

"github.com/charmbracelet/bubbles/table"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/sourcegraph/sourcegraph/lib/errors"
"github.com/sourcegraph/src-cli/internal/scout/style"
)

func Docker(ctx context.Context, client client.Client, opts ...Option) error {
cfg := &Config{
namespace: "default",
docker: true,
pod: "",
container: "",
spy: false,
k8sClient: nil,
dockerClient: &client,
metricsClient: nil,
namespace: "default",
docker: true,
pod: "",
container: "",
spy: false,
dockerClient: &client,
}

for _, opt := range opts {
opt(cfg)
}

fmt.Println("Command is routed, but not yet fixed.")
containers, err := cfg.dockerClient.ContainerList(ctx, types.ContainerListOptions{})
if err != nil {
return errors.Wrap(err, "could not get list of containers")
}

return renderDockerUsageTable(ctx, cfg, containers)
}

// renderDockerUsageTable renders a table displaying CPU and memory usage for Docker containers.
func renderDockerUsageTable(ctx context.Context, cfg *Config, containers []types.Container) error {
columns := []table.Column{
{Title: "Container", Width: 20},
{Title: "Cores", Width: 10},
{Title: "Usage", Width: 10},
{Title: "Memory", Width: 10},
{Title: "Usage", Width: 10},
}
rows := []table.Row{}

for _, container := range containers {
containerInfo, err := cfg.dockerClient.ContainerInspect(ctx, container.ID)
if err != nil {
return errors.Wrap(err, "failed to get container info")
}

stats, err := cfg.dockerClient.ContainerStats(ctx, container.ID, false)
if err != nil {
return errors.Wrap(err, "could not get container stats")
}
defer stats.Body.Close()

var usage types.StatsJSON
if err := json.NewDecoder(stats.Body).Decode(&usage); err != nil {
return errors.Wrap(err, "could not decode container stats")
}

row := makeDockerUsageRow(usage, containerInfo)
rows = append(rows, row)
}

style.ResourceTable(columns, rows)
return nil
}

// makeDockerUsageRow generates a table row displaying CPU and memory usage for a Docker container.
func makeDockerUsageRow(containerUsage types.StatsJSON, containerInfo types.ContainerJSON) table.Row {
cpuCores := float64(containerInfo.HostConfig.NanoCPUs)
memory := float64(containerInfo.HostConfig.Memory)
cpuUsage := float64(containerUsage.CPUStats.CPUUsage.TotalUsage)
memoryUsage := float64(containerUsage.MemoryStats.Usage)

return table.Row{
containerInfo.Name,
fmt.Sprintf("%.2f", cpuCores/1_000_000_000),
fmt.Sprintf("%.2f%%", getPercentage(cpuUsage, cpuCores)),
fmt.Sprintf("%.2fG", memory/1_000_000_000),
fmt.Sprintf("%.2f%%", getPercentage(memoryUsage, memory)),
}
}

0 comments on commit d9d8ca6

Please sign in to comment.