Skip to content

Instantly share code, notes, and snippets.

@danhigham
Last active December 13, 2018 00:27
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danhigham/b329da925ac192ce4dc0a64066d6f0ac to your computer and use it in GitHub Desktop.
Save danhigham/b329da925ac192ce4dc0a64066d6f0ac to your computer and use it in GitHub Desktop.
Hall of shame, cf memory consumption
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strings"
"syscall"
cfclient "github.com/cloudfoundry-community/go-cfclient"
"github.com/olekukonko/tablewriter"
"github.com/remeh/sizedwaitgroup"
"golang.org/x/crypto/ssh/terminal"
pb "gopkg.in/cheggaaa/pb.v1"
)
type appStat struct {
Name string
GUID string
Space string
Instances int
MemoryAlloc int
AvgMemoryUse int
Ratio float64
}
func (s *appStat) toValueList() []string {
return []string{s.Name, s.Space, fmt.Sprintf("%d", s.MemoryAlloc), fmt.Sprintf("%d", s.AvgMemoryUse), fmt.Sprintf("%f", s.Ratio)}
}
type byRatio []appStat
func (a byRatio) Len() int { return len(a) }
func (a byRatio) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byRatio) Less(i, j int) bool { return a[j].Ratio < a[i].Ratio }
func main() {
argsWithoutProg := os.Args[1:]
var appStats []appStat
addr := argsWithoutProg[0]
fmt.Print("Username: ")
reader := bufio.NewReader(os.Stdin)
username, _ := reader.ReadString('\n')
fmt.Println("Password:")
bytePassword, _ := terminal.ReadPassword(int(syscall.Stdin))
password := string(bytePassword)
c := &cfclient.Config{
ApiAddress: addr,
Username: strings.TrimSpace(username),
Password: password,
}
client, err := cfclient.NewClient(c)
if err != nil {
panic(err)
}
fmt.Println("Getting app list")
apps, err := client.ListApps()
fmt.Println("Getting app stats")
bar := pb.StartNew(len(apps))
wg := sizedwaitgroup.New(20)
for _, app := range apps {
wg.Add()
go func(cfApp cfclient.App, pb *pb.ProgressBar) {
defer wg.Done()
stats, err := client.GetAppStats(cfApp.Guid)
pb.Increment()
if err != nil {
return
}
if stats["0"].State != "RUNNING" {
return
}
memAlloc := stats["0"].Stats.MemQuota
var totalUsage int
for _, stat := range stats {
totalUsage += stat.Stats.Usage.Mem
}
stat := appStat{
Name: cfApp.Name,
GUID: cfApp.Guid,
Instances: cfApp.Instances,
MemoryAlloc: memAlloc,
Space: cfApp.SpaceGuid,
AvgMemoryUse: totalUsage / len(stats),
Ratio: float64(memAlloc) / float64(totalUsage/len(stats)),
}
appStats = append(appStats, stat)
}(app, bar)
}
wg.Wait()
bar.FinishPrint("Done!")
sort.Sort(byRatio(appStats))
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Name", "Space", "Alloc", "AvgUse", "Ratio"})
for _, v := range appStats {
table.Append(v.toValueList())
}
table.Render()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment