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

* Allow glob patterns in config

* Update README

* Move creating filter to init

* Need to explictly call init

Co-authored-by: Bas <3441183+BattleBas@users.noreply.github.com>
This commit is contained in:
Sebastian Spaink 2020-12-16 14:32:29 -06:00 committed by GitHub
parent 045c3c18b8
commit b858eb962a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 20 deletions

View File

@ -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*",
]
```

View File

@ -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"
@ -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*",
]
`
@ -93,6 +95,8 @@ type WinServices struct {
ServiceNames []string `toml:"service_names"`
mgrProvider ManagerProvider
servicesFilter filter.Filter
}
type ServiceInfo struct {
@ -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
}
@ -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
}
@ -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.

View File

@ -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])
@ -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")
}
@ -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))

View File

@ -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{}
@ -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{}
@ -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")