-
Notifications
You must be signed in to change notification settings - Fork 6
/
app_renderer.go
130 lines (107 loc) · 3.78 KB
/
app_renderer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package output
import (
"fmt"
"code.cloudfoundry.org/cli/cf/terminal"
"code.cloudfoundry.org/cpu-entitlement-plugin/reporter"
"code.cloudfoundry.org/lager"
"github.com/fatih/color"
)
const DateFmt = "2006-01-02 15:04:05"
const noColor color.Attribute = -1
type AppRenderer struct {
display AppDisplay
}
//go:generate counterfeiter . AppDisplay
type AppDisplay interface {
ShowMessage(message string, values ...interface{})
ShowTable(logger lager.Logger, headers []string, rows [][]string) error
}
func NewAppRenderer(display AppDisplay) AppRenderer {
return AppRenderer{display: display}
}
func (r AppRenderer) ShowApplicationReport(logger lager.Logger, appReport reporter.ApplicationReport) error {
logger = logger.Session("show-application-report")
logger.Info("start")
defer logger.Info("end")
r.showAppInfoHeader(appReport)
if len(appReport.InstanceReports) == 0 {
r.display.ShowMessage("There are no running instances of this application.")
return nil
}
if err := r.showTable(logger, appReport); err != nil {
return err
}
r.showMessage(appReport)
r.showPastSpikes(appReport)
return nil
}
func (r AppRenderer) showTable(logger lager.Logger, appReport reporter.ApplicationReport) error {
var rows [][]string
for _, report := range appReport.InstanceReports {
rowColor := noColor
instanceID := fmt.Sprintf("#%d", report.InstanceID)
avgEntitlementRatio := fmt.Sprintf("%.2f%%", report.CumulativeUsage.Value*100)
if report.CumulativeUsage.Value > 1 {
rowColor = color.FgRed
} else if report.CumulativeUsage.Value > 0.95 {
rowColor = color.FgYellow
}
currEntitlementRatio := fmt.Sprintf("%.2f%%", report.CurrentUsage.Value*100)
rows = append(rows, colorizeRow([]string{instanceID, avgEntitlementRatio, currEntitlementRatio}, rowColor))
}
err := r.display.ShowTable(logger, []string{"", terminal.Colorize("avg usage", color.Bold), terminal.Colorize("curr usage", color.Bold)}, rows)
if err != nil {
return err
}
return nil
}
func (r AppRenderer) showMessage(appReport reporter.ApplicationReport) {
var status string
var level string
for _, report := range appReport.InstanceReports {
if report.CumulativeUsage.Value > 1 {
status = "over"
level = "WARNING"
} else if report.CumulativeUsage.Value > 0.95 {
if status == "" {
status = "near"
level = "TIP"
}
}
}
if status != "" {
r.display.ShowMessage(terminal.Colorize(fmt.Sprintf("%s: Some instances are %s their CPU entitlement. Consider scaling your memory or instances.", level, status), color.FgCyan))
}
}
func (r AppRenderer) showPastSpikes(appReport reporter.ApplicationReport) {
var reportsWithSpikes []reporter.InstanceReport
for _, report := range appReport.InstanceReports {
if (report.LastSpike != reporter.LastSpike{}) && (report.CumulativeUsage.Value <= 1) {
reportsWithSpikes = append(reportsWithSpikes, report)
}
}
for _, reportWithSpike := range reportsWithSpikes {
r.display.ShowMessage(terminal.Colorize(
fmt.Sprintf("WARNING: Instance #%d was over entitlement from %s to %s", reportWithSpike.InstanceID, reportWithSpike.LastSpike.From.Format(DateFmt), reportWithSpike.LastSpike.To.Format(DateFmt)),
color.FgYellow,
))
}
}
func (r AppRenderer) showAppInfoHeader(appReport reporter.ApplicationReport) {
r.display.ShowMessage("Showing CPU usage against entitlement for app %s in org %s / space %s as %s ...\n",
terminal.EntityNameColor(appReport.ApplicationName),
terminal.EntityNameColor(appReport.Org),
terminal.EntityNameColor(appReport.Space),
terminal.EntityNameColor(appReport.Username),
)
}
func colorizeRow(row []string, rowColor color.Attribute) []string {
if rowColor == noColor {
return row
}
colorizedRow := []string{}
for _, col := range row {
colorizedRow = append(colorizedRow, terminal.Colorize(col, rowColor))
}
return colorizedRow
}