-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #100 from tsenart/dump-cmd
Dump cmd
- Loading branch information
Showing
5 changed files
with
160 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package main | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"io" | ||
"os" | ||
"os/signal" | ||
"strings" | ||
|
||
vegeta "github.com/tsenart/vegeta/lib" | ||
) | ||
|
||
func dumpCmd() command { | ||
fs := flag.NewFlagSet("vegeta dump", flag.ExitOnError) | ||
dumper := fs.String("dumper", "", "Dumper [json, csv]") | ||
inputs := fs.String("inputs", "stdin", "Input files (comma separated)") | ||
output := fs.String("output", "stdout", "Output file") | ||
return command{fs, func(args []string) error { | ||
fs.Parse(args) | ||
return dump(*dumper, *inputs, *output) | ||
}} | ||
} | ||
|
||
func dump(dumper, inputs, output string) error { | ||
dump, ok := dumpers[dumper] | ||
if !ok { | ||
return fmt.Errorf("unsupported dumper: %s", dumper) | ||
} | ||
|
||
files := strings.Split(inputs, ",") | ||
srcs := make([]io.Reader, len(files)) | ||
for i, f := range files { | ||
in, err := file(f, false) | ||
if err != nil { | ||
return err | ||
} | ||
defer in.Close() | ||
srcs[i] = in | ||
} | ||
|
||
out, err := file(output, true) | ||
if err != nil { | ||
return err | ||
} | ||
defer out.Close() | ||
|
||
sig := make(chan os.Signal, 1) | ||
signal.Notify(sig, os.Interrupt) | ||
res, errs := vegeta.Collect(srcs...) | ||
|
||
for { | ||
select { | ||
case _ = <-sig: | ||
return nil | ||
case r, ok := <-res: | ||
if !ok { | ||
return nil | ||
} | ||
dmp, err := dump.Dump(r) | ||
if err != nil { | ||
return err | ||
} else if _, err = out.Write(dmp); err != nil { | ||
return err | ||
} | ||
case err, ok := <-errs: | ||
if !ok { | ||
return nil | ||
} | ||
return err | ||
} | ||
} | ||
} | ||
|
||
var dumpers = map[string]vegeta.Dumper{ | ||
"csv": vegeta.DumpCSV, | ||
"json": vegeta.DumpJSON, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package vegeta | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
) | ||
|
||
// Dumper is an interface defining Results dumping. | ||
type Dumper interface { | ||
Dump(*Result) ([]byte, error) | ||
} | ||
|
||
// DumperFunc is an adapter to allow the use of ordinary functions as | ||
// Dumpers. If f is a function with the appropriate signature, DumperFunc(f) | ||
// is a Dumper object that calls f. | ||
type DumperFunc func(*Result) ([]byte, error) | ||
|
||
func (f DumperFunc) Dump(r *Result) ([]byte, error) { return f(r) } | ||
|
||
// DumpCSV dumps a Result as a CSV record with six columns. | ||
// The columns are: unix timestamp in ns since epoch, http status code, | ||
// request latency in ns, bytes out, bytes in, and lastly the error. | ||
var DumpCSV DumperFunc = func(r *Result) ([]byte, error) { | ||
var buf bytes.Buffer | ||
_, err := fmt.Fprintf(&buf, "%d,%d,%d,%d,%d,'%s'\n", | ||
r.Timestamp.UnixNano(), | ||
r.Code, | ||
r.Latency.Nanoseconds(), | ||
r.BytesOut, | ||
r.BytesIn, | ||
r.Error, | ||
) | ||
return buf.Bytes(), err | ||
} | ||
|
||
// DumpJSON dumps a Result as a JSON object. | ||
var DumpJSON DumperFunc = func(r *Result) ([]byte, error) { | ||
var buf bytes.Buffer | ||
err := json.NewEncoder(&buf).Encode(r) | ||
return buf.Bytes(), err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters