mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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:
parent
ccf2c01992
commit
7ae273923c
2 changed files with 116 additions and 20 deletions
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue