diff --git a/Gomfile b/Gomfile index b306c19..0572e1f 100644 --- a/Gomfile +++ b/Gomfile @@ -1,4 +1,5 @@ gom 'github.com/fatih/color' +gom 'github.com/hico-horiuchi/uitable' gom 'github.com/mattn/go-isatty' gom 'github.com/spf13/cobra' gom 'github.com/tcnksm/go-latest' diff --git a/ohgi/aggregates.go b/ohgi/aggregates.go index 801a273..14c985e 100644 --- a/ohgi/aggregates.go +++ b/ohgi/aggregates.go @@ -1,6 +1,7 @@ package ohgi import ( + "fmt" "strconv" "strings" @@ -8,8 +9,6 @@ import ( ) func GetAggregates(api *sensu.API, limit int, offset int) string { - var line string - aggregates, err := api.GetAggregates(limit, offset) checkError(err) @@ -17,18 +16,19 @@ func GetAggregates(api *sensu.API, limit int, offset int) string { return "No aggregates\n" } - print := []byte(bold("CHECK ISSUES\n")) + table := newUitable() + table.AddRow(bold("CHECK"), bold("ISSUES")) for _, aggregate := range aggregates { - line = fillSpace(aggregate.Check, 30) + strconv.Itoa(len(aggregate.Issued)) + "\n" - print = append(print, line...) + table.AddRow( + aggregate.Check, + strconv.Itoa(len(aggregate.Issued)), + ) } - return string(print) + return fmt.Sprintln(table) } func GetAggregatesCheck(api *sensu.API, check string, age int) string { - var line string - issues, err := api.GetAggregatesCheck(check, age) checkError(err) @@ -36,13 +36,16 @@ func GetAggregatesCheck(api *sensu.API, check string, age int) string { return "No aggregates\n" } - print := []byte(bold("TIMESTAMP ISSUED\n")) + table := newUitable() + table.AddRow(bold("TIMESTAMP"), bold("ISSUED")) for _, issued := range issues { - line = utoa(issued) + " " + strconv.FormatInt(issued, 10) + "\n" - print = append(print, line...) + table.AddRow( + utoa(issued), + strconv.FormatInt(issued, 10), + ) } - return string(print) + return fmt.Sprintln(table) } func DeleteAggregatesCheck(api *sensu.API, check string) string { @@ -53,8 +56,6 @@ func DeleteAggregatesCheck(api *sensu.API, check string) string { } func GetAggregatesCheckIssued(api *sensu.API, check string, issued string, summarize string, results bool) string { - var print []byte - if issued == "latest" { issues, err := api.GetAggregatesCheck(check, -1) checkError(err) @@ -71,20 +72,23 @@ func GetAggregatesCheckIssued(api *sensu.API, check string, issued string, summa aggregate, err := api.GetAggregatesCheckIssued(check, i, summarize, results) checkError(err) + table := newUitable() if summarize != "" { for output, j := range aggregate.Outputs { - output = strings.Replace(output, "\n", " ", -1) - print = append(print, (bold(fillSpace(output, 50)) + strconv.Itoa(j) + "\n")...) + table.AddRow( + bold(strings.Replace(output, "\n", " ", -1)), + strconv.Itoa(j), + ) } - return string(print) + return fmt.Sprintln(table) } - print = append(print, (bold("OK ") + fgColor(strconv.Itoa(aggregate.Ok), 0) + "\n")...) - print = append(print, (bold("WARNING ") + fgColor(strconv.Itoa(aggregate.Warning), 1) + "\n")...) - print = append(print, (bold("CRITICAL ") + fgColor(strconv.Itoa(aggregate.Critical), 2) + "\n")...) - print = append(print, (bold("UNKNOWN ") + fgColor(strconv.Itoa(aggregate.Unknown), 3) + "\n")...) - print = append(print, (bold("TOTAL ") + strconv.Itoa(aggregate.Total) + "\n")...) + table.AddRow(bold("OK:"), fgColor(strconv.Itoa(aggregate.Ok), 0)) + table.AddRow(bold("WARNING:"), fgColor(strconv.Itoa(aggregate.Warning), 1)) + table.AddRow(bold("CRITICAL:"), fgColor(strconv.Itoa(aggregate.Critical), 2)) + table.AddRow(bold("UNKNOWN:"), fgColor(strconv.Itoa(aggregate.Unknown), 3)) + table.AddRow(bold("TOTAL:"), strconv.Itoa(aggregate.Total)) if results { clients := make([]string, len(aggregate.Results)) @@ -92,8 +96,8 @@ func GetAggregatesCheckIssued(api *sensu.API, check string, issued string, summa clients[j] = result.Client } - print = append(print, (bold("CLIENTS ") + strings.Join(clients, ", ") + "\n")...) + table.AddRow(bold("CLIENTS:"), strings.Join(clients, ", ")) } - return string(print) + return fmt.Sprintln(table) } diff --git a/ohgi/checks.go b/ohgi/checks.go index 9443242..e7b33d0 100644 --- a/ohgi/checks.go +++ b/ohgi/checks.go @@ -1,6 +1,7 @@ package ohgi import ( + "fmt" "regexp" "strconv" "strings" @@ -9,8 +10,6 @@ import ( ) func GetChecks(api *sensu.API) string { - var line string - checks, err := api.GetChecks() checkError(err) @@ -18,19 +17,23 @@ func GetChecks(api *sensu.API) string { return "No checks\n" } - print := []byte(bold("NAME COMMAND INTERVAL\n")) + table := newUitable() + table.AddRow(bold("NAME"), bold("COMMAND"), bold("INTERVAL")) for _, check := range checks { - line = fillSpace(check.Name, 30) + fillSpace(check.Command, 60) + strconv.Itoa(check.Interval) + "\n" - print = append(print, line...) + table.AddRow( + check.Name, + check.Command, + strconv.Itoa(check.Interval), + ) } - return string(print) + return fmt.Sprintln(table) } func GetChecksWildcard(api *sensu.API, pattern string) string { var match []string var matches []int - var line string + var check sensu.CheckStruct checks, err := api.GetChecks() checkError(err) @@ -47,27 +50,30 @@ func GetChecksWildcard(api *sensu.API, pattern string) string { return "No checks that matches " + pattern + "\n" } - print := []byte(bold("NAME COMMAND INTERVAL\n")) + table := newUitable() + table.AddRow(bold("NAME"), bold("COMMAND"), bold("INTERVAL")) for _, i := range matches { - check := checks[i] - line = fillSpace(check.Name, 30) + fillSpace(check.Command, 60) + strconv.Itoa(check.Interval) + "\n" - print = append(print, line...) + check = checks[i] + table.AddRow( + check.Name, + check.Command, + strconv.Itoa(check.Interval), + ) } - return string(print) + return fmt.Sprintln(table) } func GetChecksCheck(api *sensu.API, name string) string { - var print []byte - check, err := api.GetChecksCheck(name) checkError(err) - print = append(print, (bold("NAME ") + check.Name + "\n")...) - print = append(print, (bold("COMMAND ") + check.Command + "\n")...) - print = append(print, (bold("SUBSCRIBERS ") + strings.Join(check.Subscribers, ", ") + "\n")...) - print = append(print, (bold("INTERVAL ") + strconv.Itoa(check.Interval) + "\n")...) - print = append(print, (bold("HANDLERS ") + strings.Join(check.Handlers, ", ") + "\n")...) + table := newUitable() + table.AddRow(bold("NAME:"), check.Name) + table.AddRow(bold("COMMAND:"), check.Command) + table.AddRow(bold("SUBSCRIBERS:"), strings.Join(check.Subscribers, ", ")) + table.AddRow(bold("INTERVAL:"), strconv.Itoa(check.Interval)) + table.AddRow(bold("HANDLERS:"), strings.Join(check.Handlers, ", ")) - return string(print) + return fmt.Sprintln(table) } diff --git a/ohgi/clients.go b/ohgi/clients.go index 8c2969f..e0c51cd 100644 --- a/ohgi/clients.go +++ b/ohgi/clients.go @@ -1,6 +1,7 @@ package ohgi import ( + "fmt" "regexp" "strings" @@ -8,8 +9,6 @@ import ( ) func GetClients(api *sensu.API, limit int, offset int) string { - var line string - clients, err := api.GetClients(limit, offset) checkError(err) @@ -17,19 +16,23 @@ func GetClients(api *sensu.API, limit int, offset int) string { return "No clients\n" } - print := []byte(bold("NAME ADDRESS TIMESTAMP\n")) + table := newUitable() + table.AddRow(bold("NAME"), bold("ADDRESS"), bold("TIMESTAMP")) for _, client := range clients { - line = fillSpace(client.Name, 40) + fillSpace(client.Address, 40) + utoa(client.Timestamp) + "\n" - print = append(print, line...) + table.AddRow( + client.Name, + client.Address, + client.Timestamp, + ) } - return string(print) + return fmt.Sprintln(table) } func GetClientsWildcard(api *sensu.API, pattern string) string { var match []string var matches []int - var line string + var client sensu.ClientStruct clients, err := api.GetClients(-1, -1) checkError(err) @@ -46,29 +49,32 @@ func GetClientsWildcard(api *sensu.API, pattern string) string { return "No clients that matches " + pattern + "\n" } - print := []byte(bold("NAME ADDRESS TIMESTAMP\n")) + table := newUitable() + table.AddRow(bold("NAME"), bold("ADDRESS"), bold("TIMESTAMP")) for _, i := range matches { - client := clients[i] - line = fillSpace(client.Name, 40) + fillSpace(client.Address, 40) + utoa(client.Timestamp) + "\n" - print = append(print, line...) + client = clients[i] + table.AddRow( + client.Name, + client.Address, + client.Timestamp, + ) } - return string(print) + return fmt.Sprintln(table) } func GetClientsClient(api *sensu.API, name string) string { - var print []byte - client, err := api.GetClientsClient(name) checkError(err) - print = append(print, (bold("NAME ") + client.Name + "\n")...) - print = append(print, (bold("ADDRESS ") + client.Address + "\n")...) - print = append(print, (bold("SUBSCRIPTIONS ") + strings.Join(client.Subscriptions, ", ") + "\n")...) - print = append(print, (bold("TIMESTAMP ") + utoa(client.Timestamp) + "\n")...) - print = append(print, (bold("VERSION ") + client.Version + "\n")...) + table := newUitable() + table.AddRow(bold("NAME:"), client.Name) + table.AddRow(bold("ADDRESS:"), client.Address) + table.AddRow(bold("SUBSCRIPTIONS:"), strings.Join(client.Subscriptions, ", ")) + table.AddRow(bold("TIMESTAMP:"), utoa(client.Timestamp)) + table.AddRow(bold("VERSION:"), client.Version) - return string(print) + return fmt.Sprintln(table) } func PostClients(api *sensu.API, name string, address string, subscriptions []string) string { diff --git a/ohgi/events.go b/ohgi/events.go index 8f58bbf..e582c47 100644 --- a/ohgi/events.go +++ b/ohgi/events.go @@ -1,6 +1,7 @@ package ohgi import ( + "fmt" "regexp" "strconv" "strings" @@ -9,8 +10,6 @@ import ( ) func GetEvents(api *sensu.API) string { - var line string - events, err := api.GetEvents() checkError(err) @@ -18,19 +17,25 @@ func GetEvents(api *sensu.API) string { return "No current events\n" } - print := []byte(bold(" CLIENT CHECK # EXECUTED\n")) + table := newUitable() + table.AddRow("", bold("CLIENT"), bold("CHECK"), bold("#"), bold("EXECUTED")) for _, event := range events { - line = indicateStatus(event.Check.Status) + fillSpace(event.Client.Name, 40) + fillSpace(event.Check.Name, 30) + fillSpace(strconv.Itoa(event.Occurrences), 10) + utoa(event.Check.Executed) + "\n" - print = append(print, line...) + table.AddRow( + indicateStatus(event.Check.Status), + event.Client.Name, + event.Check.Name, + strconv.Itoa(event.Occurrences), + utoa(event.Check.Executed), + ) } - return string(print) + return fmt.Sprintln(table) } func GetEventsWildcard(api *sensu.API, pattern string) string { var match []string var matches []int - var line string + var event sensu.EventStruct events, err := api.GetEvents() checkError(err) @@ -44,22 +49,26 @@ func GetEventsWildcard(api *sensu.API, pattern string) string { } if len(matches) == 0 { - return "No current events that match " + pattern + "\n" + return "No current events that matches " + pattern + "\n" } - print := []byte(bold(" CLIENT CHECK # EXECUTED\n")) + table := newUitable() + table.AddRow("", bold("CLIENT"), bold("CHECK"), bold("#"), bold("EXECUTED")) for _, i := range matches { - event := events[i] - line = indicateStatus(event.Check.Status) + fillSpace(event.Client.Name, 40) + fillSpace(event.Check.Name, 30) + fillSpace(strconv.Itoa(event.Occurrences), 10) + utoa(event.Check.Executed) + "\n" - print = append(print, line...) + event = events[i] + table.AddRow( + indicateStatus(event.Check.Status), + event.Client.Name, + event.Check.Name, + strconv.Itoa(event.Occurrences), + utoa(event.Check.Executed), + ) } - return string(print) + return fmt.Sprintln(table) } func GetEventsClient(api *sensu.API, client string) string { - var line, output string - events, err := api.GetEventsClient(client) checkError(err) @@ -67,41 +76,44 @@ func GetEventsClient(api *sensu.API, client string) string { return "No current events for " + client + "\n" } - print := []byte(bold(" CHECK OUTPUT EXECUTED\n")) + table := newUitable() + table.AddRow("", bold("CHECK"), bold("OUTPUT"), bold("EXECUTED")) for _, event := range events { - output = strings.Replace(event.Check.Output, "\n", " ", -1) - line = indicateStatus(event.Check.Status) + fillSpace(event.Check.Name, 30) + fillSpace(output, 50) + utoa(event.Check.Executed) + "\n" - print = append(print, line...) + table.AddRow( + indicateStatus(event.Check.Status), + event.Check.Name, + strings.Replace(event.Check.Output, "\n", " ", -1), + utoa(event.Check.Executed), + ) } - return string(print) + return fmt.Sprintln(table) } func GetEventsClientCheck(api *sensu.API, client string, check string) string { - var print []byte - event, err := api.GetEventsClientCheck(client, check) checkError(err) - print = append(print, (bold("CLIENT ") + event.Client.Name + "\n")...) - print = append(print, (bold("ADDRESS ") + event.Client.Address + "\n")...) - print = append(print, (bold("SUBSCRIPTIONS ") + strings.Join(event.Client.Subscriptions, ", ") + "\n")...) - print = append(print, (bold("TIMESTAMP ") + utoa(event.Client.Timestamp) + "\n")...) - print = append(print, (bold("CHECK ") + event.Check.Name + "\n")...) - print = append(print, (bold("COMMAND ") + event.Check.Command + "\n")...) - print = append(print, (bold("SUBSCRIBERS ") + strings.Join(event.Check.Subscribers, ", ") + "\n")...) - print = append(print, (bold("INTERVAL ") + strconv.Itoa(event.Check.Interval) + "\n")...) - print = append(print, (bold("HANDLERS ") + strings.Join(event.Check.Handlers, ", ") + "\n")...) - print = append(print, (bold("ISSUED ") + utoa(event.Check.Issued) + "\n")...) - print = append(print, (bold("EXECUTED ") + utoa(event.Check.Executed) + "\n")...) - print = append(print, (bold("OUTPUT ") + strings.Replace(event.Check.Output, "\n", " ", -1) + "\n")...) - print = append(print, (bold("STATUS ") + colorStatus(event.Check.Status) + "\n")...) - print = append(print, (bold("DURATION ") + strconv.FormatFloat(event.Check.Duration, 'f', 3, 64) + "\n")...) - print = append(print, (bold("HISTORY ") + colorHistory(strings.Join(event.Check.History, ", ")) + "\n")...) - print = append(print, (bold("OCCURRENCES ") + strconv.Itoa(event.Occurrences) + "\n")...) - print = append(print, (bold("ACTION ") + event.Action + "\n")...) - - return string(print) + table := newUitable() + table.AddRow(bold("CLIENT:"), event.Client.Name) + table.AddRow(bold("ADDRESS:"), event.Client.Address) + table.AddRow(bold("SUBSCRIPTIONS:"), strings.Join(event.Client.Subscriptions, ", ")) + table.AddRow(bold("TIMESTAMP:"), utoa(event.Client.Timestamp)) + table.AddRow(bold("CHECK:"), event.Check.Name) + table.AddRow(bold("COMMAND:"), event.Check.Command) + table.AddRow(bold("SUBSCRIBERS:"), strings.Join(event.Check.Subscribers, ", ")) + table.AddRow(bold("INTERVAL:"), strconv.Itoa(event.Check.Interval)) + table.AddRow(bold("HANDLERS:"), strings.Join(event.Check.Handlers, ", ")) + table.AddRow(bold("ISSUED:"), utoa(event.Check.Issued)) + table.AddRow(bold("EXECUTED:"), utoa(event.Check.Executed)) + table.AddRow(bold("OUTPUT:"), strings.Replace(event.Check.Output, "\n", " ", -1)) + table.AddRow(bold("STATUS:"), colorStatus(event.Check.Status)) + table.AddRow(bold("DURATION:"), strconv.FormatFloat(event.Check.Duration, 'f', 3, 64)) + table.AddRow(bold("HISTORY:"), colorHistory(strings.Join(event.Check.History, ", "))) + table.AddRow(bold("OCCURRENCES:"), strconv.Itoa(event.Occurrences)) + table.AddRow(bold("ACTION:"), event.Action) + + return fmt.Sprintln(table) } func DeleteEventsClientCheck(api *sensu.API, client string, check string) string { diff --git a/ohgi/history.go b/ohgi/history.go index 7a33c33..3cd166e 100644 --- a/ohgi/history.go +++ b/ohgi/history.go @@ -1,10 +1,12 @@ package ohgi -import "github.com/hico-horiuchi/ohgi/sensu" +import ( + "fmt" -func GetClientsHistory(api *sensu.API, client string) string { - var line string + "github.com/hico-horiuchi/ohgi/sensu" +) +func GetClientsHistory(api *sensu.API, client string) string { histories, err := api.GetClientsHistory(client) checkError(err) @@ -12,11 +14,15 @@ func GetClientsHistory(api *sensu.API, client string) string { return "No histories\n" } - print := []byte(bold("CHECK HISTORY TIMESTAMP\n")) + table := newUitable() + table.AddRow(bold("CHECK"), bold("HISTORY"), bold("TIMESTAMP")) for _, history := range histories { - line = fillSpace(history.Check, 30) + colorHistory(fillSpace(stoa(history.History, ", "), 48)) + utoa(history.LastExecution) + "\n" - print = append(print, line...) + table.AddRow( + history.Check, + colorHistory(stoa(history.History, ", ")), + utoa(history.LastExecution), + ) } - return string(print) + return fmt.Sprintln(table) } diff --git a/ohgi/info.go b/ohgi/info.go index 26c1877..858b28d 100644 --- a/ohgi/info.go +++ b/ohgi/info.go @@ -1,20 +1,20 @@ package ohgi import ( + "fmt" "strconv" "github.com/hico-horiuchi/ohgi/sensu" ) func GetInfo(api *sensu.API) string { - var print []byte - info, err := api.GetInfo() checkError(err) - print = append(print, (bold("VERSION ") + info.Sensu.Version + "\n")...) - print = append(print, (bold("TRANSPORT ") + strconv.FormatBool(info.Transport.Connected) + "\n")...) - print = append(print, (bold("REDIS ") + strconv.FormatBool(info.Redis.Connected) + "\n")...) + table := newUitable() + table.AddRow(bold("VERSION:"), info.Sensu.Version) + table.AddRow(bold("TRANSPORT:"), strconv.FormatBool(info.Transport.Connected)) + table.AddRow(bold("REDIS:"), strconv.FormatBool(info.Redis.Connected)) - return string(print) + return fmt.Sprintln(table) } diff --git a/ohgi/initialize.go b/ohgi/initialize.go index 04e008d..d3a7955 100644 --- a/ohgi/initialize.go +++ b/ohgi/initialize.go @@ -1,17 +1,41 @@ package ohgi import ( + "fmt" "os" + "os/exec" + "strconv" + "strings" isatty "github.com/mattn/go-isatty" ) var escapeSequence bool +var terminalWidth int func Initialize() { escapeSequence = isTerminal() + terminalWidth = getTerminalWidth() } func isTerminal() bool { return isatty.IsTerminal(os.Stdout.Fd()) } + +func getTerminalWidth() int { + cmd := exec.Command("stty", "size") + cmd.Stdin = os.Stdin + out, err := cmd.Output() + checkError(err) + + arr := strings.Split(strings.TrimRight(string(out), "\n"), " ") + if len(arr) != 2 { + fmt.Println("Can not get the terminal width with stty") + os.Exit(1) + } + + w, err := strconv.ParseInt(arr[1], 10, 0) + checkError(err) + + return int(w) +} diff --git a/ohgi/results.go b/ohgi/results.go index 5e74f10..13487c1 100644 --- a/ohgi/results.go +++ b/ohgi/results.go @@ -1,6 +1,7 @@ package ohgi import ( + "fmt" "regexp" "strconv" "strings" @@ -9,8 +10,6 @@ import ( ) func GetResults(api *sensu.API) string { - var line string - results, err := api.GetResults() checkError(err) @@ -18,19 +17,24 @@ func GetResults(api *sensu.API) string { return "No current check results\n" } - print := []byte(bold(" CLIENT CHECK EXECUTED\n")) + table := newUitable() + table.AddRow("", bold("CLIENT"), bold("CHECK"), bold("EXECUTED")) for _, result := range results { - line = indicateStatus(result.Check.Status) + fillSpace(result.Client, 40) + fillSpace(result.Check.Name, 30) + utoa(result.Check.Executed) + "\n" - print = append(print, line...) + table.AddRow( + indicateStatus(result.Check.Status), + result.Client, + result.Check.Name, + utoa(result.Check.Executed), + ) } - return string(print) + return fmt.Sprintln(table) } func GetResultsWildcard(api *sensu.API, pattern string) string { var match []string var matches []int - var line string + var result sensu.ResultStruct results, err := api.GetResults() checkError(err) @@ -47,19 +51,22 @@ func GetResultsWildcard(api *sensu.API, pattern string) string { return "No current check results that matches " + pattern + "\n" } - print := []byte(bold(" CLIENT CHECK EXECUTED\n")) + table := newUitable() + table.AddRow("", bold("CLIENT"), bold("CHECK"), bold("EXECUTED")) for _, i := range matches { - result := results[i] - line = indicateStatus(result.Check.Status) + fillSpace(result.Client, 40) + fillSpace(result.Check.Name, 30) + utoa(result.Check.Executed) + "\n" - print = append(print, line...) + result = results[i] + table.AddRow( + indicateStatus(result.Check.Status), + result.Client, + result.Check.Name, + utoa(result.Check.Executed), + ) } - return string(print) + return fmt.Sprintln(table) } func GetResultsClient(api *sensu.API, client string) string { - var line, output string - results, err := api.GetResultsClient(client) checkError(err) @@ -67,33 +74,36 @@ func GetResultsClient(api *sensu.API, client string) string { return "No current check results for " + client + "\n" } - print := []byte(bold(" CHECK OUTPUT EXECUTED\n")) + table := newUitable() + table.AddRow("", bold("CHECK"), bold("OUTPUT"), bold("EXECUTED")) for _, result := range results { - output = strings.Replace(result.Check.Output, "\n", " ", -1) - line = indicateStatus(result.Check.Status) + fillSpace(result.Check.Name, 30) + fillSpace(output, 50) + utoa(result.Check.Executed) + "\n" - print = append(print, line...) + table.AddRow( + indicateStatus(result.Check.Status), + result.Check.Name, + strings.Replace(result.Check.Output, "\n", " ", -1), + utoa(result.Check.Executed), + ) } - return string(print) + return fmt.Sprintln(table) } func GetResultsClientCheck(api *sensu.API, client string, check string) string { - var print []byte - result, err := api.GetResultsClientCheck(client, check) checkError(err) - print = append(print, (bold("CLIENT ") + result.Client + "\n")...) - print = append(print, (bold("CHECK ") + result.Check.Name + "\n")...) - print = append(print, (bold("COMMAND ") + result.Check.Command + "\n")...) - print = append(print, (bold("SUBSCRIBERS ") + strings.Join(result.Check.Subscribers, ", ") + "\n")...) - print = append(print, (bold("INTERVAL ") + strconv.Itoa(result.Check.Interval) + "\n")...) - print = append(print, (bold("HANDLERS ") + strings.Join(result.Check.Handlers, ", ") + "\n")...) - print = append(print, (bold("ISSUED ") + utoa(result.Check.Issued) + "\n")...) - print = append(print, (bold("EXECUTED ") + utoa(result.Check.Executed) + "\n")...) - print = append(print, (bold("OUTPUT ") + strings.Replace(result.Check.Output, "\n", " ", -1) + "\n")...) - print = append(print, (bold("STATUS ") + colorStatus(result.Check.Status) + "\n")...) - print = append(print, (bold("DURATION ") + strconv.FormatFloat(result.Check.Duration, 'f', 3, 64) + "\n")...) - - return string(print) + table := newUitable() + table.AddRow(bold("CLIENT:"), result.Client) + table.AddRow(bold("CHECK:"), result.Check.Name) + table.AddRow(bold("COMMAND:"), result.Check.Command) + table.AddRow(bold("SUBSCRIBERS:"), strings.Join(result.Check.Subscribers, ", ")) + table.AddRow(bold("INTERVAL:"), strconv.Itoa(result.Check.Interval)) + table.AddRow(bold("HANDLERS:"), strings.Join(result.Check.Handlers, ", ")) + table.AddRow(bold("ISSUED:"), utoa(result.Check.Issued)) + table.AddRow(bold("EXECUTED:"), utoa(result.Check.Executed)) + table.AddRow(bold("OUTPUT:"), strings.Replace(result.Check.Output, "\n", " ", -1)) + table.AddRow(bold("STATUS:"), colorStatus(result.Check.Status)) + table.AddRow(bold("DURATION:"), strconv.FormatFloat(result.Check.Duration, 'f', 3, 64)) + + return fmt.Sprintln(table) } diff --git a/ohgi/silence.go b/ohgi/silence.go index eb0bcdd..8db7565 100644 --- a/ohgi/silence.go +++ b/ohgi/silence.go @@ -1,6 +1,7 @@ package ohgi import ( + "fmt" "strings" "time" @@ -20,7 +21,6 @@ type contentStruct struct { func GetSilence(api *sensu.API) string { var silences []silenceStruct - var line string var path []string var expire string @@ -31,7 +31,8 @@ func GetSilence(api *sensu.API) string { return "No silence stashes\n" } - print := []byte(bold("CLIENT CHECK REASON EXPIRATION\n")) + table := newUitable() + table.AddRow(bold("CLIENT"), bold("CHECK"), bold("REASON"), bold("EXPIRATION")) for _, silence := range silences { path = strings.Split(silence.Path, "/") if path[0] != "silence" { @@ -46,11 +47,15 @@ func GetSilence(api *sensu.API) string { expire = utoa(time.Now().Unix() + silence.Expire) } - line = fillSpace(path[1], 40) + fillSpace(path[2], 30) + fillSpace(silence.Content.Reason, 30) + expire + "\n" - print = append(print, line...) + table.AddRow( + path[1], + path[2], + silence.Content.Reason, + expire, + ) } - return string(print) + return fmt.Sprintln(table) } func PostSilence(api *sensu.API, client string, check string, expiration string, reason string) string { diff --git a/ohgi/utilities.go b/ohgi/utilities.go index cc9d604..c7d54dc 100644 --- a/ohgi/utilities.go +++ b/ohgi/utilities.go @@ -5,7 +5,8 @@ import ( "os" "regexp" "strconv" - "strings" + + "github.com/hico-horiuchi/uitable" ) func checkError(err error) { @@ -15,23 +16,19 @@ func checkError(err error) { } } -func fillSpace(str string, max int) string { - length := len(str) - padding := 2 - width := max - padding - if length > width { - return str[0:width] + strings.Repeat(" ", padding) - } else { - return str + strings.Repeat(" ", max-length) - } +func newUitable() *uitable.Table { + table := uitable.New() + table.MaxColWidth = uint(terminalWidth / 2) + + return table } func indicateStatus(status int) string { if !escapeSequence { - return strconv.Itoa(status) + " " + return strconv.Itoa(status) } - return bgColor(" ", status) + " " + return bgColor(" ", status) } func colorStatus(status int) string {