forked from tsenart/vegeta
-
Notifications
You must be signed in to change notification settings - Fork 0
/
report.go
120 lines (101 loc) · 2.49 KB
/
report.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package main
import (
"flag"
"fmt"
"io"
"os"
"os/signal"
vegeta "github.com/tsenart/vegeta/lib"
)
const reportUsage = `Usage: vegeta report [options] [<file>...]
Outputs a report of attack results.
Arguments:
<file> A file with vegeta attack results encoded with one of
the supported encodings (gob | json | csv) [default: stdin]
Options:
--type Which report type to generate (text | json | hist[buckets]).
[default: text]
--output Output file [default: stdout]
Examples:
echo "GET http://:80" | vegeta attack -rate=10/s > results.gob
echo "GET http://:80" | vegeta attack -rate=100/s | vegeta encode > results.json
vegeta report results.*
`
func reportCmd() command {
fs := flag.NewFlagSet("vegeta report", flag.ExitOnError)
typ := fs.String("type", "text", "Report type to generate [text, json, hist[buckets]]")
output := fs.String("output", "stdout", "Output file")
fs.Usage = func() {
fmt.Fprintln(os.Stderr, reportUsage)
}
return command{fs, func(args []string) error {
fs.Parse(args)
files := fs.Args()
if len(files) == 0 {
files = append(files, "stdin")
}
return report(files, *typ, *output)
}}
}
func report(files []string, typ, output string) error {
if len(typ) < 4 {
return fmt.Errorf("invalid report type: %s", typ)
}
dec, mc, err := decoder(files)
defer mc.Close()
if err != nil {
return err
}
out, err := file(output, true)
if err != nil {
return err
}
defer out.Close()
var (
rep vegeta.Reporter
report vegeta.Report
)
switch typ[:4] {
case "plot":
return fmt.Errorf("The plot reporter has been deprecated and succeeded by the vegeta plot command")
case "text":
var m vegeta.Metrics
rep, report = vegeta.NewTextReporter(&m), &m
case "json":
var m vegeta.Metrics
rep, report = vegeta.NewJSONReporter(&m), &m
case "hist":
if len(typ) < 6 {
return fmt.Errorf("bad buckets: '%s'", typ[4:])
}
var hist vegeta.Histogram
if err := hist.Buckets.UnmarshalText([]byte(typ[4:])); err != nil {
return err
}
rep, report = vegeta.NewHistogramReporter(&hist), &hist
default:
return fmt.Errorf("unknown report type: %q", typ)
}
sigch := make(chan os.Signal, 1)
signal.Notify(sigch, os.Interrupt)
decode:
for {
select {
case <-sigch:
break decode
default:
var r vegeta.Result
if err = dec.Decode(&r); err != nil {
if err == io.EOF {
break decode
}
return err
}
report.Add(&r)
}
}
if c, ok := report.(vegeta.Closer); ok {
c.Close()
}
return rep.Report(out)
}