diff --git a/README.md b/README.md index aed1637..a81af23 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Usage of vegeta: -ordering="random": Attack ordering [sequential, random] -output="stdout": Reporter output file -rate=50: Requests per second - -reporter="text": Reporter to use [text, plot:timings] + -reporter="text": Reporter to use [text, json, plot:timings] -targets="targets.txt": Targets file ``` @@ -75,6 +75,24 @@ Error Set: Server Timeout Page Not Found ``` +##### -reporter=json +```json +{ + "total_requests": 50, + "total_timing": 34779791, + "mean_timing": 695595, + "total_bytes_in": 272850, + "mean_bytes_in": 5457, + "total_bytes_out": 0, + "mean_bytes_out": 0, + "total_success": 50, + "mean_success": 1, + "status_codes": { + "200": 50 + }, + "errors": [] +} +``` ##### -reporter=plot:timings Plots the request timings in SVG format. ![plot](https://dl.dropboxusercontent.com/u/83217940/plot.svg) diff --git a/lib/metrics.go b/lib/metrics.go index 217f149..a78855f 100644 --- a/lib/metrics.go +++ b/lib/metrics.go @@ -1,35 +1,36 @@ package vegeta import ( + "strconv" "time" ) // Metrics holds the stats computed out of a slice of Results // that is used for some of the Reporters type Metrics struct { - TotalRequests uint64 `json:"total_requests"` - TotalTiming time.Duration `json:"total_timing"` - MeanTiming time.Duration `json:"mean_timing"` - TotalBytesIn uint64 `json:"total_bytes_in"` - MeanBytesIn float64 `json:"mean_bytes_in"` - TotalBytesOut uint64 `json:"total_bytes_out"` - MeanBytesOut float64 `json:"mean_bytes_out"` - TotalSuccess uint64 `json:"total_success"` - MeanSuccess float64 `json:"mean_success"` - StatusCodes map[uint16]uint64 `json:"status_codes"` - Errors []string `json:"errors"` + TotalRequests uint64 `json:"total_requests"` + TotalTiming time.Duration `json:"total_timing"` + MeanTiming time.Duration `json:"mean_timing"` + TotalBytesIn uint64 `json:"total_bytes_in"` + MeanBytesIn float64 `json:"mean_bytes_in"` + TotalBytesOut uint64 `json:"total_bytes_out"` + MeanBytesOut float64 `json:"mean_bytes_out"` + TotalSuccess uint64 `json:"total_success"` + MeanSuccess float64 `json:"mean_success"` + StatusCodes map[string]int `json:"status_codes"` + Errors []string `json:"errors"` } // NewMetrics computes and returns a Metrics struct out of a slice of Results func NewMetrics(results []Result) *Metrics { m := &Metrics{ TotalRequests: uint64(len(results)), - StatusCodes: map[uint16]uint64{}, + StatusCodes: map[string]int{}, } errorSet := map[string]struct{}{} for _, result := range results { - m.StatusCodes[result.Code]++ + m.StatusCodes[strconv.Itoa(int(result.Code))]++ m.TotalTiming += result.Timing m.TotalBytesOut += result.BytesOut m.TotalBytesIn += result.BytesIn diff --git a/lib/reporters.go b/lib/reporters.go index ddfcff5..a7cd30d 100644 --- a/lib/reporters.go +++ b/lib/reporters.go @@ -6,6 +6,7 @@ import ( "code.google.com/p/plotinum/plotutil" "code.google.com/p/plotinum/vg" "code.google.com/p/plotinum/vg/vgsvg" + "encoding/json" "fmt" "io" "text/tabwriter" @@ -41,6 +42,11 @@ func ReportText(results []Result, out io.Writer) error { return w.Flush() } +// ReportJSON writes a computed Metrics struct to out as JSON +func ReportJSON(results []Result, out io.Writer) error { + return json.NewEncoder(out).Encode(NewMetrics(results)) +} + // ReportTimingsPlot builds up a plot of the response times of the requests // in SVG format and writes it to out func ReportTimingsPlot(results []Result, out io.Writer) error { diff --git a/main.go b/main.go index eccd08e..63363f6 100644 --- a/main.go +++ b/main.go @@ -17,7 +17,7 @@ func main() { 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]") + reporter = flag.String("reporter", "text", "Reporter to use [text, json, plot:timings]") output = flag.String("output", "stdout", "Reporter output file") cpus = flag.Int("cpus", runtime.NumCPU(), "Number of CPUs to use") ) @@ -72,6 +72,8 @@ func run(rate uint64, duration time.Duration, targetsf, ordering, reporter, outp switch reporter { case "text": rep = vegeta.ReportText + case "json": + rep = vegeta.ReportJSON case "plot:timings": rep = vegeta.ReportTimingsPlot default: