|
|
|
@ -6,6 +6,7 @@ import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
|
|
|
|
"os"
|
|
|
|
|
"runtime/pprof"
|
|
|
|
|
"strings"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
@ -40,9 +41,13 @@ func wrap(err error, t string, args ...interface{}) error {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type options struct {
|
|
|
|
|
b bool // bzip compression flag
|
|
|
|
|
v bool // verbose flag
|
|
|
|
|
f string // input file
|
|
|
|
|
b bool // bzip compression flag
|
|
|
|
|
v bool // verbose flag
|
|
|
|
|
f string // input file
|
|
|
|
|
memprofile string
|
|
|
|
|
cpuprofile string
|
|
|
|
|
messages bool // dump messages or no
|
|
|
|
|
packets bool // dump packets or no
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (o options) input() (io.Reader, error) {
|
|
|
|
@ -63,19 +68,62 @@ func (o options) input() (io.Reader, error) {
|
|
|
|
|
return r, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func memprofile(dest string) {
|
|
|
|
|
fmt.Println("writing mem profile to", dest)
|
|
|
|
|
w, err := os.Create(dest)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Fprintf(os.Stderr, "unable to open memprofile output %s: %v\n", dest, err)
|
|
|
|
|
} else {
|
|
|
|
|
defer w.Close()
|
|
|
|
|
err := pprof.WriteHeapProfile(w)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Fprintf(os.Stderr, "unable to write heap profile: %v\n", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func cpuprofile(dest string) func() {
|
|
|
|
|
fmt.Println("writing cpu profile to", dest)
|
|
|
|
|
w, err := os.Create(dest)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Fprintf(os.Stderr, "unable to open cpuprofile output %s: %v\n", dest, err)
|
|
|
|
|
return func() {}
|
|
|
|
|
} else {
|
|
|
|
|
pprof.StartCPUProfile(w)
|
|
|
|
|
return func() {
|
|
|
|
|
pprof.StopCPUProfile()
|
|
|
|
|
w.Close()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
var opts options
|
|
|
|
|
flag.BoolVar(&opts.b, "b", false, "input is expected to be bzip-compressed")
|
|
|
|
|
flag.BoolVar(&opts.v, "v", false, "verbose mode")
|
|
|
|
|
flag.StringVar(&opts.f, "f", "--", "input file to be used. -- means stdin")
|
|
|
|
|
flag.BoolVar(&opts.messages, "messages", false, "dump top-level messages to stdout")
|
|
|
|
|
flag.BoolVar(&opts.packets, "packets", false, "dump packets to stdout")
|
|
|
|
|
flag.StringVar(&opts.memprofile, "memprofile", "", "memory profile destination")
|
|
|
|
|
flag.StringVar(&opts.cpuprofile, "cpuprofile", "", "cpu profile destination")
|
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
|
|
if opts.memprofile != "" {
|
|
|
|
|
defer memprofile(opts.memprofile)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if opts.cpuprofile != "" {
|
|
|
|
|
defer cpuprofile(opts.cpuprofile)()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r, err := opts.input()
|
|
|
|
|
if err != nil {
|
|
|
|
|
bail(1, "input error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p := newParser(r)
|
|
|
|
|
p.dumpMessages = opts.messages
|
|
|
|
|
p.dumpPackets = opts.packets
|
|
|
|
|
if err := p.start(); err != nil {
|
|
|
|
|
bail(1, "parse error: %v", err)
|
|
|
|
|
}
|
|
|
|
|