Skip to content

[cherry-pick] feat(cmd/debuginfo) add new metrics to be collected #7562

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 18 additions & 22 deletions dgraph/cmd/debuginfo/pprof.go → dgraph/cmd/debuginfo/debugging.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,7 @@ import (
"github.com/golang/glog"
)

var pprofProfileTypes = []string{
"goroutine",
"heap",
"threadcreate",
"block",
"mutex",
"profile",
"trace",
}

func saveProfiles(addr, pathPrefix string, duration time.Duration, profiles []string) {
func saveMetrics(addr, pathPrefix string, seconds uint32, metricTypes []string) {
u, err := url.Parse(addr)
if err != nil || (u.Host == "" && u.Scheme != "" && u.Scheme != "file") {
u, err = url.Parse("http://" + addr)
Expand All @@ -49,27 +39,33 @@ func saveProfiles(addr, pathPrefix string, duration time.Duration, profiles []st
return
}

for _, profileType := range profiles {
source := fmt.Sprintf("%s/debug/pprof/%s?duration=%d", u.String(),
profileType, int(duration.Seconds()))
savePath := fmt.Sprintf("%s%s.gz", pathPrefix, profileType)
duration := time.Duration(seconds) * time.Second

if err := saveProfile(source, savePath, duration); err != nil {
glog.Errorf("error while saving pprof profile from %s: %s", source, err)
for _, metricType := range metricTypes {
source := u.String() + metricMap[metricType]
switch metricType {
case "cpu":
source += fmt.Sprintf("%s%d", "?seconds=", seconds)
case "trace":
source += fmt.Sprintf("%s%d", "?seconds=", seconds)
}
savePath := fmt.Sprintf("%s%s.gz", pathPrefix, metricType)
if err := saveDebug(source, savePath, duration); err != nil {
glog.Errorf("error while saving metric from %s: %s", source, err)
continue
}

glog.Infof("saving %s profile in %s", profileType, savePath)
glog.Infof("saving %s metric in %s", metricType, savePath)
}
}

// saveProfile writes the profile specified in the argument fetching it from the host
// saveDebug writes the debug info specified in the argument fetching it from the host
// provided in the configuration
func saveProfile(sourceURL, filePath string, duration time.Duration) error {
func saveDebug(sourceURL, filePath string, duration time.Duration) error {
var err error
var resp io.ReadCloser

glog.Infof("fetching profile over HTTP from %s", sourceURL)
glog.Infof("fetching information over HTTP from %s", sourceURL)
if duration > 0 {
glog.Info(fmt.Sprintf("please wait... (%v)", duration))
}
Expand All @@ -83,7 +79,7 @@ func saveProfile(sourceURL, filePath string, duration time.Duration) error {
defer resp.Close()
out, err := os.Create(filePath)
if err != nil {
return fmt.Errorf("error while creating profile dump file: %s", err)
return fmt.Errorf("error while creating debug file: %s", err)
}
_, err = io.Copy(out, resp)
return err
Expand Down
69 changes: 51 additions & 18 deletions dgraph/cmd/debuginfo/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,57 @@ import (
"io/ioutil"
"os"
"path/filepath"
"time"

"github.com/dgraph-io/dgraph/x"
"github.com/golang/glog"
"github.com/spf13/cobra"
)

type debugInfoCmdOpts struct {
alphaAddr string
zeroAddr string
archive bool
directory string
duration uint32

pprofProfiles []string
alphaAddr string
zeroAddr string
archive bool
directory string
seconds uint32
metricTypes []string
}

var (
DebugInfo x.SubCommand
debugInfoCmd = debugInfoCmdOpts{}
)

var metricMap = map[string]string{
"jemalloc": "/jemalloc",
"state": "/state",
"health": "/health",
"vars": "/debug/vars",
"metrics": "/metrics",
"heap": "/debug/pprof/heap",
"goroutine": "/debug/pprof/goroutine?debug=2",
"threadcreate": "/debug/pprof/threadcreate",
"block": "/debug/pprof/block",
"mutex": "/debug/pprof/mutex",
"cpu": "/debug/pprof/profile",
"trace": "/debug/pprof/trace",
}

var metricList = []string{
"heap",
"cpu",
"state",
"health",
"jemalloc",
"trace",
"metrics",
"vars",
"trace",
"goroutine",
"block",
"mutex",
"threadcreate",
}

func init() {
DebugInfo.Cmd = &cobra.Command{
Use: "debuginfo",
Expand All @@ -54,6 +83,7 @@ func init() {
}
},
}

DebugInfo.EnvPrefix = "DGRAPH_AGENT_DEBUGINFO"

flags := DebugInfo.Cmd.Flags()
Expand All @@ -64,10 +94,11 @@ func init() {
"Directory to write the debug info into.")
flags.BoolVarP(&debugInfoCmd.archive, "archive", "x", true,
"Whether to archive the generated report")
flags.Uint32VarP(&debugInfoCmd.duration, "seconds", "s", 15,
"Duration for time-based profile collection.")
flags.StringSliceVarP(&debugInfoCmd.pprofProfiles, "profiles", "p", pprofProfileTypes,
"List of pprof profiles to dump in the report.")
flags.Uint32VarP(&debugInfoCmd.seconds, "seconds", "s", 30,
"Duration for time-based metric collection.")
flags.StringSliceVarP(&debugInfoCmd.metricTypes, "metrics", "m", metricList,
"List of metrics & profile to dump in the report.")

}

func collectDebugInfo() (err error) {
Expand All @@ -84,25 +115,27 @@ func collectDebugInfo() (err error) {
}
glog.Infof("using directory %s for debug info dump.", debugInfoCmd.directory)

collectPProfProfiles()
collectDebug()

if debugInfoCmd.archive {
return archiveDebugInfo()
}
return nil
}

func collectPProfProfiles() {
duration := time.Duration(debugInfoCmd.duration) * time.Second

func collectDebug() {
if debugInfoCmd.alphaAddr != "" {
filePrefix := filepath.Join(debugInfoCmd.directory, "alpha_")
saveProfiles(debugInfoCmd.alphaAddr, filePrefix, duration, debugInfoCmd.pprofProfiles)

saveMetrics(debugInfoCmd.alphaAddr, filePrefix, debugInfoCmd.seconds, debugInfoCmd.metricTypes)

}

if debugInfoCmd.zeroAddr != "" {
filePrefix := filepath.Join(debugInfoCmd.directory, "zero_")
saveProfiles(debugInfoCmd.zeroAddr, filePrefix, duration, debugInfoCmd.pprofProfiles)

saveMetrics(debugInfoCmd.zeroAddr, filePrefix, debugInfoCmd.seconds, debugInfoCmd.metricTypes)

}
}

Expand Down