From c7c0ca719610d8473bea438eae4f23c1d715366f Mon Sep 17 00:00:00 2001 From: k1LoW Date: Thu, 19 Sep 2019 17:31:22 +0900 Subject: [PATCH] Add `--group.exclude` option for exclude group name using regexp --- cmd/root.go | 2 ++ go.mod | 3 ++- go.sum | 6 +++-- grouper/cgroup/cgroup.go | 18 +++++++++++++ grouper/cgroup/cgroup_test.go | 24 +++++++++++++++++ grouper/grouper.go | 1 + grouper/proc_status_name/proc_status_name.go | 18 +++++++++++++ .../proc_status_name/proc_status_name_test.go | 27 +++++++++++++++++++ 8 files changed, 96 insertions(+), 3 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index b378023..6a2c67a 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -47,6 +47,7 @@ var ( endpoint string groupType string nReStr string + eReStr string collectStat bool collectIO bool @@ -157,6 +158,7 @@ func init() { rootCmd.Flags().StringVarP(&endpoint, "telemetry.endpoint", "", "/metrics", "Path under which to expose metrics.") rootCmd.Flags().StringVarP(&groupType, "group.type", "", "cgroup", "Grouping type.") rootCmd.Flags().StringVarP(&nReStr, "group.normalize", "", "", "Regexp for normalize group names. Exporter use regexp match result $1 as group name.") + rootCmd.Flags().StringVarP(&eReStr, "group.exclude", "", "", "Regexp for exclude group names. Exporter exclude group using regexp match before group name normalization") rootCmd.Flags().BoolVarP(&collectStat, "collector.stat", "", false, "Enable collecting /proc/[PID]/stat.") rootCmd.Flags().BoolVarP(&collectIO, "collector.io", "", false, "Enable collecting /proc/[PID]/io.") diff --git a/go.mod b/go.mod index fe67c97..65fdafd 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/prometheus/procfs v0.0.5 github.com/sirupsen/logrus v1.4.2 github.com/spf13/cobra v0.0.5 - golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 // indirect + github.com/spf13/pflag v1.0.5 // indirect + golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect ) diff --git a/go.sum b/go.sum index 95787cc..d285669 100644 --- a/go.sum +++ b/go.sum @@ -91,6 +91,8 @@ github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tL github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -113,8 +115,8 @@ golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1cHUZgO1Ebq5r2hIjfo= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13 h1:/zi0zzlPHWXYXrO1LjNRByFu8sdGgCkj2JLDdBIB84k= +golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= diff --git a/grouper/cgroup/cgroup.go b/grouper/cgroup/cgroup.go index d2913ce..5b00982 100644 --- a/grouper/cgroup/cgroup.go +++ b/grouper/cgroup/cgroup.go @@ -35,6 +35,7 @@ var Subsystems = []string{ type Cgroup struct { fsPath string nRe *regexp.Regexp + eRe *regexp.Regexp } func (c *Cgroup) Name() string { @@ -56,6 +57,11 @@ func (c *Cgroup) Collect(gprocs *grouped_proc.GroupedProcs, enabled map[metric.M } if f.IsDir() { cPath := strings.Replace(path, searchDir, "", 1) + if c.eRe != nil { + if c.eRe.MatchString(cPath) { + return nil + } + } if c.nRe != nil { matches := c.nRe.FindStringSubmatch(cPath) if len(matches) > 1 { @@ -128,6 +134,18 @@ func (c *Cgroup) SetNormalizeRegexp(nReStr string) error { return nil } +func (c *Cgroup) SetExcludeRegexp(eReStr string) error { + if eReStr == "" { + return nil + } + eRe, err := regexp.Compile(eReStr) + if err != nil { + return err + } + c.eRe = eRe + return nil +} + // NewCgroup func NewCgroup(fsPath string) *Cgroup { return &Cgroup{ diff --git a/grouper/cgroup/cgroup_test.go b/grouper/cgroup/cgroup_test.go index 9ed2d50..e7ff4a7 100644 --- a/grouper/cgroup/cgroup_test.go +++ b/grouper/cgroup/cgroup_test.go @@ -60,6 +60,30 @@ func TestCollectWithNormalize(t *testing.T) { } } +func TestCollectWithExclude(t *testing.T) { + cgroup := testCgroup() + err := cgroup.SetExcludeRegexp("my.+") + if err != nil { + t.Fatalf("%v", err) + } + gprocs := grouped_proc.NewGroupedProcs() + enabled := make(map[metric.MetricKey]bool) + + enabled[metric.ProcIO] = true + enabled[metric.ProcStat] = true + err = cgroup.Collect(gprocs, enabled) + if err != nil { + t.Fatalf("%v", err) + } + + if gprocs.Length() != 1 { + t.Errorf("want %d, got %d", 1, gprocs.Length()) + } + if _, ok := gprocs.Load("/system.slice/nginx.service"); !ok { + t.Errorf("want %s, got none", "/system.slice/nginx.service") + } +} + func testCgroup() *Cgroup { os.Setenv("GROUPED_PROCESS_PROC_MOUNT_POINT", testProcPath) return NewCgroup(testCgroupPath) diff --git a/grouper/grouper.go b/grouper/grouper.go index 213db57..bc66699 100644 --- a/grouper/grouper.go +++ b/grouper/grouper.go @@ -8,5 +8,6 @@ import ( type Grouper interface { Name() string SetNormalizeRegexp(nReStr string) error + SetExcludeRegexp(eReStr string) error Collect(gprocs *grouped_proc.GroupedProcs, enabled map[metric.MetricKey]bool) error } diff --git a/grouper/proc_status_name/proc_status_name.go b/grouper/proc_status_name/proc_status_name.go index 9ed56d3..25b6a96 100644 --- a/grouper/proc_status_name/proc_status_name.go +++ b/grouper/proc_status_name/proc_status_name.go @@ -13,6 +13,7 @@ import ( type ProcStatusName struct { nRe *regexp.Regexp + eRe *regexp.Regexp procMountPoint string } @@ -44,6 +45,11 @@ func (g *ProcStatusName) Collect(gprocs *grouped_proc.GroupedProcs, enabled map[ pid := proc.PID name := status.Name + if g.eRe != nil { + if g.eRe.MatchString(name) { + continue + } + } if g.nRe != nil { matches := g.nRe.FindStringSubmatch(name) if len(matches) > 1 { @@ -85,6 +91,18 @@ func (g *ProcStatusName) SetNormalizeRegexp(nReStr string) error { return nil } +func (g *ProcStatusName) SetExcludeRegexp(eReStr string) error { + if eReStr == "" { + return nil + } + eRe, err := regexp.Compile(eReStr) + if err != nil { + return err + } + g.eRe = eRe + return nil +} + // NewProcStatusName func NewProcStatusName() *ProcStatusName { procMountPoint := os.Getenv("GROUPED_PROCESS_PROC_MOUNT_POINT") diff --git a/grouper/proc_status_name/proc_status_name_test.go b/grouper/proc_status_name/proc_status_name_test.go index e8fc2fd..6db054a 100644 --- a/grouper/proc_status_name/proc_status_name_test.go +++ b/grouper/proc_status_name/proc_status_name_test.go @@ -62,6 +62,33 @@ func TestCollectWithNormalize(t *testing.T) { } } +func TestCollectWithExclude(t *testing.T) { + procStatusName := testProcStatusName() + err := procStatusName.SetExcludeRegexp("my.+") + if err != nil { + t.Fatalf("%v", err) + } + gprocs := grouped_proc.NewGroupedProcs() + enabled := make(map[metric.MetricKey]bool) + + enabled[metric.ProcIO] = true + enabled[metric.ProcStat] = true + err = procStatusName.Collect(gprocs, enabled) + if err != nil { + t.Fatalf("%v", err) + } + + if gprocs.Length() != 1 { + t.Errorf("want %d, got %d", 1, gprocs.Length()) + } + if _, ok := gprocs.Load("nginx"); !ok { + t.Errorf("want %s, got none", "nginx") + } + if _, ok := gprocs.Load("mysqld"); ok { + t.Errorf("want nont, got %s", "mysqld") + } +} + func testProcStatusName() *ProcStatusName { os.Setenv("GROUPED_PROCESS_PROC_MOUNT_POINT", testProcPath) return NewProcStatusName()