Skip to content

Commit a522070

Browse files
authored
In the tags command, print percentages relative to profile total. (#929)
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 a522070

File tree

8 files changed

+59
-43
lines changed

8 files changed

+59
-43
lines changed

internal/driver/driver_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ func TestParse(t *testing.T) {
9797
{"weblist=line(1000|3000)$,addresses,flat", "cpu"},
9898
{"tags,tagfocus=400kb:", "heap_request"},
9999
{"tags,tagfocus=+400kb:", "heap_request"},
100+
{"tags,relative_percentages,tagfocus=400kb:", "heap_request"},
100101
{"dot", "long_name_funcs"},
101102
{"text", "long_name_funcs"},
102103
}
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
key1: Total 1.1s
2-
1.0s (89.29%): tag1
3-
100.0ms ( 8.93%): tag2
4-
10.0ms ( 0.89%): tag3
5-
10.0ms ( 0.89%): tag4
1+
key1: Total 1.12s of 1.12s ( 100%)
2+
1s (89.29%): tag1
3+
100ms ( 8.93%): tag2
4+
10ms ( 0.89%): tag3
5+
10ms ( 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.02s of 1.12s (91.07%)
8+
1.01s (90.18%): tag1
9+
10ms ( 0.89%): tag2
1010

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

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

4-
key3: Total 100.0ms
5-
100.0ms ( 100%): tag2
4+
key3: Total 100ms of 1.12s ( 8.93%)
5+
100ms ( 8.93%): tag2
66

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
bytes: Total 98.6MB
2-
62.5MB (63.37%): 1.56MB
3-
31.2MB (31.68%): 400kB
4-
3.9MB ( 3.96%): 200kB
5-
1000.0kB ( 0.99%): 100kB
1+
bytes: Total 98.63MB of 98.63MB ( 100%)
2+
62.50MB (63.37%): 1.56MB
3+
31.25MB (31.68%): 400kB
4+
3.91MB ( 3.96%): 200kB
5+
1000kB ( 0.99%): 100kB
66

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
bytes: Total 103424000.0B
2-
65536000.0B (63.37%): 1638400B
3-
32768000.0B (31.68%): 409600B
4-
4096000.0B ( 3.96%): 204800B
5-
1024000.0B ( 0.99%): 102400B
1+
bytes: Total 103424000B of 103424000B ( 100%)
2+
65536000B (63.37%): 1638400B
3+
32768000B (31.68%): 409600B
4+
4096000B ( 3.96%): 204800B
5+
1024000B ( 0.99%): 102400B
66

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
bytes: Total 93.75MB of 93.75MB ( 100%)
2+
62.50MB (66.67%): 1.56MB
3+
31.25MB (33.33%): 400kB
4+
5+
request: Total 93.75MB of 93.75MB ( 100%)
6+
62.50MB (66.67%): 1.56MB
7+
31.25MB (33.33%): 400kB
8+
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
bytes: Total 93.8MB
2-
62.5MB (66.67%): 1.56MB
3-
31.2MB (33.33%): 400kB
1+
bytes: Total 93.75MB of 98.63MB (95.05%)
2+
62.50MB (63.37%): 1.56MB
3+
31.25MB (31.68%): 400kB
44

5-
request: Total 93.8MB
6-
62.5MB (66.67%): 1.56MB
7-
31.2MB (33.33%): 400kB
5+
request: Total 93.75MB of 98.63MB (95.05%)
6+
62.50MB (63.37%): 1.56MB
7+
31.25MB (31.68%): 400kB
88

internal/report/report.go

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -699,21 +699,26 @@ 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+
// Note that we assume single value per tag per sample. Multiple values are
709+
// encodable in the format but are discouraged.
710+
tagTotalMap := make(map[string]int64)
708711
for _, s := range p.Sample {
712+
sampleValue := o.SampleValue(s.Value)
709713
for key, vals := range s.Label {
710714
for _, val := range vals {
711715
valueMap, ok := tagMap[key]
712716
if !ok {
713717
valueMap = make(map[string]int64)
714718
tagMap[key] = valueMap
715719
}
716-
valueMap[val] += o.SampleValue(s.Value)
720+
valueMap[val] += sampleValue
721+
tagTotalMap[key] += sampleValue
717722
}
718723
}
719724
for key, vals := range s.NumLabel {
@@ -725,7 +730,8 @@ func printTags(w io.Writer, rpt *Report) error {
725730
valueMap = make(map[string]int64)
726731
tagMap[key] = valueMap
727732
}
728-
valueMap[val] += o.SampleValue(s.Value)
733+
valueMap[val] += sampleValue
734+
tagTotalMap[key] += sampleValue
729735
}
730736
}
731737
}
@@ -736,22 +742,23 @@ func printTags(w io.Writer, rpt *Report) error {
736742
}
737743
tabw := tabwriter.NewWriter(w, 0, 0, 1, ' ', tabwriter.AlignRight)
738744
for _, tagKey := range graph.SortTags(tagKeys, true) {
739-
var total int64
740745
key := tagKey.Name
741746
tags := make([]*graph.Tag, 0, len(tagMap[key]))
742747
for t, c := range tagMap[key] {
743-
total += c
744748
tags = append(tags, &graph.Tag{Name: t, Flat: c})
745749
}
746750

747-
f, u := measurement.Scale(total, o.SampleUnit, o.OutputUnit)
748-
fmt.Fprintf(tabw, "%s:\t Total %.1f%s\n", key, f, u)
751+
tagTotal, profileTotal := tagTotalMap[key], rpt.Total()
752+
if profileTotal > 0 {
753+
fmt.Fprintf(tabw, "%s:\t Total %s of %s (%s)\n", key, rpt.formatValue(tagTotal), rpt.formatValue(profileTotal), measurement.Percentage(tagTotal, profileTotal))
754+
} else {
755+
fmt.Fprintf(tabw, "%s:\t Total %s of %s\n", key, rpt.formatValue(tagTotal), rpt.formatValue(profileTotal))
756+
}
749757
for _, t := range graph.SortTags(tags, true) {
750-
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)
758+
if profileTotal > 0 {
759+
fmt.Fprintf(tabw, " \t%s (%s):\t %s\n", rpt.formatValue(t.FlatValue()), measurement.Percentage(t.FlatValue(), profileTotal), t.Name)
753760
} else {
754-
fmt.Fprintf(tabw, " \t%.1f%s:\t %s\n", f, u, t.Name)
761+
fmt.Fprintf(tabw, " \t%s:\t %s\n", rpt.formatValue(t.FlatValue()), t.Name)
755762
}
756763
}
757764
fmt.Fprintln(tabw)

0 commit comments

Comments
 (0)