Skip to content

Commit c1deddd

Browse files
committed
In the tags command, print percentages relative to profile total.
Before this change percentages were relative to the tag total and this sometimes causes confusion for users as it makes it look like the tag is set for all samples when it's not. Note that the percentage calculation as implemented does not attempt to be friendly to samples where a given tag has multiple values. Multiple values per tag per sample are discouraged and we should deprecate them. Maybe we should make pprof print a warning for such profiles.
1 parent fc31438 commit c1deddd

File tree

6 files changed

+34
-23
lines changed

6 files changed

+34
-23
lines changed
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
key1: Total 1.1s
1+
key1: Total 1.1s of 1.1s ( 100%)
22
1.0s (89.29%): tag1
33
100.0ms ( 8.93%): tag2
44
10.0ms ( 0.89%): tag3
55
10.0ms ( 0.89%): tag4
66

7-
key2: Total 1.0s
8-
1.0s (99.02%): tag1
9-
10.0ms ( 0.98%): tag2
7+
key2: Total 1.0s of 1.1s (91.07%)
8+
1.0s (90.18%): tag1
9+
10.0ms ( 0.89%): tag2
1010

11-
key3: Total 100.0ms
12-
100.0ms ( 100%): tag2
11+
key3: Total 100.0ms of 1.1s ( 8.93%)
12+
100.0ms ( 8.93%): tag2
1313

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
key1: Total 100.0ms
1+
key1: Total 100.0ms of 100.0ms ( 100%)
22
100.0ms ( 100%): tag2
33

4-
key3: Total 100.0ms
4+
key3: Total 100.0ms of 100.0ms ( 100%)
55
100.0ms ( 100%): tag2
66

internal/driver/testdata/pprof.heap.tags

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
bytes: Total 98.6MB
1+
bytes: Total 98.6MB of 98.6MB ( 100%)
22
62.5MB (63.37%): 1.56MB
33
31.2MB (31.68%): 400kB
44
3.9MB ( 3.96%): 200kB

internal/driver/testdata/pprof.heap.tags.unit

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
bytes: Total 103424000.0B
1+
bytes: Total 103424000.0B of 103424000.0B ( 100%)
22
65536000.0B (63.37%): 1638400B
33
32768000.0B (31.68%): 409600B
44
4096000.0B ( 3.96%): 204800B
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
bytes: Total 93.8MB
1+
bytes: Total 93.8MB of 93.8MB ( 100%)
22
62.5MB (66.67%): 1.56MB
33
31.2MB (33.33%): 400kB
44

5-
request: Total 93.8MB
5+
request: Total 93.8MB of 93.8MB ( 100%)
66
62.5MB (66.67%): 1.56MB
77
31.2MB (33.33%): 400kB
88

internal/report/report.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -699,21 +699,28 @@ func printTags(w io.Writer, rpt *Report) error {
699699
p := rpt.prof
700700

701701
o := rpt.options
702-
formatTag := func(v int64, key string) string {
703-
return measurement.ScaledLabel(v, key, o.OutputUnit)
702+
formatTag := func(v int64, unit string) string {
703+
return measurement.ScaledLabel(v, unit, o.OutputUnit)
704704
}
705705

706-
// Hashtable to keep accumulate tags as key,value,count.
706+
// Accumulate tags as key,value,count.
707707
tagMap := make(map[string]map[string]int64)
708+
// In the total and residue calculation we assume single value per tag per
709+
// sample. Multiple values are encodable in the format but are discouraged.
710+
tagTotal := make(map[string]int64)
711+
var profileTotal int64
708712
for _, s := range p.Sample {
713+
sampleValue := o.SampleValue(s.Value)
714+
profileTotal += sampleValue
709715
for key, vals := range s.Label {
710716
for _, val := range vals {
711717
valueMap, ok := tagMap[key]
712718
if !ok {
713719
valueMap = make(map[string]int64)
714720
tagMap[key] = valueMap
715721
}
716-
valueMap[val] += o.SampleValue(s.Value)
722+
valueMap[val] += sampleValue
723+
tagTotal[key] += sampleValue
717724
}
718725
}
719726
for key, vals := range s.NumLabel {
@@ -725,7 +732,8 @@ func printTags(w io.Writer, rpt *Report) error {
725732
valueMap = make(map[string]int64)
726733
tagMap[key] = valueMap
727734
}
728-
valueMap[val] += o.SampleValue(s.Value)
735+
valueMap[val] += sampleValue
736+
tagTotal[key] += sampleValue
729737
}
730738
}
731739
}
@@ -735,21 +743,24 @@ func printTags(w io.Writer, rpt *Report) error {
735743
tagKeys = append(tagKeys, &graph.Tag{Name: key})
736744
}
737745
tabw := tabwriter.NewWriter(w, 0, 0, 1, ' ', tabwriter.AlignRight)
746+
fp, up := measurement.Scale(profileTotal, o.SampleUnit, o.OutputUnit)
738747
for _, tagKey := range graph.SortTags(tagKeys, true) {
739-
var total int64
740748
key := tagKey.Name
741749
tags := make([]*graph.Tag, 0, len(tagMap[key]))
742750
for t, c := range tagMap[key] {
743-
total += c
744751
tags = append(tags, &graph.Tag{Name: t, Flat: c})
745752
}
746753

747-
f, u := measurement.Scale(total, o.SampleUnit, o.OutputUnit)
748-
fmt.Fprintf(tabw, "%s:\t Total %.1f%s\n", key, f, u)
754+
f, u := measurement.Scale(tagTotal[tagKey.Name], o.SampleUnit, o.OutputUnit)
755+
if profileTotal > 0 {
756+
fmt.Fprintf(tabw, "%s:\t Total %.1f%s of %.1f%s (%s)\n", key, f, u, fp, up, measurement.Percentage(tagTotal[tagKey.Name], profileTotal))
757+
} else {
758+
fmt.Fprintf(tabw, "%s:\t Total %.1f%s of %.1f%s\n", key, f, u, fp, up)
759+
}
749760
for _, t := range graph.SortTags(tags, true) {
750761
f, u := measurement.Scale(t.FlatValue(), o.SampleUnit, o.OutputUnit)
751-
if total > 0 {
752-
fmt.Fprintf(tabw, " \t%.1f%s (%s):\t %s\n", f, u, measurement.Percentage(t.FlatValue(), total), t.Name)
762+
if profileTotal > 0 {
763+
fmt.Fprintf(tabw, " \t%.1f%s (%s):\t %s\n", f, u, measurement.Percentage(t.FlatValue(), profileTotal), t.Name)
753764
} else {
754765
fmt.Fprintf(tabw, " \t%.1f%s:\t %s\n", f, u, t.Name)
755766
}

0 commit comments

Comments
 (0)