func main() { flag.Parse() var serviceIP string ips, err := net.LookupIP(*host) if err != nil { fmt.Printf("Error looking up %s: %v\n", *host, err) os.Exit(2) } for _, ip := range ips { ipv4 := ip.To4() if ipv4 != nil { serviceIP = ipv4.String() break } } if len(serviceIP) == 0 { fmt.Printf("Failed to find suitable IP address: %v", ips) os.Exit(2) } host := serviceIP if *port != 80 { host = fmt.Sprintf("%s:%d", host, port) } var targets []vegeta.Target for _, path := range strings.Split(*paths, ",") { path = strings.TrimPrefix(path, "/") targets = append(targets, vegeta.Target{ Method: "GET", URL: fmt.Sprintf("http://%s/%s", host, path), }) } targeter := vegeta.NewStaticTargeter(targets...) attacker := vegeta.NewAttacker(vegeta.Workers(uint64(*workers))) reporter := &HTTPReporter{} go http.ListenAndServe(*addr, reporter) for { metrics := &vegeta.Metrics{} for res := range attacker.Attack(targeter, uint64(*rate), *duration) { metrics.Add(res) } metrics.Close() reporter.SetMetrics(metrics) } }
func main() { flag.Parse() var serviceIP string ips, err := net.LookupIP(*host) if err != nil { fmt.Printf("Error looking up %s: %v\n", *host, err) os.Exit(2) } for _, ip := range ips { ipv4 := ip.To4() if ipv4 != nil { serviceIP = ipv4.String() break } } if len(serviceIP) == 0 { fmt.Printf("Failed to find suitable IP address: %v", ips) os.Exit(2) } targeter := vegeta.NewStaticTargeter(vegeta.Target{ Method: "GET", URL: "http://" + serviceIP + "/", }) attacker := vegeta.NewAttacker(vegeta.Workers(uint64(*workers))) reporter := &HTTPReporter{} go http.ListenAndServe(*addr, reporter) for { metrics := &vegeta.Metrics{} for res := range attacker.Attack(targeter, uint64(*rate), *duration) { metrics.Add(res) } metrics.Close() reporter.SetMetrics(metrics) } }
// attack validates the attack arguments, sets up the // required resources, launches the attack and writes the results func attack(opts *attackOpts) (err error) { if opts.rate == 0 { return errZeroRate } if opts.duration == 0 { return errZeroDuration } files := map[string]io.Reader{} for _, filename := range []string{opts.targetsf, opts.bodyf, opts.certf} { if filename == "" { continue } f, err := file(filename, false) if err != nil { return fmt.Errorf("error opening %s: %s", filename, err) } defer f.Close() files[filename] = f } var body []byte if bodyf, ok := files[opts.bodyf]; ok { if body, err = ioutil.ReadAll(bodyf); err != nil { return fmt.Errorf("error reading %s: %s", opts.bodyf, err) } } var ( tr vegeta.Targeter src = files[opts.targetsf] hdr = opts.headers.Header ) if opts.lazy { tr = vegeta.NewLazyTargeter(src, body, hdr) } else if tr, err = vegeta.NewEagerTargeter(src, body, hdr); err != nil { return err } out, err := file(opts.outputf, true) if err != nil { return fmt.Errorf("error opening %s: %s", opts.outputf, err) } defer out.Close() var cert []byte if certf, ok := files[opts.certf]; ok { if cert, err = ioutil.ReadAll(certf); err != nil { return fmt.Errorf("error reading %s: %s", opts.certf, err) } } tlsc := *vegeta.DefaultTLSConfig if opts.certf != "" { if tlsc.RootCAs, err = certPool(cert); err != nil { return err } } atk := vegeta.NewAttacker( vegeta.Redirects(opts.redirects), vegeta.Timeout(opts.timeout), vegeta.LocalAddr(*opts.laddr.IPAddr), vegeta.TLSConfig(&tlsc), vegeta.Workers(opts.workers), vegeta.KeepAlive(opts.keepalive), vegeta.Connections(opts.connections), ) res := atk.Attack(tr, opts.rate, opts.duration) enc := vegeta.NewEncoder(out) sig := make(chan os.Signal, 1) signal.Notify(sig, os.Interrupt) for { select { case <-sig: atk.Stop() return nil case r, ok := <-res: if !ok { return nil } if err = enc.Encode(r); err != nil { return err } } } }