// attack validates the attack arguments, sets up the // required resources, launches the attack and writes the results func attack(rate uint64, duration time.Duration, targetsf, ordering, output string, redirects int, timeout time.Duration, unique bool, hdr http.Header) error { if rate == 0 { return fmt.Errorf(errRatePrefix + "can't be zero") } if duration == 0 { return fmt.Errorf(errDurationPrefix + "can't be zero") } in, err := file(targetsf, false) if err != nil { return fmt.Errorf(errTargetsFilePrefix+"(%s): %s", targetsf, err) } defer in.Close() targets, err := vegeta.NewTargetsFrom(in, unique) if err != nil { return fmt.Errorf(errTargetsFilePrefix+"(%s): %s", targetsf, err) } targets.SetHeader(hdr) switch ordering { case "random": targets.Shuffle(time.Now().UnixNano()) case "sequential": break default: return fmt.Errorf(errOrderingPrefix+"`%s` is invalid", ordering) } out, err := file(output, true) if err != nil { return fmt.Errorf(errOutputFilePrefix+"(%s): %s", output, err) } defer out.Close() vegeta.DefaultAttacker.SetRedirects(redirects) if timeout > 0 { vegeta.DefaultAttacker.SetTimeout(timeout) } log.Printf("Vegeta is attacking %d targets in %s order for %s...\n", len(targets), ordering, duration) results := vegeta.Attack(targets, rate, duration) log.Println("Done!") log.Printf("Writing results to '%s'...", output) if err := results.Encode(out); err != nil { return err } return nil }
func main() { rps := flag.Uint64("r", 100, "rate: request per second") duration := flag.Int64("t", 5, "duration in seconds") flag.Parse() args := flag.Args() if len(args) == 0 { fmt.Println("goab [options] url") flag.Usage() return } cmd := "GET " + args[len(args)-1] fmt.Printf("Latency for [%s]\n%s\n", cmd, strings.Repeat("-", 40)) targets, _ := vegeta.NewTargets([]string{cmd}) results := vegeta.Attack(targets, *rps, time.Second*time.Duration(*duration)) metrics := vegeta.NewMetrics(results) fmt.Printf("%8s: %15s\n", "mean", metrics.Latencies.Mean) fmt.Printf("%8s: %15s\n", "max", metrics.Latencies.Max) fmt.Printf("%8s: %15s\n", "95%", metrics.Latencies.P95) fmt.Printf("%8s: %15s\n", "99%", metrics.Latencies.P99) }
func main() { var ( rate = flag.Uint64("rate", 50, "Requests per second") targetsf = flag.String("targets", "targets.txt", "Targets file") ordering = flag.String("ordering", "random", "Attack ordering [sequential, random]") duration = flag.Duration("duration", 10*time.Second, "Duration of the test") reporter = flag.String("reporter", "text", "Reporter to use [text, plot:timings]") output = flag.String("output", "stdout", "Reporter output file") ) flag.Parse() if flag.NFlag() == 0 { flag.Usage() return } if *rate == 0 { log.Fatal("rate can't be zero") } targets, err := vegeta.NewTargetsFromFile(*targetsf) if err != nil { log.Fatal(err) } switch *ordering { case "random": targets.Shuffle(time.Now().UnixNano()) case "sequential": break default: log.Fatalf("Unknown ordering %s", *ordering) } if *duration == 0 { log.Fatal("Duration provided is invalid") } var rep vegeta.Reporter switch *reporter { case "text": rep = vegeta.NewTextReporter() case "plot:timings": rep = vegeta.NewTimingsPlotReporter() default: log.Println("Reporter provided is not supported. using text") rep = vegeta.NewTextReporter() } var out io.Writer switch *output { case "stdout": out = os.Stdout default: file, err := os.Create(*output) if err != nil { log.Fatalf("Couldn't open `%s` for writing report: %s", *output, err) } defer file.Close() out = file } log.Printf("Vegeta is attacking %d targets in %s order for %s...\n", len(targets), *ordering, *duration) vegeta.Attack(targets, *rate, *duration, rep) log.Println("Done!") log.Printf("Writing report to '%s'...", *output) if rep.Report(out) != nil { log.Println("Failed to report!") } }