From 2403961d8680a2b9ce4f7ca9dc47c0c2d5bf16a4 Mon Sep 17 00:00:00 2001 From: Chris D Brown Date: Tue, 4 Jun 2019 21:47:47 +0100 Subject: [PATCH] feat(newrelic): Display deploy information from multiple apps --- go.sum | 2 + maker/widget_maker.go | 2 +- modules/newrelic/display.go | 74 +++++++++++++++++++++++++++++ modules/newrelic/keyboard.go | 9 ++++ modules/newrelic/settings.go | 12 ++--- modules/newrelic/widget.go | 90 +++++++++++++----------------------- 6 files changed, 125 insertions(+), 64 deletions(-) create mode 100644 modules/newrelic/display.go create mode 100644 modules/newrelic/keyboard.go diff --git a/go.sum b/go.sum index 2f7befe27..7a7be4aad 100644 --- a/go.sum +++ b/go.sum @@ -135,9 +135,11 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/lucasb-eyer/go-colorful v1.0.2 h1:mCMFu6PgSozg9tDNMMK3g18oJBX7oYGrC09mS6CXfO4= github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= diff --git a/maker/widget_maker.go b/maker/widget_maker.go index 0a12a059d..2b7acef04 100644 --- a/maker/widget_maker.go +++ b/maker/widget_maker.go @@ -137,7 +137,7 @@ func MakeWidget( widget = nbascore.NewWidget(app, pages, settings) case "newrelic": settings := newrelic.NewSettingsFromYAML(widgetName, moduleConfig, globalConfig) - widget = newrelic.NewWidget(app, settings) + widget = newrelic.NewWidget(app, pages, settings) case "opsgenie": settings := opsgenie.NewSettingsFromYAML(widgetName, moduleConfig, globalConfig) widget = opsgenie.NewWidget(app, settings) diff --git a/modules/newrelic/display.go b/modules/newrelic/display.go new file mode 100644 index 000000000..db7113fc0 --- /dev/null +++ b/modules/newrelic/display.go @@ -0,0 +1,74 @@ +package newrelic + +import ( + "fmt" + + "github.com/wtfutil/wtf/wtf" + nr "github.com/yfronto/newrelic" +) + +func (widget *Widget) display() { + client := widget.currentData() + if client == nil { + widget.Redraw(widget.CommonSettings.Title, " NewRelic data unavailable ", false) + return + } + app, appErr := client.Application() + deploys, depErr := client.Deployments() + + appName := "error" + if appErr == nil { + appName = app.Name + } + + var content string + title := fmt.Sprintf("%s - [green]%s[white]", widget.CommonSettings.Title, appName) + wrap := false + if depErr != nil { + wrap = true + content = depErr.Error() + } else { + content = widget.contentFrom(deploys) + } + + widget.Redraw(title, content, wrap) +} + +func (widget *Widget) contentFrom(deploys []nr.ApplicationDeployment) string { + str := fmt.Sprintf( + " %s\n", + "[red]Latest Deploys[white]", + ) + + revisions := []string{} + + for _, deploy := range deploys { + if (deploy.Revision != "") && wtf.Exclude(revisions, deploy.Revision) { + lineColor := "white" + if wtf.IsToday(deploy.Timestamp) { + lineColor = "lightblue" + } + + revLen := 8 + if revLen > len(deploy.Revision) { + revLen = len(deploy.Revision) + } + + str += fmt.Sprintf( + " [green]%s[%s] %s %-.16s[white]\n", + deploy.Revision[0:revLen], + lineColor, + deploy.Timestamp.Format("Jan 02 15:04 MST"), + wtf.NameFromEmail(deploy.User), + ) + + revisions = append(revisions, deploy.Revision) + + if len(revisions) == widget.settings.deployCount { + break + } + } + } + + return str +} diff --git a/modules/newrelic/keyboard.go b/modules/newrelic/keyboard.go new file mode 100644 index 000000000..d572a4e17 --- /dev/null +++ b/modules/newrelic/keyboard.go @@ -0,0 +1,9 @@ +package newrelic + +import "github.com/gdamore/tcell" + +func (widget *Widget) initializeKeyboardControls() { + widget.SetKeyboardChar("/", widget.ShowHelp, "Show/hide this help window") + widget.SetKeyboardKey(tcell.KeyLeft, widget.PrevSource, "Select previous application") + widget.SetKeyboardKey(tcell.KeyRight, widget.NextSource, "Select next application") +} diff --git a/modules/newrelic/settings.go b/modules/newrelic/settings.go index 7c72d3b8b..ff717f3bc 100644 --- a/modules/newrelic/settings.go +++ b/modules/newrelic/settings.go @@ -12,9 +12,9 @@ const defaultTitle = "NewRelic" type Settings struct { common *cfg.Common - apiKey string - applicationID int - deployCount int + apiKey string + deployCount int + applicationIDs []interface{} } func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { @@ -22,9 +22,9 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co settings := Settings{ common: cfg.NewCommonSettingsFromModule(name, defaultTitle, ymlConfig, globalConfig), - apiKey: ymlConfig.UString("apiKey", os.Getenv("WTF_NEW_RELIC_API_KEY")), - applicationID: ymlConfig.UInt("applicationID"), - deployCount: ymlConfig.UInt("deployCount", 5), + apiKey: ymlConfig.UString("apiKey", os.Getenv("WTF_NEW_RELIC_API_KEY")), + deployCount: ymlConfig.UInt("deployCount", 5), + applicationIDs: ymlConfig.UList("applicationIDs"), } return &settings diff --git a/modules/newrelic/widget.go b/modules/newrelic/widget.go index edd1b7645..ff8adb96f 100644 --- a/modules/newrelic/widget.go +++ b/modules/newrelic/widget.go @@ -1,28 +1,37 @@ package newrelic import ( - "fmt" + "sort" "github.com/rivo/tview" "github.com/wtfutil/wtf/wtf" - nr "github.com/yfronto/newrelic" ) type Widget struct { + wtf.KeyboardWidget + wtf.MultiSourceWidget wtf.TextWidget - client *Client + Clients []*Client + settings *Settings } -func NewWidget(app *tview.Application, settings *Settings) *Widget { +func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget { widget := Widget{ - TextWidget: wtf.NewTextWidget(app, settings.common, false), + KeyboardWidget: wtf.NewKeyboardWidget(app, pages, settings.common), + MultiSourceWidget: wtf.NewMultiSourceWidget(settings.common, "applicationID", "applicationIDs"), + TextWidget: wtf.NewTextWidget(app, settings.common, true), settings: settings, } - widget.client = NewClient(widget.settings.apiKey, widget.settings.applicationID) + widget.initializeKeyboardControls() + widget.View.SetInputCapture(widget.InputCapture) + + widget.SetDisplayFunction(widget.display) + + widget.KeyboardWidget.SetView(widget.View) return &widget } @@ -30,64 +39,31 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { /* -------------------- Exported Functions -------------------- */ func (widget *Widget) Refresh() { - app, appErr := widget.client.Application() - deploys, depErr := widget.client.Deployments() - - appName := "error" - if appErr == nil { - appName = app.Name + for _, id := range wtf.ToInts(widget.settings.applicationIDs) { + widget.Clients = append(widget.Clients, NewClient(widget.settings.apiKey, id)) } - var content string - title := fmt.Sprintf("%s - [green]%s[white]", widget.CommonSettings.Title, appName) - wrap := false - if depErr != nil { - wrap = true - content = depErr.Error() - } else { - content = widget.contentFrom(deploys) - } + sort.Slice(widget.Clients, func(i, j int) bool { + return widget.Clients[i].applicationId < widget.Clients[j].applicationId + }) - widget.Redraw(title, content, wrap) + widget.display() +} + +func (widget *Widget) HelpText() string { + return widget.KeyboardWidget.HelpText() } /* -------------------- Unexported Functions -------------------- */ -func (widget *Widget) contentFrom(deploys []nr.ApplicationDeployment) string { - str := fmt.Sprintf( - " %s\n", - "[red]Latest Deploys[white]", - ) - - revisions := []string{} - - for _, deploy := range deploys { - if (deploy.Revision != "") && wtf.Exclude(revisions, deploy.Revision) { - lineColor := "white" - if wtf.IsToday(deploy.Timestamp) { - lineColor = "lightblue" - } - - revLen := 8 - if revLen > len(deploy.Revision) { - revLen = len(deploy.Revision) - } - - str += fmt.Sprintf( - " [green]%s[%s] %s %-.16s[white]\n", - deploy.Revision[0:revLen], - lineColor, - deploy.Timestamp.Format("Jan 02 15:04 MST"), - wtf.NameFromEmail(deploy.User), - ) - - revisions = append(revisions, deploy.Revision) - - if len(revisions) == widget.settings.deployCount { - break - } - } +func (widget *Widget) currentData() *Client { + if len(widget.Clients) == 0 { + return nil + } + + if widget.Idx < 0 || widget.Idx >= len(widget.Clients) { + return nil } - return str + return widget.Clients[widget.Idx] }