Пример #1
0
// greetings prints a brief welcome and some overall profile
// information before accepting interactive commands.
func greetings(p *profile.Profile, ui plugin.UI) {
	ropt, err := reportOptions(p, pprofVariables)
	if err == nil {
		ui.Print(strings.Join(report.ProfileLabels(report.New(p, ropt)), "\n"))
	}
	ui.Print("Entering interactive mode (type \"help\" for commands, \"o\" for options)")
}
Пример #2
0
func printCurrentOptions(p *profile.Profile, ui plugin.UI) {
	var args []string
	type groupInfo struct {
		set    string
		values []string
	}
	groups := make(map[string]*groupInfo)
	for n, o := range pprofVariables {
		v := o.stringValue()
		comment := ""
		if g := o.group; g != "" {
			gi, ok := groups[g]
			if !ok {
				gi = &groupInfo{}
				groups[g] = gi
			}
			if o.boolValue() {
				gi.set = n
			}
			gi.values = append(gi.values, n)
			continue
		}
		switch {
		case n == "sample_index":
			st := sampleTypes(p)
			if v == "" {
				// Apply default (last sample index).
				v = st[len(st)-1]
			}
			// Add comments for all sample types in profile.
			comment = "[" + strings.Join(st, " | ") + "]"
		case n == "source_path":
			continue
		case n == "nodecount" && v == "-1":
			comment = "default"
		case v == "":
			// Add quotes for empty values.
			v = `""`
		}
		if comment != "" {
			comment = commentStart + " " + comment
		}
		args = append(args, fmt.Sprintf("  %-25s = %-20s %s", n, v, comment))
	}
	for g, vars := range groups {
		sort.Strings(vars.values)
		comment := commentStart + " [" + strings.Join(vars.values, " | ") + "]"
		args = append(args, fmt.Sprintf("  %-25s = %-20s %s", g, vars.set, comment))
	}
	sort.Strings(args)
	ui.Print(strings.Join(args, "\n"))
}
Пример #3
0
// convertPerfData converts the file at path which should be in perf.data format
// using the perf_to_profile tool and returns the file containing the
// profile.proto formatted data.
func convertPerfData(perfPath string, ui plugin.UI) (*os.File, error) {
	ui.Print(fmt.Sprintf(
		"Converting %s to a profile.proto... (May take a few minutes)",
		perfPath))
	profile, err := newTempFile(os.TempDir(), "pprof_", ".pb.gz")
	if err != nil {
		return nil, err
	}
	deferDeleteTempFile(profile.Name())
	cmd := exec.Command("perf_to_profile", perfPath, profile.Name())
	if err := cmd.Run(); err != nil {
		profile.Close()
		return nil, fmt.Errorf("failed to convert perf.data file. Try github.com/google/perf_data_converter: %v", err)
	}
	return profile, nil
}
Пример #4
0
// fetch fetches a profile from source, within the timeout specified,
// producing messages through the ui. It returns the profile and the
// url of the actual source of the profile for remote profiles.
func fetch(source string, duration, timeout time.Duration, ui plugin.UI) (p *profile.Profile, src string, err error) {
	var f io.ReadCloser

	if sourceURL, timeout := adjustURL(source, duration, timeout); sourceURL != "" {
		ui.Print("Fetching profile over HTTP from " + sourceURL)
		if duration > 0 {
			ui.Print(fmt.Sprintf("Please wait... (%v)", duration))
		}
		f, err = fetchURL(sourceURL, timeout)
		src = sourceURL
	} else {
		f, err = os.Open(source)
	}
	if err == nil {
		defer f.Close()
		p, err = profile.Parse(f)
	}
	return
}
Пример #5
0
// commandHelp displays help and usage information for all Commands
// and Variables or a specific Command or Variable.
func commandHelp(args string, ui plugin.UI) {
	if args == "" {
		help := usage(false)
		help = help + `
  :   Clear focus/ignore/hide/tagfocus/tagignore

  type "help <cmd|option>" for more information
`

		ui.Print(help)
		return
	}

	if c := pprofCommands[args]; c != nil {
		ui.Print(c.help(args))
		return
	}

	if v := pprofVariables[args]; v != nil {
		ui.Print(v.help + "\n")
		return
	}

	ui.PrintErr("Unknown command: " + args)
}