Rename profile package to pprof

Address pr feedback, rename profile package to pprof to more accurately
describe its purpose. Adds gc param for heap lookup profiles.
This commit is contained in:
Drew Bailey
2019-12-19 11:41:55 -05:00
parent 1776458956
commit 549045fcbb
9 changed files with 78 additions and 72 deletions

View File

@@ -16,7 +16,7 @@ import (
log "github.com/hashicorp/go-hclog"
"github.com/hashicorp/nomad/acl"
cstructs "github.com/hashicorp/nomad/client/structs"
"github.com/hashicorp/nomad/command/agent/profile"
"github.com/hashicorp/nomad/command/agent/pprof"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/hashicorp/serf/serf"
"github.com/mitchellh/copystructure"
@@ -341,11 +341,11 @@ func (s *HTTPServer) AgentPprofRequest(resp http.ResponseWriter, req *http.Reque
// no root index route
return nil, CodedError(404, ErrInvalidMethod)
case "cmdline":
return s.agentPprof(profile.CmdReq, resp, req)
return s.agentPprof(pprof.CmdReq, resp, req)
case "profile":
return s.agentPprof(profile.CPUReq, resp, req)
return s.agentPprof(pprof.CPUReq, resp, req)
case "trace":
return s.agentPprof(profile.TraceReq, resp, req)
return s.agentPprof(pprof.TraceReq, resp, req)
default:
// Add profile to request
values := req.URL.Query()
@@ -353,26 +353,20 @@ func (s *HTTPServer) AgentPprofRequest(resp http.ResponseWriter, req *http.Reque
req.URL.RawQuery = values.Encode()
// generic pprof profile request
return s.agentPprof(profile.LookupReq, resp, req)
return s.agentPprof(pprof.LookupReq, resp, req)
}
}
func (s *HTTPServer) agentPprof(reqType profile.ReqType, resp http.ResponseWriter, req *http.Request) ([]byte, error) {
var secret string
s.parseToken(req, &secret)
func (s *HTTPServer) agentPprof(reqType pprof.ReqType, resp http.ResponseWriter, req *http.Request) ([]byte, error) {
// Parse profile duration, default to 1 second
var err error
secondsParam := req.URL.Query().Get("seconds")
var seconds int
if secondsParam == "" {
// Parse query param int values
seconds, _ := strconv.Atoi(req.URL.Query().Get("seconds"))
debug, _ := strconv.Atoi(req.URL.Query().Get("debug"))
gc, _ := strconv.Atoi(req.URL.Query().Get("gc"))
// default to 1 second
if seconds == 0 {
seconds = 1
} else {
seconds, err = strconv.Atoi(secondsParam)
if err != nil {
errStr := fmt.Sprintf("Error parsing seconds parameter %s", secondsParam)
return nil, CodedError(400, errStr)
}
}
// Create the request
@@ -380,6 +374,8 @@ func (s *HTTPServer) agentPprof(reqType profile.ReqType, resp http.ResponseWrite
NodeID: req.URL.Query().Get("node_id"),
Profile: req.URL.Query().Get("profile"),
ServerID: req.URL.Query().Get("server_id"),
Debug: debug,
GC: gc,
ReqType: reqType,
Seconds: seconds,
}

View File

@@ -1,10 +1,16 @@
package profile
// Package profile is meant to be a near identical implemenation of
// https://golang.org/src/net/http/pprof/pprof.go
// It's purpose is to provide a way to accommodate the RPC endpoint style
// we use instead of traditional http handlers.
package pprof
import (
"bytes"
"context"
"fmt"
"os"
"runtime"
"runtime/pprof"
"runtime/trace"
"strings"
@@ -17,7 +23,7 @@ const (
CmdReq ReqType = "cmdline"
CPUReq ReqType = "cpu"
TraceReq ReqType = "trace"
LookupReq ReqType = "profile"
LookupReq ReqType = "lookup"
ErrProfileNotFoundPrefix = "Pprof profile not found profile:"
)
@@ -49,12 +55,16 @@ func Cmdline() ([]byte, map[string]string, error) {
// Profile generates a pprof.Profile report for the given profile name
// see runtime/pprof/pprof.go for available profiles.
func Profile(profile string, debug int) ([]byte, map[string]string, error) {
func Profile(profile string, debug, gc int) ([]byte, map[string]string, error) {
p := pprof.Lookup(profile)
if p == nil {
return nil, nil, NewErrProfileNotFound(profile)
}
if profile == "heap" && gc > 0 {
runtime.GC()
}
var buf bytes.Buffer
if err := p.WriteTo(&buf, debug); err != nil {
return nil, nil, err

View File

@@ -1,4 +1,4 @@
package profile
package pprof
import (
"context"
@@ -12,6 +12,7 @@ func TestProfile(t *testing.T) {
desc string
profile string
debug int
gc int
expectedHeaders map[string]string
expectedErr error
}{
@@ -43,7 +44,7 @@ func TestProfile(t *testing.T) {
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
resp, headers, err := Profile(tc.profile, tc.debug)
resp, headers, err := Profile(tc.profile, tc.debug, tc.gc)
require.Equal(t, tc.expectedHeaders, headers)
if tc.expectedErr != nil {