Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e393c3af3f
commit
4978089aab
4963 changed files with 677545 additions and 0 deletions
91
plugins/inputs/win_services/README.md
Normal file
91
plugins/inputs/win_services/README.md
Normal file
|
@ -0,0 +1,91 @@
|
|||
# Windows Services Input Plugin
|
||||
|
||||
Reports information about Windows service status.
|
||||
|
||||
Monitoring some services may require running Telegraf with administrator
|
||||
privileges.
|
||||
|
||||
## Global configuration options <!-- @/docs/includes/plugin_config.md -->
|
||||
|
||||
In addition to the plugin-specific configuration settings, plugins support
|
||||
additional global and plugin configuration settings. These settings are used to
|
||||
modify metrics, tags, and field or create aliases and configure ordering, etc.
|
||||
See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
|
||||
|
||||
[CONFIGURATION.md]: ../../../docs/CONFIGURATION.md#plugins
|
||||
|
||||
## Configuration
|
||||
|
||||
```toml @sample.conf
|
||||
# Input plugin to report Windows services info.
|
||||
# This plugin ONLY supports Windows
|
||||
[[inputs.win_services]]
|
||||
## Names of the services to monitor. Leave empty to monitor all the available
|
||||
## services on the host. Globs accepted. Case insensitive.
|
||||
service_names = [
|
||||
"LanmanServer",
|
||||
"TermService",
|
||||
"Win*",
|
||||
]
|
||||
|
||||
# optional, list of service names to exclude
|
||||
excluded_service_names = ['WinRM']
|
||||
```
|
||||
|
||||
## Metrics
|
||||
|
||||
- win_services
|
||||
- state : integer
|
||||
- startup_mode : integer
|
||||
|
||||
The `state` field can have the following values:
|
||||
|
||||
- 1 - stopped
|
||||
- 2 - start pending
|
||||
- 3 - stop pending
|
||||
- 4 - running
|
||||
- 5 - continue pending
|
||||
- 6 - pause pending
|
||||
- 7 - paused
|
||||
|
||||
The `startup_mode` field can have the following values:
|
||||
|
||||
- 0 - boot start
|
||||
- 1 - system start
|
||||
- 2 - auto start
|
||||
- 3 - demand start
|
||||
- 4 - disabled
|
||||
|
||||
### Tags
|
||||
|
||||
- All measurements have the following tags:
|
||||
- service_name
|
||||
- display_name
|
||||
|
||||
## Example Output
|
||||
|
||||
```text
|
||||
win_services,host=WIN2008R2H401,display_name=Server,service_name=LanmanServer state=4i,startup_mode=2i 1500040669000000000
|
||||
win_services,display_name=Remote\ Desktop\ Services,service_name=TermService,host=WIN2008R2H401 state=1i,startup_mode=3i 1500040669000000000
|
||||
```
|
||||
|
||||
### TICK Scripts
|
||||
|
||||
A sample TICK script for a notification about a not running service. It sends a
|
||||
notification whenever any service changes its state to be not _running_ and when
|
||||
it changes that state back to _running_. The notification is sent via an HTTP
|
||||
POST call.
|
||||
|
||||
```shell
|
||||
stream
|
||||
|from()
|
||||
.database('telegraf')
|
||||
.retentionPolicy('autogen')
|
||||
.measurement('win_services')
|
||||
.groupBy('host','service_name')
|
||||
|alert()
|
||||
.crit(lambda: "state" != 4)
|
||||
.stateChangesOnly()
|
||||
.message('Service {{ index .Tags "service_name" }} on Host {{ index .Tags "host" }} is in state {{ index .Fields "state" }} ')
|
||||
.post('http://localhost:666/alert/service')
|
||||
```
|
13
plugins/inputs/win_services/sample.conf
Normal file
13
plugins/inputs/win_services/sample.conf
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Input plugin to report Windows services info.
|
||||
# This plugin ONLY supports Windows
|
||||
[[inputs.win_services]]
|
||||
## Names of the services to monitor. Leave empty to monitor all the available
|
||||
## services on the host. Globs accepted. Case insensitive.
|
||||
service_names = [
|
||||
"LanmanServer",
|
||||
"TermService",
|
||||
"Win*",
|
||||
]
|
||||
|
||||
# optional, list of service names to exclude
|
||||
excluded_service_names = ['WinRM']
|
248
plugins/inputs/win_services/win_services.go
Normal file
248
plugins/inputs/win_services/win_services.go
Normal file
|
@ -0,0 +1,248 @@
|
|||
//go:generate ../../../tools/readme_config_includer/generator
|
||||
//go:build windows
|
||||
|
||||
package win_services
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
"golang.org/x/sys/windows/svc"
|
||||
"golang.org/x/sys/windows/svc/mgr"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/filter"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
//go:embed sample.conf
|
||||
var sampleConfig string
|
||||
|
||||
type WinServices struct {
|
||||
ServiceNames []string `toml:"service_names"`
|
||||
ServiceNamesExcluded []string `toml:"excluded_service_names"`
|
||||
|
||||
Log telegraf.Logger `toml:"-"`
|
||||
|
||||
mgrProvider managerProvider
|
||||
servicesFilter filter.Filter
|
||||
}
|
||||
|
||||
// winService provides interface for svc.Service
|
||||
type winService interface {
|
||||
Close() error
|
||||
Config() (mgr.Config, error)
|
||||
Query() (svc.Status, error)
|
||||
}
|
||||
|
||||
// managerProvider sets interface for acquiring manager instance, like mgr.Mgr
|
||||
type managerProvider interface {
|
||||
connect() (winServiceManager, error)
|
||||
}
|
||||
|
||||
// winServiceManager provides interface for mgr.Mgr
|
||||
type winServiceManager interface {
|
||||
disconnect() error
|
||||
openService(name string) (winService, error)
|
||||
listServices() ([]string, error)
|
||||
}
|
||||
|
||||
type serviceInfo struct {
|
||||
ServiceName string
|
||||
DisplayName string
|
||||
State int
|
||||
StartUpMode int
|
||||
}
|
||||
|
||||
func (*WinServices) SampleConfig() string {
|
||||
return sampleConfig
|
||||
}
|
||||
|
||||
func (m *WinServices) Init() error {
|
||||
// For case insensitive comparison (see issue #8796) we need to transform the services
|
||||
// to lowercase
|
||||
servicesInclude := make([]string, 0, len(m.ServiceNames))
|
||||
for _, s := range m.ServiceNames {
|
||||
servicesInclude = append(servicesInclude, strings.ToLower(s))
|
||||
}
|
||||
servicesExclude := make([]string, 0, len(m.ServiceNamesExcluded))
|
||||
for _, s := range m.ServiceNamesExcluded {
|
||||
servicesExclude = append(servicesExclude, strings.ToLower(s))
|
||||
}
|
||||
|
||||
f, err := filter.NewIncludeExcludeFilter(servicesInclude, servicesExclude)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.servicesFilter = f
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *WinServices) Gather(acc telegraf.Accumulator) error {
|
||||
scmgr, err := m.mgrProvider.connect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not open service manager: %w", err)
|
||||
}
|
||||
defer scmgr.disconnect()
|
||||
|
||||
serviceNames, err := m.listServices(scmgr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, srvName := range serviceNames {
|
||||
service, err := collectServiceInfo(scmgr, srvName)
|
||||
if err != nil {
|
||||
if isPermission(err) {
|
||||
m.Log.Debug(err.Error())
|
||||
} else {
|
||||
m.Log.Error(err.Error())
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
tags := map[string]string{
|
||||
"service_name": service.ServiceName,
|
||||
}
|
||||
// display name could be empty, but still valid service
|
||||
if len(service.DisplayName) > 0 {
|
||||
tags["display_name"] = service.DisplayName
|
||||
}
|
||||
|
||||
fields := map[string]interface{}{
|
||||
"state": service.State,
|
||||
"startup_mode": service.StartUpMode,
|
||||
}
|
||||
acc.AddFields("win_services", fields, tags)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// listServices returns a list of services to gather.
|
||||
func (m *WinServices) listServices(scmgr winServiceManager) ([]string, error) {
|
||||
names, err := scmgr.listServices()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not list services: %w", err)
|
||||
}
|
||||
|
||||
var services []string
|
||||
for _, name := range names {
|
||||
// Compare case-insensitive. Use lowercase as we already converted the filter to use it.
|
||||
n := strings.ToLower(name)
|
||||
if m.servicesFilter.Match(n) {
|
||||
services = append(services, name)
|
||||
}
|
||||
}
|
||||
|
||||
return services, nil
|
||||
}
|
||||
|
||||
func isPermission(err error) bool {
|
||||
var serviceErr *serviceError
|
||||
if errors.As(err, &serviceErr) {
|
||||
return errors.Is(serviceErr, fs.ErrPermission)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// collectServiceInfo gathers info about a service.
|
||||
func collectServiceInfo(scmgr winServiceManager, serviceName string) (*serviceInfo, error) {
|
||||
srv, err := scmgr.openService(serviceName)
|
||||
if err != nil {
|
||||
return nil, &serviceError{
|
||||
message: "could not open service",
|
||||
service: serviceName,
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
srvStatus, err := srv.Query()
|
||||
if err != nil {
|
||||
return nil, &serviceError{
|
||||
message: "could not query service",
|
||||
service: serviceName,
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
|
||||
srvCfg, err := srv.Config()
|
||||
if err != nil {
|
||||
return nil, &serviceError{
|
||||
message: "could not get config of service",
|
||||
service: serviceName,
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
|
||||
serviceInfo := &serviceInfo{
|
||||
ServiceName: serviceName,
|
||||
DisplayName: srvCfg.DisplayName,
|
||||
StartUpMode: int(srvCfg.StartType),
|
||||
State: int(srvStatus.State),
|
||||
}
|
||||
return serviceInfo, nil
|
||||
}
|
||||
|
||||
type serviceError struct {
|
||||
message string
|
||||
service string
|
||||
err error
|
||||
}
|
||||
|
||||
func (e *serviceError) Error() string {
|
||||
return fmt.Sprintf("%s: %q: %v", e.message, e.service, e.err)
|
||||
}
|
||||
|
||||
// winSvcMgr is wrapper for mgr.Mgr implementing winServiceManager interface
|
||||
type winSvcMgr struct {
|
||||
realMgr *mgr.Mgr
|
||||
}
|
||||
|
||||
func (m *winSvcMgr) disconnect() error {
|
||||
return m.realMgr.Disconnect()
|
||||
}
|
||||
|
||||
func (m *winSvcMgr) openService(name string) (winService, error) {
|
||||
serviceName, err := syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot convert service name %q: %w", name, err)
|
||||
}
|
||||
h, err := windows.OpenService(m.realMgr.Handle, serviceName, windows.GENERIC_READ)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgr.Service{Name: name, Handle: h}, nil
|
||||
}
|
||||
|
||||
func (m *winSvcMgr) listServices() ([]string, error) {
|
||||
return m.realMgr.ListServices()
|
||||
}
|
||||
|
||||
// mgProvider is an implementation of WinServiceManagerProvider interface returning winSvcMgr
|
||||
type mgProvider struct {
|
||||
}
|
||||
|
||||
func (*mgProvider) connect() (winServiceManager, error) {
|
||||
h, err := windows.OpenSCManager(nil, nil, windows.GENERIC_READ)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
scmgr := &mgr.Mgr{Handle: h}
|
||||
return &winSvcMgr{scmgr}, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
inputs.Add("win_services", func() telegraf.Input {
|
||||
return &WinServices{
|
||||
mgrProvider: &mgProvider{},
|
||||
}
|
||||
})
|
||||
}
|
78
plugins/inputs/win_services/win_services_integration_test.go
Normal file
78
plugins/inputs/win_services/win_services_integration_test.go
Normal file
|
@ -0,0 +1,78 @@
|
|||
//go:build windows
|
||||
|
||||
// these tests must be run under administrator account
|
||||
package win_services
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
)
|
||||
|
||||
var invalidServices = []string{"XYZ1@", "ZYZ@", "SDF_@#"}
|
||||
var knownServices = []string{"LanmanServer", "TermService"}
|
||||
|
||||
func TestListIntegration(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping integration test in short mode")
|
||||
}
|
||||
provider := &mgProvider{}
|
||||
scmgr, err := provider.connect()
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
err := scmgr.disconnect()
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
winServices := &WinServices{
|
||||
ServiceNames: knownServices,
|
||||
}
|
||||
|
||||
require.NoError(t, 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])
|
||||
require.Equal(t, services[1], knownServices[1])
|
||||
}
|
||||
|
||||
func TestEmptyListIntegration(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping integration test in short mode")
|
||||
}
|
||||
provider := &mgProvider{}
|
||||
scmgr, err := provider.connect()
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
err := scmgr.disconnect()
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
winServices := &WinServices{
|
||||
ServiceNames: make([]string, 0),
|
||||
}
|
||||
|
||||
require.NoError(t, winServices.Init())
|
||||
services, err := winServices.listServices(scmgr)
|
||||
require.NoError(t, err)
|
||||
require.Condition(t, func() bool { return len(services) > 20 }, "Too few service")
|
||||
}
|
||||
|
||||
func TestGatherErrorsIntegration(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping integration test in short mode")
|
||||
}
|
||||
ws := &WinServices{
|
||||
Log: testutil.Logger{},
|
||||
ServiceNames: invalidServices,
|
||||
mgrProvider: &mgProvider{},
|
||||
}
|
||||
|
||||
require.NoError(t, ws.Init())
|
||||
require.Len(t, ws.ServiceNames, 3, "Different number of services")
|
||||
var acc testutil.Accumulator
|
||||
require.NoError(t, ws.Gather(&acc))
|
||||
require.Len(t, acc.Errors, 3, "There should be 3 errors after gather")
|
||||
}
|
33
plugins/inputs/win_services/win_services_notwindows.go
Normal file
33
plugins/inputs/win_services/win_services_notwindows.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
//go:generate ../../../tools/readme_config_includer/generator
|
||||
//go:build !windows
|
||||
|
||||
package win_services
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
//go:embed sample.conf
|
||||
var sampleConfig string
|
||||
|
||||
type WinServices struct {
|
||||
Log telegraf.Logger `toml:"-"`
|
||||
}
|
||||
|
||||
func (*WinServices) SampleConfig() string { return sampleConfig }
|
||||
|
||||
func (w *WinServices) Init() error {
|
||||
w.Log.Warn("Current platform is not supported")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*WinServices) Gather(telegraf.Accumulator) error { return nil }
|
||||
|
||||
func init() {
|
||||
inputs.Add("win_services", func() telegraf.Input {
|
||||
return &WinServices{}
|
||||
})
|
||||
}
|
240
plugins/inputs/win_services/win_services_test.go
Normal file
240
plugins/inputs/win_services/win_services_test.go
Normal file
|
@ -0,0 +1,240 @@
|
|||
//go:build windows
|
||||
|
||||
package win_services
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/sys/windows/svc"
|
||||
"golang.org/x/sys/windows/svc/mgr"
|
||||
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
)
|
||||
|
||||
// testData is DD wrapper for unit testing of WinServices
|
||||
type testData struct {
|
||||
// collection that will be returned in listServices if service array passed into WinServices constructor is empty
|
||||
queryServiceList []string
|
||||
mgrConnectError error
|
||||
mgrListServicesError error
|
||||
services []serviceTestInfo
|
||||
}
|
||||
|
||||
type serviceTestInfo struct {
|
||||
serviceOpenError error
|
||||
serviceQueryError error
|
||||
serviceConfigError error
|
||||
serviceName string
|
||||
displayName string
|
||||
state int
|
||||
startUpMode int
|
||||
}
|
||||
|
||||
type FakeSvcMgr struct {
|
||||
testData testData
|
||||
}
|
||||
|
||||
func (*FakeSvcMgr) disconnect() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *FakeSvcMgr) openService(name string) (winService, error) {
|
||||
for _, s := range m.testData.services {
|
||||
if s.serviceName == name {
|
||||
if s.serviceOpenError != nil {
|
||||
return nil, s.serviceOpenError
|
||||
}
|
||||
return &fakeWinSvc{s}, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("cannot find service %q", name)
|
||||
}
|
||||
|
||||
func (m *FakeSvcMgr) listServices() ([]string, error) {
|
||||
if m.testData.mgrListServicesError != nil {
|
||||
return nil, m.testData.mgrListServicesError
|
||||
}
|
||||
return m.testData.queryServiceList, nil
|
||||
}
|
||||
|
||||
type FakeMgProvider struct {
|
||||
testData testData
|
||||
}
|
||||
|
||||
func (m *FakeMgProvider) connect() (winServiceManager, error) {
|
||||
if m.testData.mgrConnectError != nil {
|
||||
return nil, m.testData.mgrConnectError
|
||||
}
|
||||
return &FakeSvcMgr{m.testData}, nil
|
||||
}
|
||||
|
||||
type fakeWinSvc struct {
|
||||
testData serviceTestInfo
|
||||
}
|
||||
|
||||
func (*fakeWinSvc) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *fakeWinSvc) Config() (mgr.Config, error) {
|
||||
if m.testData.serviceConfigError != nil {
|
||||
return mgr.Config{}, m.testData.serviceConfigError
|
||||
}
|
||||
return mgr.Config{
|
||||
ServiceType: 0,
|
||||
StartType: uint32(m.testData.startUpMode),
|
||||
ErrorControl: 0,
|
||||
BinaryPathName: "",
|
||||
LoadOrderGroup: "",
|
||||
TagId: 0,
|
||||
Dependencies: nil,
|
||||
ServiceStartName: m.testData.serviceName,
|
||||
DisplayName: m.testData.displayName,
|
||||
Password: "",
|
||||
Description: "",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *fakeWinSvc) Query() (svc.Status, error) {
|
||||
if m.testData.serviceQueryError != nil {
|
||||
return svc.Status{}, m.testData.serviceQueryError
|
||||
}
|
||||
return svc.Status{
|
||||
State: svc.State(m.testData.state),
|
||||
Accepts: 0,
|
||||
CheckPoint: 0,
|
||||
WaitHint: 0,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var testErrors = []testData{
|
||||
{nil, errors.New("fake mgr connect error"), nil, nil},
|
||||
{nil, nil, errors.New("fake mgr list services error"), nil},
|
||||
{[]string{"Fake service 1", "Fake service 2", "Fake service 3"}, nil, nil, []serviceTestInfo{
|
||||
{errors.New("fake srv open error"), nil, nil, "Fake service 1", "", 0, 0},
|
||||
{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},
|
||||
}},
|
||||
{[]string{"Fake service 1"}, nil, nil, []serviceTestInfo{
|
||||
{errors.New("fake srv open error"), nil, nil, "Fake service 1", "", 0, 0},
|
||||
}},
|
||||
}
|
||||
|
||||
func TestMgrErrors(t *testing.T) {
|
||||
// mgr.connect error
|
||||
winServices := &WinServices{
|
||||
Log: testutil.Logger{},
|
||||
mgrProvider: &FakeMgProvider{testErrors[0]},
|
||||
}
|
||||
var acc1 testutil.Accumulator
|
||||
err := winServices.Gather(&acc1)
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), testErrors[0].mgrConnectError.Error())
|
||||
|
||||
// mgr.listServices error
|
||||
winServices = &WinServices{
|
||||
Log: testutil.Logger{},
|
||||
mgrProvider: &FakeMgProvider{testErrors[1]},
|
||||
}
|
||||
var acc2 testutil.Accumulator
|
||||
err = winServices.Gather(&acc2)
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), testErrors[1].mgrListServicesError.Error())
|
||||
|
||||
// mgr.listServices error 2
|
||||
winServices = &WinServices{
|
||||
Log: testutil.Logger{},
|
||||
ServiceNames: []string{"Fake service 1"},
|
||||
mgrProvider: &FakeMgProvider{testErrors[3]},
|
||||
}
|
||||
err = winServices.Init()
|
||||
require.NoError(t, err)
|
||||
|
||||
var acc3 testutil.Accumulator
|
||||
buf := &bytes.Buffer{}
|
||||
log.SetOutput(buf)
|
||||
require.NoError(t, winServices.Gather(&acc3))
|
||||
|
||||
require.Contains(t, buf.String(), testErrors[2].services[0].serviceOpenError.Error())
|
||||
}
|
||||
|
||||
func TestServiceErrors(t *testing.T) {
|
||||
winServices := &WinServices{
|
||||
Log: testutil.Logger{},
|
||||
mgrProvider: &FakeMgProvider{testErrors[2]},
|
||||
}
|
||||
err := winServices.Init()
|
||||
require.NoError(t, err)
|
||||
|
||||
var acc1 testutil.Accumulator
|
||||
buf := &bytes.Buffer{}
|
||||
log.SetOutput(buf)
|
||||
require.NoError(t, winServices.Gather(&acc1))
|
||||
|
||||
// open service error
|
||||
require.Contains(t, buf.String(), testErrors[2].services[0].serviceOpenError.Error())
|
||||
// query service error
|
||||
require.Contains(t, buf.String(), testErrors[2].services[1].serviceQueryError.Error())
|
||||
// config service error
|
||||
require.Contains(t, buf.String(), testErrors[2].services[2].serviceConfigError.Error())
|
||||
}
|
||||
|
||||
var testSimpleData = []testData{
|
||||
{[]string{"Service 1", "Service 2"}, nil, nil, []serviceTestInfo{
|
||||
{nil, nil, nil, "Service 1", "Fake service 1", 1, 2},
|
||||
{nil, nil, nil, "Service 2", "Fake service 2", 1, 2},
|
||||
}},
|
||||
}
|
||||
|
||||
func TestGatherContainsTag(t *testing.T) {
|
||||
winServices := &WinServices{
|
||||
Log: testutil.Logger{},
|
||||
ServiceNames: []string{"Service*"},
|
||||
mgrProvider: &FakeMgProvider{testSimpleData[0]},
|
||||
}
|
||||
|
||||
err := winServices.Init()
|
||||
require.NoError(t, err)
|
||||
|
||||
var acc1 testutil.Accumulator
|
||||
require.NoError(t, winServices.Gather(&acc1))
|
||||
require.Empty(t, acc1.Errors, "There should be no errors after gather")
|
||||
|
||||
for _, s := range testSimpleData[0].services {
|
||||
fields := make(map[string]interface{})
|
||||
tags := make(map[string]string)
|
||||
fields["state"] = s.state
|
||||
fields["startup_mode"] = s.startUpMode
|
||||
tags["service_name"] = s.serviceName
|
||||
tags["display_name"] = s.displayName
|
||||
acc1.AssertContainsTaggedFields(t, "win_services", fields, tags)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExcludingNamesTag(t *testing.T) {
|
||||
winServices := &WinServices{
|
||||
Log: testutil.Logger{},
|
||||
ServiceNamesExcluded: []string{"Service*"},
|
||||
mgrProvider: &FakeMgProvider{testSimpleData[0]},
|
||||
}
|
||||
err := winServices.Init()
|
||||
require.NoError(t, err)
|
||||
|
||||
var acc1 testutil.Accumulator
|
||||
require.NoError(t, winServices.Gather(&acc1))
|
||||
|
||||
for _, s := range testSimpleData[0].services {
|
||||
fields := make(map[string]interface{})
|
||||
tags := make(map[string]string)
|
||||
fields["state"] = s.state
|
||||
fields["startup_mode"] = s.startUpMode
|
||||
tags["service_name"] = s.serviceName
|
||||
tags["display_name"] = s.displayName
|
||||
acc1.AssertDoesNotContainsTaggedFields(t, "win_services", fields, tags)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue