diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 48e6ae3b6060..720a2fc22ae4 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -125,6 +125,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix a rate limit related issue in httpjson input for Okta module. {issue}18530[18530] {pull}18534[18534] - Fix tls mapping in suricata module {issue}19492[19492] {pull}19494[19494] - Fix Cisco ASA dissect pattern for 313008 & 313009 messages. {pull}19149[19149] +- Fix bug with empty filter values in system/service {pull}19812[19812] *Heartbeat* diff --git a/metricbeat/module/system/service/dbus.go b/metricbeat/module/system/service/dbus.go index 621129221364..c3c5bf1dc418 100644 --- a/metricbeat/module/system/service/dbus.go +++ b/metricbeat/module/system/service/dbus.go @@ -139,33 +139,43 @@ func listUnitsWrapper(conn *dbus.Conn, states, patterns []string) ([]dbus.UnitSt if err != nil { return nil, errors.Wrap(err, "ListUnits error") } - if len(patterns) > 0 { - units, err = matchUnitPatterns(patterns, units) - if err != nil { - return nil, errors.Wrap(err, "error matching unit patterns") - } + + units, err = matchUnitPatterns(patterns, units) + if err != nil { + return nil, errors.Wrap(err, "error matching unit patterns") } - if len(states) > 0 { - var finalUnits []dbus.UnitStatus - for _, unit := range units { - for _, state := range states { - if unit.LoadState == state || unit.ActiveState == state || unit.SubState == state { - finalUnits = append(finalUnits, unit) - break - } + finalUnits := matchUnitState(states, units) + + return finalUnits, nil +} + +// matchUnitState returns a list of units that match the pattern list +// This checks the LoadState, ActiveState, and SubState for a matching status string +func matchUnitState(states []string, units []dbus.UnitStatus) []dbus.UnitStatus { + if len(states) == 0 { + return units + } + var finalUnits []dbus.UnitStatus + for _, unit := range units { + for _, state := range states { + if unit.LoadState == state || unit.ActiveState == state || unit.SubState == state { + finalUnits = append(finalUnits, unit) + break } } - return finalUnits, nil } + return finalUnits - return units, nil } // matchUnitPatterns returns a list of units that match the pattern list. // This algo, including filepath.Match, is designed to (somewhat) emulate the behavior of ListUnitsByPatterns, which uses `fnmatch`. func matchUnitPatterns(patterns []string, units []dbus.UnitStatus) ([]dbus.UnitStatus, error) { var matchUnits []dbus.UnitStatus + if len(patterns) == 0 { + return units, nil + } for _, unit := range units { for _, pattern := range patterns { match, err := filepath.Match(pattern, unit.Name) diff --git a/metricbeat/module/system/service/service_test.go b/metricbeat/module/system/service/service_test.go index 10549f81c747..87581ff45f81 100644 --- a/metricbeat/module/system/service/service_test.go +++ b/metricbeat/module/system/service/service_test.go @@ -31,10 +31,12 @@ import ( var exampleUnits = []dbus.UnitStatus{ dbus.UnitStatus{ - Name: "sshd.service", + Name: "sshd.service", + LoadState: "active", }, dbus.UnitStatus{ - Name: "metricbeat.service", + Name: "metricbeat.service", + LoadState: "active", }, dbus.UnitStatus{ Name: "filebeat.service", @@ -104,3 +106,23 @@ func TestFilterMatches(t *testing.T) { assert.NoError(t, err) assert.Len(t, shouldMatch, 1) } + +func TestNoFilter(t *testing.T) { + shouldReturnResults, err := matchUnitPatterns([]string{}, exampleUnits) + assert.NoError(t, err) + assert.Len(t, shouldReturnResults, 3) +} + +func TestUnitStateFilter(t *testing.T) { + stateFilter := []string{ + "active", + } + shouldReturnResults := matchUnitState(stateFilter, exampleUnits) + assert.Len(t, shouldReturnResults, 2) + +} + +func TestUnitStateNoFilter(t *testing.T) { + shouldReturnResults := matchUnitState([]string{}, exampleUnits) + assert.Len(t, shouldReturnResults, 3) +}