Selaa lähdekoodia

Merge pull request #33 from rauls5382/tagshow

Add tagshow/taghide commands to select a subset of tags in a profile
Josef Jelinek 8 vuotta sitten
vanhempi
commit
7dfb5e832b

+ 6
- 1
internal/driver/commands.go Näytä tiedosto

@@ -199,7 +199,12 @@ var pprofVariables = variables{
199 199
 	"tagignore": &variable{stringKind, "", "", helpText(
200 200
 		"Discard samples with tags in range or matched by regexp",
201 201
 		"Discard samples that do include a node with a tag matching this regexp.")},
202
-
202
+	"tagshow": &variable{stringKind, "", "", helpText(
203
+		"Only consider tags matching this regexp",
204
+		"Discard tags that do not match this regexp")},
205
+	"taghide": &variable{stringKind, "", "", helpText(
206
+		"Skip tags matching this regexp",
207
+		"Discard tags that match this regexp")},
203 208
 	// Heap profile options
204 209
 	"divide_by": &variable{floatKind, "1", "", helpText(
205 210
 		"Ratio to divide all samples before visualization",

+ 6
- 0
internal/driver/driver_focus.go Näytä tiedosto

@@ -50,6 +50,12 @@ func applyFocus(prof *profile.Profile, v variables, ui plugin.UI) error {
50 50
 	warnNoMatches(tagfocus == nil || tfm, "TagFocus", ui)
51 51
 	warnNoMatches(tagignore == nil || tim, "TagIgnore", ui)
52 52
 
53
+	tagshow, err := compileRegexOption("tagshow", v["tagshow"].value, err)
54
+	taghide, err := compileRegexOption("taghide", v["taghide"].value, err)
55
+	tns, tnh := prof.FilterTagsByName(tagshow, taghide)
56
+	warnNoMatches(tagshow == nil || tns, "TagShow", ui)
57
+	warnNoMatches(tagignore == nil || tnh, "TagHide", ui)
58
+
53 59
 	if prunefrom != nil {
54 60
 		prof.PruneFrom(prunefrom)
55 61
 	}

+ 1
- 1
internal/symbolizer/symbolizer.go Näytä tiedosto

@@ -292,7 +292,7 @@ func newMapping(prof *profile.Profile, obj plugin.ObjTool, ui plugin.UI, force b
292 292
 			missingBinaries = true
293 293
 			continue
294 294
 		}
295
-		
295
+
296 296
 		// Skip well-known system mappings
297 297
 		name := filepath.Base(m.File)
298 298
 		if name == "[vdso]" || strings.HasPrefix(name, "linux-vdso") {

+ 30
- 0
profile/filter.go Näytä tiedosto

@@ -73,6 +73,36 @@ func (p *Profile) FilterSamplesByName(focus, ignore, hide, show *regexp.Regexp)
73 73
 	return
74 74
 }
75 75
 
76
+// FilterTagsByName filters the tags in a profile and only keeps
77
+// tags that match show and not hide.
78
+func (p *Profile) FilterTagsByName(show, hide *regexp.Regexp) (sm, hm bool) {
79
+	matchRemove := func(name string) bool {
80
+		matchShow := show == nil || show.MatchString(name)
81
+		matchHide := hide != nil && hide.MatchString(name)
82
+
83
+		if matchShow {
84
+			sm = true
85
+		}
86
+		if matchHide {
87
+			hm = true
88
+		}
89
+		return !matchShow || matchHide
90
+	}
91
+	for _, s := range p.Sample {
92
+		for lab := range s.Label {
93
+			if matchRemove(lab) {
94
+				delete(s.Label, lab)
95
+			}
96
+		}
97
+		for lab := range s.NumLabel {
98
+			if matchRemove(lab) {
99
+				delete(s.NumLabel, lab)
100
+			}
101
+		}
102
+	}
103
+	return
104
+}
105
+
76 106
 // matchesName returns whether the location matches the regular
77 107
 // expression. It checks any available function names, file names, and
78 108
 // mapping object filename.

+ 43
- 0
profile/profile_test.go Näytä tiedosto

@@ -507,6 +507,49 @@ func TestFilter(t *testing.T) {
507 507
 	}
508 508
 }
509 509
 
510
+func TestTagFilter(t *testing.T) {
511
+     // Perform several forms of tag filtering on the test profile.
512
+
513
+	type filterTestcase struct {
514
+		include, exclude *regexp.Regexp
515
+		im, em bool
516
+		count int
517
+	}
518
+
519
+	countTags := func (p *Profile) map[string]bool {
520
+		  tags := make(map[string]bool)
521
+
522
+		  for _, s := range p.Sample {
523
+		      for l := range s.Label {
524
+		      	  tags[l] = true
525
+		      }		      
526
+		      for l := range s.NumLabel {
527
+		      	  tags[l] = true
528
+		      }		      
529
+		  }
530
+		  return tags
531
+	}	
532
+	
533
+	for tx, tc := range []filterTestcase{
534
+		{nil, nil, true, false, 3},
535
+		{regexp.MustCompile("notfound"), nil, false, false, 0},
536
+		{regexp.MustCompile("key1"), nil, true, false, 1},
537
+		{nil, regexp.MustCompile("key[12]"), true, true, 1},
538
+	} {
539
+		prof := testProfile.Copy()
540
+		gim, gem := prof.FilterTagsByName(tc.include, tc.exclude)
541
+		if  gim != tc.im {
542
+			t.Errorf("Filter #%d, got include match=%v, want %v", tx, gim, tc.im)
543
+		}		
544
+		if  gem != tc.em {
545
+			t.Errorf("Filter #%d, got exclude match=%v, want %v", tx, gem, tc.em)
546
+		}		
547
+		if  tags := countTags(prof) ; len(tags) != tc.count {
548
+			t.Errorf("Filter #%d, got %d tags[%v], want %d", tx, len(tags), tags, tc.count)
549
+		}		
550
+	}
551
+}
552
+
510 553
 // locationHash constructs a string to use as a hashkey for a sample, based on its locations
511 554
 func locationHash(s *Sample) string {
512 555
 	var tb string