Skip to content

Commit

Permalink
Added Glob pattern matching for "Windows Services" plugin (#8575)
Browse files Browse the repository at this point in the history
* Allow glob patterns in config

* Update README

* Move creating filter to init

* Need to explictly call init

Co-authored-by: Bas <[email protected]>
(cherry picked from commit b858eb9)
  • Loading branch information
sspaink authored and ssoroka committed Dec 16, 2020
1 parent 6f32110 commit c7e06a9
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 20 deletions.
3 changes: 2 additions & 1 deletion plugins/inputs/win_services/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ Monitoring some services may require running Telegraf with administrator privile

```toml
[[inputs.win_services]]
## Names of the services to monitor. Leave empty to monitor all the available services on the host
## Names of the services to monitor. Leave empty to monitor all the available services on the host. Globs accepted.
service_names = [
"LanmanServer",
"TermService",
"Win*",
]
```

Expand Down
36 changes: 27 additions & 9 deletions plugins/inputs/win_services/win_services.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"

"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/filter"
"github.com/influxdata/telegraf/plugins/inputs"
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/mgr"
Expand Down Expand Up @@ -78,10 +79,11 @@ func (rmr *MgProvider) Connect() (WinServiceManager, error) {
}

var sampleConfig = `
## Names of the services to monitor. Leave empty to monitor all the available services on the host
## Names of the services to monitor. Leave empty to monitor all the available services on the host. Globs accepted.
service_names = [
"LanmanServer",
"TermService",
"TermService",
"Win*",
]
`

Expand All @@ -93,6 +95,8 @@ type WinServices struct {

ServiceNames []string `toml:"service_names"`
mgrProvider ManagerProvider

servicesFilter filter.Filter
}

type ServiceInfo struct {
Expand All @@ -102,6 +106,16 @@ type ServiceInfo struct {
StartUpMode int
}

func (m *WinServices) Init() error {
var err error
m.servicesFilter, err = filter.NewIncludeExcludeFilter(m.ServiceNames, nil)
if err != nil {
return err
}

return nil
}

func (m *WinServices) Description() string {
return description
}
Expand All @@ -117,7 +131,7 @@ func (m *WinServices) Gather(acc telegraf.Accumulator) error {
}
defer scmgr.Disconnect()

serviceNames, err := listServices(scmgr, m.ServiceNames)
serviceNames, err := m.listServices(scmgr)
if err != nil {
return err
}
Expand Down Expand Up @@ -152,16 +166,20 @@ func (m *WinServices) Gather(acc telegraf.Accumulator) error {
}

// listServices returns a list of services to gather.
func listServices(scmgr WinServiceManager, userServices []string) ([]string, error) {
if len(userServices) != 0 {
return userServices, nil
}

func (m *WinServices) listServices(scmgr WinServiceManager) ([]string, error) {
names, err := scmgr.ListServices()
if err != nil {
return nil, fmt.Errorf("Could not list services: %s", err)
}
return names, nil

var services []string
for _, n := range names {
if m.servicesFilter.Match(n) {
services = append(services, n)
}
}

return services, nil
}

// collectServiceInfo gathers info about a service.
Expand Down
13 changes: 11 additions & 2 deletions plugins/inputs/win_services/win_services_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ func TestList(t *testing.T) {
require.NoError(t, err)
defer scmgr.Disconnect()

services, err := listServices(scmgr, KnownServices)
winServices := &WinServices{
ServiceNames: KnownServices,
}
winServices.Init()
services, err := winServices.listServices(scmgr)
require.NoError(t, err)
require.Len(t, services, 2, "Different number of services")
require.Equal(t, services[0], KnownServices[0])
Expand All @@ -38,7 +42,11 @@ func TestEmptyList(t *testing.T) {
require.NoError(t, err)
defer scmgr.Disconnect()

services, err := listServices(scmgr, []string{})
winServices := &WinServices{
ServiceNames: []string{},
}
winServices.Init()
services, err := winServices.listServices(scmgr)
require.NoError(t, err)
require.Condition(t, func() bool { return len(services) > 20 }, "Too few service")
}
Expand All @@ -52,6 +60,7 @@ func TestGatherErrors(t *testing.T) {
ServiceNames: InvalidServices,
mgrProvider: &MgProvider{},
}
ws.Init()
require.Len(t, ws.ServiceNames, 3, "Different number of services")
var acc testutil.Accumulator
require.NoError(t, ws.Gather(&acc))
Expand Down
40 changes: 32 additions & 8 deletions plugins/inputs/win_services/win_services_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,35 +123,50 @@ var testErrors = []testData{
{nil, errors.New("Fake srv query error"), nil, "Fake service 2", "", 0, 0},
{nil, nil, errors.New("Fake srv config error"), "Fake service 3", "", 0, 0},
}},
{nil, nil, nil, []serviceTestInfo{
{[]string{"Fake service 1"}, nil, nil, []serviceTestInfo{
{errors.New("Fake srv open error"), nil, nil, "Fake service 1", "", 0, 0},
}},
}

func TestBasicInfo(t *testing.T) {

winServices := &WinServices{testutil.Logger{}, nil, &FakeMgProvider{testErrors[0]}}
winServices := &WinServices{
Log: testutil.Logger{},
mgrProvider: &FakeMgProvider{testErrors[0]},
}
winServices.Init()
assert.NotEmpty(t, winServices.SampleConfig())
assert.NotEmpty(t, winServices.Description())
}

func TestMgrErrors(t *testing.T) {
//mgr.connect error
winServices := &WinServices{testutil.Logger{}, nil, &FakeMgProvider{testErrors[0]}}
winServices := &WinServices{
Log: testutil.Logger{},
mgrProvider: &FakeMgProvider{testErrors[0]},
}
var acc1 testutil.Accumulator
err := winServices.Gather(&acc1)
require.Error(t, err)
assert.Contains(t, err.Error(), testErrors[0].mgrConnectError.Error())

////mgr.listServices error
winServices = &WinServices{testutil.Logger{}, nil, &FakeMgProvider{testErrors[1]}}
winServices = &WinServices{
Log: testutil.Logger{},
mgrProvider: &FakeMgProvider{testErrors[1]},
}
var acc2 testutil.Accumulator
err = winServices.Gather(&acc2)
require.Error(t, err)
assert.Contains(t, err.Error(), testErrors[1].mgrListServicesError.Error())

////mgr.listServices error 2
winServices = &WinServices{testutil.Logger{}, []string{"Fake service 1"}, &FakeMgProvider{testErrors[3]}}
winServices = &WinServices{
Log: testutil.Logger{},
ServiceNames: []string{"Fake service 1"},
mgrProvider: &FakeMgProvider{testErrors[3]},
}
winServices.Init()
var acc3 testutil.Accumulator

buf := &bytes.Buffer{}
Expand All @@ -162,7 +177,11 @@ func TestMgrErrors(t *testing.T) {
}

func TestServiceErrors(t *testing.T) {
winServices := &WinServices{testutil.Logger{}, nil, &FakeMgProvider{testErrors[2]}}
winServices := &WinServices{
Log: testutil.Logger{},
mgrProvider: &FakeMgProvider{testErrors[2]},
}
winServices.Init()
var acc1 testutil.Accumulator

buf := &bytes.Buffer{}
Expand All @@ -184,8 +203,13 @@ var testSimpleData = []testData{
}},
}

func TestGather2(t *testing.T) {
winServices := &WinServices{testutil.Logger{}, nil, &FakeMgProvider{testSimpleData[0]}}
func TestGatherContainsTag(t *testing.T) {
winServices := &WinServices{
Log: testutil.Logger{},
ServiceNames: []string{"Service*"},
mgrProvider: &FakeMgProvider{testSimpleData[0]},
}
winServices.Init()
var acc1 testutil.Accumulator
require.NoError(t, winServices.Gather(&acc1))
assert.Len(t, acc1.Errors, 0, "There should be no errors after gather")
Expand Down

0 comments on commit c7e06a9

Please sign in to comment.