cmd/trace: split large traces into parts

Trace viewer cannot handle traces larger than 256MB (limit on js string size):
https://github.com/catapult-project/catapult/issues/627
And even that is problematic (chrome hangs and crashes).
Split large traces into 100MB parts. Somewhat clumsy, but I don't see any other
solution (other than rewriting trace viewer). At least it works reliably now.

Fixes #15482

Change-Id: I993b5f43d22072c6f5bd041ab5888ce176f272b2
Reviewed-on: https://go-review.googlesource.com/22731
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
This commit is contained in:
Dmitry Vyukov 2016-05-03 16:44:25 +02:00
parent ccf2c01992
commit 7ae273923c
2 changed files with 116 additions and 20 deletions

View file

@ -22,7 +22,9 @@ import (
"bufio"
"flag"
"fmt"
"html/template"
"internal/trace"
"log"
"net"
"net/http"
"os"
@ -76,20 +78,36 @@ func main() {
if err != nil {
dief("failed to create server socket: %v\n", err)
}
// Open browser.
log.Printf("Parsing trace...")
events, err := parseEvents()
if err != nil {
dief("%v\n", err)
}
log.Printf("Serializing trace...")
params := &traceParams{
events: events,
endTime: int64(1<<63 - 1),
}
data := generateTrace(params)
log.Printf("Splitting trace...")
ranges = splitTrace(data)
log.Printf("Opening browser")
if !startBrowser("http://" + ln.Addr().String()) {
fmt.Fprintf(os.Stderr, "Trace viewer is listening on http://%s\n", ln.Addr().String())
}
// Parse and symbolize trace asynchronously while browser opens.
go parseEvents()
// Start http server.
http.HandleFunc("/", httpMain)
err = http.Serve(ln, nil)
dief("failed to start http server: %v\n", err)
}
var ranges []Range
var loader struct {
once sync.Once
events []*trace.Event
@ -118,13 +136,23 @@ func parseEvents() ([]*trace.Event, error) {
// httpMain serves the starting page.
func httpMain(w http.ResponseWriter, r *http.Request) {
w.Write(templMain)
if err := templMain.Execute(w, ranges); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
var templMain = []byte(`
var templMain = template.Must(template.New("").Parse(`
<html>
<body>
<a href="/trace">View trace</a><br>
{{if $}}
{{range $e := $}}
<a href="/trace?start={{$e.Start}}&end={{$e.End}}">View trace ({{$e.Name}})</a><br>
{{end}}
<br>
{{else}}
<a href="/trace">View trace</a><br>
{{end}}
<a href="/goroutines">Goroutine analysis</a><br>
<a href="/io">Network blocking profile</a><br>
<a href="/block">Synchronization blocking profile</a><br>
@ -132,7 +160,7 @@ var templMain = []byte(`
<a href="/sched">Scheduler latency profile</a><br>
</body>
</html>
`)
`))
// startBrowser tries to open the URL in a browser
// and reports whether it succeeds.