mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 18:35:44 +03:00
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:
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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 {
|
||||
Reference in New Issue
Block a user