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:
parent
045c3c18b8
commit
b858eb962a
|
|
@ -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*",
|
||||
]
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
Loading…
Reference in New Issue