From 112e516f133241efb708b583d31ad8f4e1212a8e Mon Sep 17 00:00:00 2001 From: yamasaki Date: Sat, 23 Sep 2023 04:30:42 +0900 Subject: [PATCH] feat : bluma output and metrics analyze --- cmd/attack.go | 30 ++++++++++++++++++++++++++++-- cmd/root.go | 26 ++++++++++++++++++++------ 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/cmd/attack.go b/cmd/attack.go index f3fce94..b376dc5 100644 --- a/cmd/attack.go +++ b/cmd/attack.go @@ -31,6 +31,7 @@ import ( "time" "github.com/seipan/bulma/lib" + vegeta "github.com/tsenart/vegeta/lib" ) func ParseAndAttack(ctx context.Context, path string, freq int, duration time.Duration) error { @@ -43,13 +44,17 @@ func ParseAndAttack(ctx context.Context, path string, freq int, duration time.Du if err != nil { return fmt.Errorf("failed to convert openapi to attacker: %w", err) } + fmt.Println("--------------------------bulma attack start-------------------------------") var wg sync.WaitGroup for _, atk := range atks { wg.Add(1) - go atk.Attack() + go func() { + metrics := atk.Attack() + outputMetrics(metrics, &atk) + }() wg.Done() } - + fmt.Println("--------------------------bulma attack finish-------------------------------") wg.Wait() return nil } @@ -87,3 +92,24 @@ func createBody(bodys []lib.Body) ([]byte, error) { } return jsonData, nil } + +func outputMetrics(metrics vegeta.Metrics, atk *lib.Attacker) { + fmt.Printf("--------------------------vegeta attack to %s--------------------------\n", atk.Path.Path()) + mtd := atk.Path.Method(atk.MethodIndex) + fmt.Printf("vegeta attack to method: %s\n", mtd.Method()) + fmt.Printf("path StatusCode: %v\n", metrics.StatusCodes) + + fmt.Println() + + fmt.Printf("max percentile: %s\n", metrics.Latencies.Max) + fmt.Printf("mean percentile: %s\n", metrics.Latencies.Mean) + fmt.Printf("total percentile: %s\n", metrics.Latencies.Total) + fmt.Printf("99th percentile: %s\n", metrics.Latencies.P99) + + fmt.Println() + + fmt.Printf(" earliest: %v\n", metrics.Earliest) + fmt.Printf(" latest: %v\n", metrics.Latest) + + fmt.Println("-----------------------------------------------------------------------") +} diff --git a/cmd/root.go b/cmd/root.go index ede882d..32b3b0b 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -23,6 +23,7 @@ package cmd import ( + "log" "os" "github.com/spf13/cobra" @@ -32,15 +33,28 @@ import ( var rootCmd = &cobra.Command{ Use: "bluma", Short: "CLI tool to parse OpenAPI and stress test each endpoint.", - Long: `A longer description that spans multiple lines and likely contains -examples and usage of using your application. For example: - -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.`, + Long: `CLI tool to parse OpenAPI and stress test each endpoint..`, // Uncomment the following line if your bare application // has an action associated with it: // Run: func(cmd *cobra.Command, args []string) { }, + Run: func(cmd *cobra.Command, args []string) { + path, err := cmd.Flags().GetString("path") + if err != nil { + log.Println(err) + } + freq, err := cmd.Flags().GetInt("frequency") + if err != nil { + log.Println(err) + } + duration, err := cmd.Flags().GetDuration("duration") + if err != nil { + log.Println(err) + } + err = ParseAndAttack(cmd.Context(), path, freq, duration) + if err != nil { + log.Println(err) + } + }, } // Execute adds all child commands to the root command and sets flags appropriately.