1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package driver
16
17 import (
18 "encoding/json"
19 "html/template"
20 "net/http"
21 "strings"
22
23 "github.com/google/pprof/internal/graph"
24 "github.com/google/pprof/internal/measurement"
25 "github.com/google/pprof/internal/report"
26 )
27
28 type treeNode struct {
29 Name string `json:"n"`
30 FullName string `json:"f"`
31 Cum int64 `json:"v"`
32 CumFormat string `json:"l"`
33 Percent string `json:"p"`
34 Children []*treeNode `json:"c"`
35 }
36
37
38 func (ui *webInterface) flamegraph(w http.ResponseWriter, req *http.Request) {
39
40
41 rpt, errList := ui.makeReport(w, req, []string{"svg"}, func(cfg *config) {
42 cfg.CallTree = true
43 cfg.Trim = false
44 })
45 if rpt == nil {
46 return
47 }
48
49
50 g, config := report.GetDOT(rpt)
51 var nodes []*treeNode
52 nroots := 0
53 rootValue := int64(0)
54 nodeArr := []string{}
55 nodeMap := map[*graph.Node]*treeNode{}
56
57 for _, n := range g.Nodes {
58 v := n.CumValue()
59 fullName := n.Info.PrintableName()
60 node := &treeNode{
61 Name: graph.ShortenFunctionName(fullName),
62 FullName: fullName,
63 Cum: v,
64 CumFormat: config.FormatValue(v),
65 Percent: strings.TrimSpace(measurement.Percentage(v, config.Total)),
66 }
67 nodes = append(nodes, node)
68 if len(n.In) == 0 {
69 nodes[nroots], nodes[len(nodes)-1] = nodes[len(nodes)-1], nodes[nroots]
70 nroots++
71 rootValue += v
72 }
73 nodeMap[n] = node
74
75 nodeArr = append(nodeArr, n.Info.Name)
76 }
77
78 for _, n := range g.Nodes {
79 node := nodeMap[n]
80 for child := range n.Out {
81 node.Children = append(node.Children, nodeMap[child])
82 }
83 }
84
85 rootNode := &treeNode{
86 Name: "root",
87 FullName: "root",
88 Cum: rootValue,
89 CumFormat: config.FormatValue(rootValue),
90 Percent: strings.TrimSpace(measurement.Percentage(rootValue, config.Total)),
91 Children: nodes[0:nroots],
92 }
93
94
95 b, err := json.Marshal(rootNode)
96 if err != nil {
97 http.Error(w, "error serializing flame graph", http.StatusInternalServerError)
98 ui.options.UI.PrintErr(err)
99 return
100 }
101
102 ui.render(w, req, "flamegraph", rpt, errList, config.Labels, webArgs{
103 FlameGraph: template.JS(b),
104 Nodes: nodeArr,
105 })
106 }
107
View as plain text