feat(plugins/inputs/systemd_units): add pattern support (#9665)
This commit is contained in:
parent
1a59157b91
commit
4dc2967e34
|
|
@ -1,7 +1,7 @@
|
||||||
# systemd Units Input Plugin
|
# systemd Units Input Plugin
|
||||||
|
|
||||||
The systemd_units plugin gathers systemd unit status on Linux. It relies on
|
The systemd_units plugin gathers systemd unit status on Linux. It relies on
|
||||||
`systemctl list-units --all --plain --type=service` to collect data on service status.
|
`systemctl list-units [PATTERN] --all --plain --type=service` to collect data on service status.
|
||||||
|
|
||||||
The results are tagged with the unit name and provide enumerated fields for
|
The results are tagged with the unit name and provide enumerated fields for
|
||||||
loaded, active and running fields, indicating the unit health.
|
loaded, active and running fields, indicating the unit health.
|
||||||
|
|
@ -22,6 +22,13 @@ see `systemctl list-units --all --type help` for possible options.
|
||||||
## values are "socket", "target", "device", "mount", "automount", "swap",
|
## values are "socket", "target", "device", "mount", "automount", "swap",
|
||||||
## "timer", "path", "slice" and "scope ":
|
## "timer", "path", "slice" and "scope ":
|
||||||
# unittype = "service"
|
# unittype = "service"
|
||||||
|
#
|
||||||
|
## Filter for a specific pattern, default is "" (i.e. all), other possible
|
||||||
|
## values are valid pattern for systemctl, e.g. "a*" for all units with
|
||||||
|
## names starting with "a"
|
||||||
|
# pattern = ""
|
||||||
|
## pattern = "telegraf* influxdb*"
|
||||||
|
## pattern = "a*"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Metrics
|
### Metrics
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,11 @@ import (
|
||||||
type SystemdUnits struct {
|
type SystemdUnits struct {
|
||||||
Timeout config.Duration
|
Timeout config.Duration
|
||||||
UnitType string `toml:"unittype"`
|
UnitType string `toml:"unittype"`
|
||||||
|
Pattern string `toml:"pattern"`
|
||||||
systemctl systemctl
|
systemctl systemctl
|
||||||
}
|
}
|
||||||
|
|
||||||
type systemctl func(timeout config.Duration, unitType string) (*bytes.Buffer, error)
|
type systemctl func(timeout config.Duration, unitType string, pattern string) (*bytes.Buffer, error)
|
||||||
|
|
||||||
const measurement = "systemd_units"
|
const measurement = "systemd_units"
|
||||||
|
|
||||||
|
|
@ -115,6 +116,7 @@ var subMap = map[string]int{
|
||||||
var (
|
var (
|
||||||
defaultTimeout = config.Duration(time.Second)
|
defaultTimeout = config.Duration(time.Second)
|
||||||
defaultUnitType = "service"
|
defaultUnitType = "service"
|
||||||
|
defaultPattern = ""
|
||||||
)
|
)
|
||||||
|
|
||||||
// Description returns a short description of the plugin
|
// Description returns a short description of the plugin
|
||||||
|
|
@ -132,12 +134,19 @@ func (s *SystemdUnits) SampleConfig() string {
|
||||||
## values are "socket", "target", "device", "mount", "automount", "swap",
|
## values are "socket", "target", "device", "mount", "automount", "swap",
|
||||||
## "timer", "path", "slice" and "scope ":
|
## "timer", "path", "slice" and "scope ":
|
||||||
# unittype = "service"
|
# unittype = "service"
|
||||||
|
#
|
||||||
|
## Filter for a specific pattern, default is "" (i.e. all), other possible
|
||||||
|
## values are valid pattern for systemctl, e.g. "a*" for all units with
|
||||||
|
## names starting with "a"
|
||||||
|
# pattern = ""
|
||||||
|
## pattern = "telegraf* influxdb*"
|
||||||
|
## pattern = "a*"
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gather parses systemctl outputs and adds counters to the Accumulator
|
// Gather parses systemctl outputs and adds counters to the Accumulator
|
||||||
func (s *SystemdUnits) Gather(acc telegraf.Accumulator) error {
|
func (s *SystemdUnits) Gather(acc telegraf.Accumulator) error {
|
||||||
out, err := s.systemctl(s.Timeout, s.UnitType)
|
out, err := s.systemctl(s.Timeout, s.UnitType, s.Pattern)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -192,22 +201,32 @@ func (s *SystemdUnits) Gather(acc telegraf.Accumulator) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setSystemctl(timeout config.Duration, unitType string) (*bytes.Buffer, error) {
|
func setSystemctl(timeout config.Duration, unitType string, pattern string) (*bytes.Buffer, error) {
|
||||||
// is systemctl available ?
|
// is systemctl available ?
|
||||||
systemctlPath, err := exec.LookPath("systemctl")
|
systemctlPath, err := exec.LookPath("systemctl")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// build parameters for systemctl call
|
||||||
cmd := exec.Command(systemctlPath, "list-units", "--all", "--plain", fmt.Sprintf("--type=%s", unitType), "--no-legend")
|
params := []string{"list-units"}
|
||||||
|
// create patterns parameters if provided in config
|
||||||
|
if pattern != "" {
|
||||||
|
psplit := strings.SplitN(pattern, " ", -1)
|
||||||
|
for v := range psplit {
|
||||||
|
params = append(params, psplit[v])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
params = append(params, "--all", "--plain")
|
||||||
|
// add type as configured in config
|
||||||
|
params = append(params, fmt.Sprintf("--type=%s", unitType))
|
||||||
|
params = append(params, "--no-legend")
|
||||||
|
cmd := exec.Command(systemctlPath, params...)
|
||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
cmd.Stdout = &out
|
cmd.Stdout = &out
|
||||||
err = internal.RunTimeout(cmd, time.Duration(timeout))
|
err = internal.RunTimeout(cmd, time.Duration(timeout))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &out, fmt.Errorf("error running systemctl list-units --all --plain --type=%s --no-legend: %s", unitType, err)
|
return &out, fmt.Errorf("error running systemctl %s: %s", strings.Join(params, " "), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &out, nil
|
return &out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -217,6 +236,7 @@ func init() {
|
||||||
systemctl: setSystemctl,
|
systemctl: setSystemctl,
|
||||||
Timeout: defaultTimeout,
|
Timeout: defaultTimeout,
|
||||||
UnitType: defaultUnitType,
|
UnitType: defaultUnitType,
|
||||||
|
Pattern: defaultPattern,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ func TestSystemdUnits(t *testing.T) {
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
systemdUnits := &SystemdUnits{
|
systemdUnits := &SystemdUnits{
|
||||||
systemctl: func(timeout config.Duration, unitType string) (*bytes.Buffer, error) {
|
systemctl: func(timeout config.Duration, unitType string, pattern string) (*bytes.Buffer, error) {
|
||||||
return bytes.NewBufferString(tt.line), nil
|
return bytes.NewBufferString(tt.line), nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue