Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Glob pattern matching for "Windows Services" plugin #8575

Merged
merged 4 commits into from
Dec 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
sspaink marked this conversation as resolved.
Show resolved Hide resolved
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