diff --git a/plugins/inputs/procstat/filter.go b/plugins/inputs/procstat/filter.go index d182d6bc8708f..13a09d004d996 100644 --- a/plugins/inputs/procstat/filter.go +++ b/plugins/inputs/procstat/filter.go @@ -14,17 +14,21 @@ import ( type Filter struct { Name string `toml:"name"` PidFiles []string `toml:"pid_files"` - Patterns []string `toml:"patterns"` - Users []string `toml:"users"` - CGroups []string `toml:"cgroups"` SystemdUnits []string `toml:"systemd_units"` SupervisorUnits []string `toml:"supervisor_units"` WinService []string `toml:"win_services"` + CGroups []string `toml:"cgroups"` + Patterns []string `toml:"patterns"` + Users []string `toml:"users"` + Executables []string `toml:"executables"` + ProcessNames []string `toml:"process_names"` RecursionDepth int `toml:"recursion_depth"` + filterSupervisorUnit string filterCmds []*regexp.Regexp filterUser filter.Filter - filterSupervisorUnit string + filterExecutable filter.Filter + filterProcessName filter.Filter } func (f *Filter) Init() error { @@ -63,11 +67,18 @@ func (f *Filter) Init() error { f.filterCmds = append(f.filterCmds, re) } + f.filterSupervisorUnit = strings.TrimSpace(strings.Join(f.SupervisorUnits, " ")) + var err error if f.filterUser, err = filter.Compile(f.Users); err != nil { - return fmt.Errorf("compiling users of filter %q failed: %w", f.Name, err) + return fmt.Errorf("compiling users filter for %q failed: %w", f.Name, err) + } + if f.filterExecutable, err = filter.Compile(f.Executables); err != nil { + return fmt.Errorf("compiling executables filter for %q failed: %w", f.Name, err) + } + if f.filterProcessName, err = filter.Compile(f.ProcessNames); err != nil { + return fmt.Errorf("compiling process-names filter for %q failed: %w", f.Name, err) } - f.filterSupervisorUnit = strings.TrimSpace(strings.Join(f.SupervisorUnits, " ")) return nil } @@ -122,12 +133,22 @@ func (f *Filter) ApplyFilter() ([]processGroup, error) { for _, p := range g.processes { // Users if f.filterUser != nil { - username, err := p.Username() - if err != nil { - // This can happen if we don't have permissions or the process no longer exists + if username, err := p.Username(); err != nil || !f.filterUser.Match(username) { + // Errors can happen if we don't have permissions or the process no longer exists + continue + } + } + + // Executables + if f.filterExecutable != nil { + if exe, err := p.Exe(); err != nil || !f.filterExecutable.Match(exe) { continue } - if !f.filterUser.Match(username) { + } + + // Process names + if f.filterProcessName != nil { + if name, err := p.Name(); err != nil || !f.filterProcessName.Match(name) { continue } } diff --git a/plugins/inputs/procstat/procstat.go b/plugins/inputs/procstat/procstat.go index 49245d417d4c0..fdbed339f4281 100644 --- a/plugins/inputs/procstat/procstat.go +++ b/plugins/inputs/procstat/procstat.go @@ -292,6 +292,11 @@ func (p *Procstat) gatherNew(acc telegraf.Accumulator) error { for _, g := range groups { count += len(g.processes) for _, gp := range g.processes { + // Skip over non-running processes + if running, err := gp.IsRunning(); err != nil || !running { + continue + } + // Use the cached processes as we need the existing instances // to compute delta-metrics (e.g. cpu-usage). pid := PID(gp.Pid) diff --git a/plugins/inputs/procstat/sample.conf b/plugins/inputs/procstat/sample.conf index dd8be789379f6..39a5a31a4f3ec 100644 --- a/plugins/inputs/procstat/sample.conf +++ b/plugins/inputs/procstat/sample.conf @@ -69,6 +69,10 @@ # # patterns = ['.*'] # ## List of users owning the process (wildcards are supported) # # users = ['*'] + # ## List of executable paths of the process (wildcards are supported) + # # executables = ['*'] + # ## List of process names (wildcards are supported) + # # process_names = ['*'] # ## Recursion depth for determining children of the matched processes # ## A negative value means all children with infinite depth # #recursion_depth = 0