Example #1
0
// New builds a new report indexing the sample values interpreting the
// samples with the provided function.
func New(prof *profile.Profile, o *Options) *Report {
	format := func(v int64) string {
		if r := o.Ratio; r > 0 && r != 1 {
			fv := float64(v) * r
			v = int64(fv)
		}
		return measurement.ScaledLabel(v, o.SampleUnit, o.OutputUnit)
	}
	return &Report{prof, computeTotal(prof, o.SampleValue, !o.PositivePercentages),
		o, format}
}
Example #2
0
// printDOT prints an annotated callgraph in DOT format.
func printDOT(w io.Writer, rpt *Report) error {
	g, origCount, droppedNodes, droppedEdges := rpt.newTrimmedGraph()
	rpt.selectOutputUnit(g)
	labels := reportLabels(rpt, g, origCount, droppedNodes, droppedEdges, true)

	o := rpt.options
	formatTag := func(v int64, key string) string {
		return measurement.ScaledLabel(v, key, o.OutputUnit)
	}

	c := &graph.DotConfig{
		Title:       rpt.options.Title,
		Labels:      labels,
		FormatValue: rpt.formatValue,
		FormatTag:   formatTag,
		Total:       rpt.total,
	}
	graph.ComposeDot(w, g, &graph.DotAttributes{}, c)
	return nil
}
Example #3
0
// newGraph creates a new graph for this report. If nodes is non-nil,
// only nodes whose info matches are included. Otherwise, all nodes
// are included, without trimming.
func (rpt *Report) newGraph(nodes graph.NodeSet) *graph.Graph {
	o := rpt.options

	// Clean up file paths using heuristics.
	prof := rpt.prof
	for _, f := range prof.Function {
		f.Filename = trimPath(f.Filename)
	}
	// Remove numeric tags not recognized by pprof.
	for _, s := range prof.Sample {
		numLabels := make(map[string][]int64, len(s.NumLabel))
		for k, v := range s.NumLabel {
			if k == "bytes" {
				numLabels[k] = append(numLabels[k], v...)
			}
		}
		s.NumLabel = numLabels
	}

	formatTag := func(v int64, key string) string {
		return measurement.ScaledLabel(v, key, o.OutputUnit)
	}

	gopt := &graph.Options{
		SampleValue:       o.SampleValue,
		SampleMeanDivisor: o.SampleMeanDivisor,
		FormatTag:         formatTag,
		CallTree:          o.CallTree && (o.OutputFormat == Dot || o.OutputFormat == Callgrind),
		DropNegative:      o.DropNegative,
		KeptNodes:         nodes,
	}

	// Only keep binary names for disassembly-based reports, otherwise
	// remove it to allow merging of functions across binaries.
	switch o.OutputFormat {
	case Raw, List, WebList, Dis, Callgrind:
		gopt.ObjNames = true
	}

	return graph.New(rpt.prof, gopt)
}
Example #4
0
// printTags collects all tags referenced in the profile and prints
// them in a sorted table.
func printTags(w io.Writer, rpt *Report) error {
	p := rpt.prof

	o := rpt.options
	formatTag := func(v int64, key string) string {
		return measurement.ScaledLabel(v, key, o.OutputUnit)
	}

	// Hashtable to keep accumulate tags as key,value,count.
	tagMap := make(map[string]map[string]int64)
	for _, s := range p.Sample {
		for key, vals := range s.Label {
			for _, val := range vals {
				if valueMap, ok := tagMap[key]; ok {
					valueMap[val] = valueMap[val] + s.Value[0]
					continue
				}
				valueMap := make(map[string]int64)
				valueMap[val] = s.Value[0]
				tagMap[key] = valueMap
			}
		}
		for key, vals := range s.NumLabel {
			for _, nval := range vals {
				val := formatTag(nval, key)
				if valueMap, ok := tagMap[key]; ok {
					valueMap[val] = valueMap[val] + s.Value[0]
					continue
				}
				valueMap := make(map[string]int64)
				valueMap[val] = s.Value[0]
				tagMap[key] = valueMap
			}
		}
	}

	tagKeys := make([]*graph.Tag, 0, len(tagMap))
	for key := range tagMap {
		tagKeys = append(tagKeys, &graph.Tag{Name: key})
	}
	for _, tagKey := range graph.SortTags(tagKeys, true) {
		var total int64
		key := tagKey.Name
		tags := make([]*graph.Tag, 0, len(tagMap[key]))
		for t, c := range tagMap[key] {
			total += c
			tags = append(tags, &graph.Tag{Name: t, Flat: c})
		}

		fmt.Fprintf(w, "%s: Total %d\n", key, total)
		for _, t := range graph.SortTags(tags, true) {
			if total > 0 {
				fmt.Fprintf(w, "  %8d (%s): %s\n", t.FlatValue(),
					percentage(t.FlatValue(), total), t.Name)
			} else {
				fmt.Fprintf(w, "  %8d: %s\n", t.FlatValue(), t.Name)
			}
		}
		fmt.Fprintln(w)
	}
	return nil
}