Skip to content

Commit

Permalink
Merge #58023
Browse files Browse the repository at this point in the history
58023: pprofui: allow ?seconds to be passed to heap, goroutine, etc r=knz a=tbg

In Go [1.15], the pprof http handlers got a new feature:

    All profile endpoints now support a "seconds" parameter. When present,
    the endpoint profiles for the specified number of seconds and reports
    the difference. The meaning of the "seconds" parameter in the cpu
    profile and the trace endpoints is unchanged.

This is now available via the pprofui as well. For discoverability,
a link has been added to the debug section of the console which I
expect to see a fair bit of usage: a 5s history of allocation counts.
Previously, we were only able to look at the lifetime allocation
counts or the currently actively referenced objects. But my feeling
is that we care a lot more about which parts of the code are allocation
heavy at any given moment in time, which is something the endpoints now
provide. Previously, one would have had to take two consecutive
profiles, and use the `-base` option to [pprof].

[1.15]: https://golang.org/doc/go1.15
[pprof]: https://github.com/google/pprof/blob/master/doc/README.md

Release note(ui change): The advanced debug section's `pprofui` links now support the `?seconds=x` parameter throughout.


Co-authored-by: Tobias Grieger <[email protected]>
  • Loading branch information
craig[bot] and tbg committed Dec 17, 2020
2 parents eda9189 + 74459e0 commit f4ab896
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 24 deletions.
44 changes: 20 additions & 24 deletions pkg/server/debug/pprofui/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,33 +65,29 @@ func NewServer(storage Storage, hook func(profile string, labels bool, do func()
hook: hook,
}

s.profileTypes = map[string]http.HandlerFunc{
// The CPU profile endpoint is special in that the handler actually blocks
// for a predetermined duration (recording the profile in the meantime).
// It is not included in `runtimepprof.Profiles` below.
"profile": func(w http.ResponseWriter, r *http.Request) {
const defaultProfileDurationSeconds = 5
if r.Form == nil {
r.Form = url.Values{}
}
if r.Form.Get("seconds") == "" {
r.Form.Set("seconds", strconv.Itoa(defaultProfileDurationSeconds))
}
s.profileSem.Lock()
defer s.profileSem.Unlock()
pprof.Profile(w, r)
},
}

// Register the endpoints for heap, block, threadcreate, etc.
s.profileTypes = map[string]http.HandlerFunc{}
for _, p := range runtimepprof.Profiles() {
p := p // copy
s.profileTypes[p.Name()] = func(w http.ResponseWriter, r *http.Request) {
if err := p.WriteTo(w, 0 /* debug */); err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
}
name := p.Name()
s.profileTypes[name] = func(w http.ResponseWriter, r *http.Request) {
pprof.Handler(name).ServeHTTP(w, r)
}
}
// The CPU profile endpoint is special cased because a) it's not in the map
// yet and b) it always needs to block. We want to default to 5s if profiling
// if nothing is specified, we use a convenience mutex to serialize concurrent
// attempts to get a profile (the endpoint otherwise returns an error).
s.profileTypes["profile"] = func(w http.ResponseWriter, r *http.Request) {
const defaultProfileDurationSeconds = 5
if r.Form == nil {
r.Form = url.Values{}
}
if r.Form.Get("seconds") == "" {
r.Form.Set("seconds", strconv.Itoa(defaultProfileDurationSeconds))
}
s.profileSem.Lock()
defer s.profileSem.Unlock()
pprof.Profile(w, r)
}

return s
Expand Down
1 change: 1 addition & 0 deletions pkg/ui/src/views/reports/containers/debug/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ export default function Debug() {
</DebugTableRow>
<DebugTableRow title="Profiling UI/pprof">
<DebugTableLink name="Heap" url="/debug/pprof/ui/heap/" />
<DebugTableLink name="Heap (recent allocs)" url="/debug/pprof/ui/heap/?seconds=5&amp;si=alloc_objects" />
<DebugTableLink name="Profile" url="/debug/pprof/ui/profile/?seconds=5&amp;labels=true" />
<DebugTableLink name="Block" url="/debug/pprof/ui/block/" />
<DebugTableLink name="Mutex" url="/debug/pprof/ui/mutex/" />
Expand Down

0 comments on commit f4ab896

Please sign in to comment.