From 6e96b2e00f50dcd7d3f5fc8a395eac2e8df46230 Mon Sep 17 00:00:00 2001 From: Robin Trietsch Date: Tue, 17 Aug 2021 17:56:51 +0200 Subject: [PATCH] feat(usage): implement csv, json, json-raw printers for usage --- pkg/entity/usage/cmd.go | 9 ++++-- pkg/entity/usage/printers.go | 55 ++++++++++++++++++++++++++++++++++-- pkg/entity/usage/usage.go | 40 +------------------------- pkg/util/printers.go | 12 ++++++++ 4 files changed, 72 insertions(+), 44 deletions(-) diff --git a/pkg/entity/usage/cmd.go b/pkg/entity/usage/cmd.go index a91eb4c..099f4fd 100644 --- a/pkg/entity/usage/cmd.go +++ b/pkg/entity/usage/cmd.go @@ -3,6 +3,7 @@ package usage import ( "fmt" "github.com/spf13/cobra" + "streammachine.io/strm/pkg/common" "streammachine.io/strm/pkg/entity/stream" "streammachine.io/strm/pkg/util" ) @@ -61,8 +62,12 @@ from,count,duration,change,rate _ = usage.RegisterFlagCompletionFunc(fromFlag, dateCompletion) _ = usage.RegisterFlagCompletionFunc(untilFlag, dateCompletion) - //usage.PersistentFlags().Lookup(util.OutputFormatFlag).Hidden = true - flags.StringP(util.OutputFormatFlag, "o", "table", "") + flags.StringP(util.OutputFormatFlag, "o", "csv", "Usage output format [csv, json, json-raw]") + err := usage.RegisterFlagCompletionFunc(util.OutputFormatFlag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return []string{"csv", "json", "json-raw"}, cobra.ShellCompDirectiveNoFileComp + }) + + common.CliExit(err) return usage } diff --git a/pkg/entity/usage/printers.go b/pkg/entity/usage/printers.go index 4d7b2a1..d68b2c9 100644 --- a/pkg/entity/usage/printers.go +++ b/pkg/entity/usage/printers.go @@ -1,7 +1,13 @@ package usage import ( + "fmt" + "github.com/jedib0t/go-pretty/v6/table" "github.com/spf13/cobra" + "github.com/streammachineio/api-definitions-go/api/usage/v1" + "google.golang.org/protobuf/proto" + "math" + "streammachine.io/strm/pkg/common" "streammachine.io/strm/pkg/util" ) @@ -11,11 +17,54 @@ func configurePrinter(cmd *cobra.Command) util.Printer { outputFormat := util.GetStringAndErr(cmd.Flags(), util.OutputFormatFlag) switch outputFormat { - case "json": + case "json-raw": return util.GenericRawJsonPrinter{} + case "json": + return util.GenericPrettyJsonPrinter{} case "table": - return util.GenericRawJsonPrinter{} + common.CliExit("Output format 'table' is not supported for usage.") + return nil + case "csv": + return getCsvPrinter{} default: - return util.GenericRawJsonPrinter{} + return util.GenericPrettyJsonPrinter{} } } + +type getCsvPrinter struct{} + +func (p getCsvPrinter) Print(data proto.Message) { + streamUsage, _ := (data).(*usage.GetStreamEventUsageResponse) + + rows := make([]table.Row, 0, len(streamUsage.Windows)) + + windowCount := int64(-1) + change := math.NaN() + for _, window := range streamUsage.Windows { + if windowCount != -1 { + change = float64(window.EventCount - windowCount) + } + windowCount = window.EventCount + + windowDuration := window.EndTime.AsTime().Sub(window.StartTime.AsTime()) + rate := change / windowDuration.Seconds() + + rows = append(rows, table.Row{ + fmt.Sprintf("%d", windowCount), + fmt.Sprintf("%.0f", windowDuration.Seconds()), + fmt.Sprintf("%v", change), + fmt.Sprintf("%.2f", rate), + }) + } + + util.RenderCsv( + table.Row{ + "From", + "Count", + "Duration", + "Change", + "Rate", + }, + rows, + ) +} diff --git a/pkg/entity/usage/usage.go b/pkg/entity/usage/usage.go index a22d64c..d7ce9ff 100644 --- a/pkg/entity/usage/usage.go +++ b/pkg/entity/usage/usage.go @@ -2,7 +2,6 @@ package usage import ( "context" - "encoding/csv" "fmt" "github.com/bykof/gostradamus" "github.com/golang/protobuf/ptypes/duration" @@ -11,14 +10,11 @@ import ( "github.com/streammachineio/api-definitions-go/api/entities/v1" "github.com/streammachineio/api-definitions-go/api/usage/v1" "google.golang.org/grpc" - "math" - "os" "regexp" "strconv" "streammachine.io/strm/pkg/common" "streammachine.io/strm/pkg/util" "strings" - "time" ) const ( @@ -73,36 +69,8 @@ func get(cmd *cobra.Command, streamName *string) { streamUsage, err := client.GetStreamEventUsage(apiContext, req) common.CliExit(err) - if util.GetBoolAndErr(flags, jsonFlag) { - printer.Print(streamUsage) - } else { - printCsv(streamUsage) - } -} -func printCsv(streamUsage *usage.GetStreamEventUsageResponse) { - w := csv.NewWriter(os.Stdout) - _ = w.Write([]string{"from", "count", "duration", "change", "rate"}) - - windowCount := int64(-1) - change := math.NaN() - for _, window := range streamUsage.Windows { - if windowCount != -1 { - change = float64(window.EventCount - windowCount) - } - windowCount = window.EventCount - - windowDuration := window.EndTime.AsTime().Sub(window.StartTime.AsTime()) - rate := change / windowDuration.Seconds() - record := []string{isoFormat(window.StartTime.AsTime()), - fmt.Sprintf("%d", windowCount), - fmt.Sprintf("%.0f", windowDuration.Seconds()), - fmt.Sprintf("%v", change), - fmt.Sprintf("%.2f", rate), - } - _ = w.Write(record) - } - w.Flush() + printer.Print(streamUsage) } func interpretInterval(by string) int64 { @@ -134,12 +102,6 @@ func interpretInterval(by string) int64 { return interval } -func isoFormat(t time.Time) string { - n := gostradamus.DateTimeFromTime(t) - return n.InTimezone(tz).IsoFormatTZ() - //return t.Format(time.RFC3339) -} - func dateCompletion(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { endTime := gostradamus.NowInTimezone(tz).FloorHour() hourRange := 48 diff --git a/pkg/util/printers.go b/pkg/util/printers.go index 63650a6..f8a016b 100644 --- a/pkg/util/printers.go +++ b/pkg/util/printers.go @@ -75,6 +75,18 @@ func RenderTable(headers table.Row, rows []table.Row) { } } +func RenderCsv(headers table.Row, rows []table.Row) { + if len(rows) == 0 { + fmt.Println("No usage in the provided time period.") + } else { + t := table.NewWriter() + t.SetOutputMirror(os.Stdout) + t.AppendHeader(headers) + t.AppendRows(rows) + t.RenderCSV() + } +} + var noBordersStyle = table.Style{ Name: "StyleNoBorders", Options: table.OptionsNoBorders,