Ejemplo n.º 1
0
func runWithOptions(allOpts *options, remaining []string) error {
	pprofRawOutput, err := pprof.GetRaw(allOpts.PProfOptions, remaining)
	if err != nil {
		return fmt.Errorf("could not get raw output from pprof: %v", err)
	}

	callStacks, err := pprof.ParseRaw(pprofRawOutput)
	if err != nil {
		return fmt.Errorf("could not parse raw pprof output: %v", err)
	}

	flameInput, err := renderer.ToFlameInput(callStacks)
	if err != nil {
		return fmt.Errorf("could not convert stacks to flamegraph input: %v", err)
	}

	opts := allOpts.OutputOpts
	if opts.Raw {
		torchlog.Print("Printing raw flamegraph input to stdout")
		fmt.Printf("%s\n", flameInput)
		return nil
	}

	var flameGraphArgs = buildFlameGraphArgs(opts)
	flameGraph, err := renderer.GenerateFlameGraph(flameInput, flameGraphArgs...)
	if err != nil {
		return fmt.Errorf("could not generate flame graph: %v", err)
	}

	if opts.Print {
		torchlog.Print("Printing svg to stdout")
		fmt.Printf("%s\n", flameGraph)
		return nil
	}

	torchlog.Printf("Writing svg to %v", opts.File)
	if err := ioutil.WriteFile(opts.File, flameGraph, 0666); err != nil {
		return fmt.Errorf("could not write output file: %v", err)
	}

	return nil
}
Ejemplo n.º 2
0
func runPProf(args ...string) ([]byte, error) {
	allArgs := []string{"tool", "pprof", "-raw"}
	allArgs = append(allArgs, args...)

	var buf bytes.Buffer
	torchlog.Printf("Run pprof command: go %v", strings.Join(allArgs, " "))
	cmd := exec.Command("go", allArgs...)
	cmd.Stderr = &buf
	out, err := cmd.Output()
	if err != nil {
		return nil, fmt.Errorf("pprof error: %v\nSTDERR:\n%s", err, buf.Bytes())
	}

	// @HACK because 'go tool pprof' doesn't exit on errors with nonzero status codes.
	// Ironically, this means that Go's own os/exec package does not detect its errors.
	// See issue here https://github.com/golang/go/issues/11510
	if len(out) == 0 {
		return nil, fmt.Errorf("pprof error:\n%s", buf.Bytes())
	}

	return out, nil
}