Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vegeta plot command #317

Merged
merged 34 commits into from
Aug 14, 2018
Merged
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
c8e7de8
report: Downsample time series in plot reporter
tsenart Jul 13, 2018
40f7924
vendor: Add github.com/dgryski/go-lttb
tsenart Jul 13, 2018
cf9f116
reporters: Elide unecessary type conversions
tsenart Jul 13, 2018
435185e
reporters: Fix incorrect allocation optimisation
tsenart Jul 13, 2018
0d2e7f7
plot: Introduce vegeta plot command
tsenart Jul 14, 2018
e1a4f38
plot: Highcharts and streaming refactoring WIP
tsenart Jul 18, 2018
d21bc64
git: Add *.gob and *.lz to .gitignore
tsenart Jul 19, 2018
f9995df
plot: Revert back to Dygraphs
tsenart Jul 21, 2018
15bec40
lttb: Implement on-line version of the LTTB algorithm
tsenart Jul 25, 2018
05d47cf
lttb: Fix LTTB bucketing and add better tests
tsenart Jul 29, 2018
4be48a3
lttb: Move to independent package
tsenart Aug 11, 2018
b274d1f
attack: Same order of timestamps and seq numbers
tsenart Aug 11, 2018
bcddd8a
plot: Buffering logic
tsenart Aug 11, 2018
6b1a62d
lttb: Checkin
tsenart Aug 11, 2018
cbb1581
lttb: Improve Iter comment
tsenart Aug 12, 2018
f3fb801
plot: Rename attackSeries to labeledSeries
tsenart Aug 12, 2018
eacb7a8
plot: Ensure timestamp monotonicity
tsenart Aug 12, 2018
f63b43a
plot: HTMLPlotOpts
tsenart Aug 12, 2018
c9b9ae4
plot: Move to independent package
tsenart Aug 12, 2018
48ba0db
plot: Rename BenchmarkHTMLPlot
tsenart Aug 12, 2018
df544bc
plot: TestLabeledSeries
tsenart Aug 12, 2018
24703ba
plot: Golden test for plot output
tsenart Aug 13, 2018
ca99fe5
plot: Update Dygraphs and HTML2Canvas
tsenart Aug 13, 2018
e19fc14
plot: Use github.com/tsenart/go-tsz
tsenart Aug 13, 2018
0992b8e
Update .gitignore
tsenart Aug 13, 2018
449e551
targets: Simplify generation code
tsenart Aug 13, 2018
8a24986
plot: Update README and add examples
tsenart Aug 13, 2018
52b6595
plot: Improve TestLabeledSeries
tsenart Aug 13, 2018
0754549
README: Update Plot image url
tsenart Aug 13, 2018
b294ddb
plot: Update golden file
tsenart Aug 13, 2018
dd2ea0d
plot: Deterministic WriteTo output
tsenart Aug 13, 2018
65989a8
Merge branch 'master' into plot-reporter-downsampling
tsenart Aug 13, 2018
055ddc6
plot: Add missing assets
tsenart Aug 13, 2018
9388665
Update deps
tsenart Aug 14, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 53 additions & 32 deletions lib/reporters.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import (
"encoding/json"
"fmt"
"io"
"sort"
"strconv"
"strings"
"text/tabwriter"

lttb "github.com/dgryski/go-lttb"
"github.com/lucasb-eyer/go-colorful"
)

Expand Down Expand Up @@ -109,51 +111,70 @@ func NewJSONReporter(m *Metrics) Reporter {
// http://dygraphs.com/
func NewPlotReporter(title string, rs *Results) Reporter {
return func(w io.Writer) (err error) {
_, err = fmt.Fprintf(w, plotsTemplateHead, title, asset(dygraphs), asset(html2canvas))
if err != nil {
return err
series := make(map[string][]Results, len(*rs))
for _, r := range *rs {
idx := 0
if r.Error == "" {
idx++
}

if len(series[r.Attack]) == 0 {
series[r.Attack] = make([]Results, 2)
}

series[r.Attack][idx] = append(series[r.Attack][idx], r)
}

attacks := make(map[string]Results, len(*rs))
for _, r := range *rs {
attacks[r.Attack] = append(attacks[r.Attack], r)
samples := make(map[string][][]lttb.Point, len(series))
for attack, results := range series {
for i := range results {
sort.Sort(results[i])
points := make([]lttb.Point, 0, len(results[i]))
for _, r := range results[i] {
points = append(points, lttb.Point{
X: float64(r.Timestamp.Sub(results[i][0].Timestamp).Seconds()),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unnecessary conversion

Y: float64(r.Latency.Seconds() * 1000),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unnecessary conversion

})
}
samples[attack] = append(samples[attack], lttb.LTTB(points, 1000))
}
}

const series = 2 // OK and Errors
i, offsets := 0, make(map[string]int, len(attacks))
for attack := range attacks {
offsets[attack] = 1 + i*series
const count = 2 // OK and Errors
i, offsets := 0, make(map[string]int, len(series))
for name := range series {
offsets[name] = 1 + i*count
i++
}

const nan = "NaN"

data := make([]string, 1+len(attacks)*series)
for attack, results := range attacks {
for i, r := range results {
for j := range data {
data[j] = nan
}
_, err = fmt.Fprintf(w, plotsTemplateHead, title, asset(dygraphs), asset(html2canvas))
if err != nil {
return err
}

offset := offsets[attack]
if r.Error == "" {
offset++
}
const nan = "NaN"

ts := r.Timestamp.Sub(results[0].Timestamp).Seconds()
data[0] = strconv.FormatFloat(ts, 'f', -1, 32)
data := make([]string, 1+len(series)*count)
for attack, results := range samples {
for idx, points := range results {
for i, p := range points {
for j := range data {
data[j] = nan
}

latency := r.Latency.Seconds() * 1000
data[offset] = strconv.FormatFloat(latency, 'f', -1, 32)
offset := offsets[attack] + idx
data[0] = strconv.FormatFloat(p.X, 'f', -1, 32)
data[offset] = strconv.FormatFloat(p.Y, 'f', -1, 32)

s := "[" + strings.Join(data, ",") + "]"
s := "[" + strings.Join(data, ",") + "]"

if i < len(*rs)-1 {
s += ","
}
if i < len(*rs)-1 {
s += ","
}

if _, err = io.WriteString(w, s); err != nil {
return err
if _, err = io.WriteString(w, s); err != nil {
return err
}
}
}
}
Expand Down