Skip to content

Commit

Permalink
Continuation of #8561 - add windows.service.start_name and windows.se…
Browse files Browse the repository at this point in the history
…rvice.path_name (#11877)

* implement issue #8364 in metricbeat windows module, pathname and usename of service

* Fix changelog entries

* Update changelog

* resolved rebase merge issue
  • Loading branch information
narph authored Apr 26, 2019
1 parent e03993f commit d421be8
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
- Allow module configurations to have variants {pull}9118[9118]
- Add `timeseries.instance` field calculation. {pull}10293[10293]
- Added new disk states and raid level to the system/raid metricset. {pull}11613[11613]
- Added `path_name` and `start_name` to service metricset on windows module {issue}8364[8364] {pull}11877[11877]
- Add check on object name in the counter path if the instance name is missing {issue}6528[6528] {pull}11878[11878]

*Packetbeat*
Expand Down
24 changes: 24 additions & 0 deletions metricbeat/docs/fields.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -26726,6 +26726,30 @@ type: keyword
The startup type of the service. The possible values are `Automatic`, `Boot`, `Disabled`, `Manual`, and `System`.


--

*`windows.service.start_name`*::
+
--
type: keyword

example: NT AUTHORITY\LocalService

Account name under which a service runs.


--

*`windows.service.path_name`*::
+
--
type: keyword

example: C:\WINDOWS\system32\svchost.exe -k LocalService -p

Fully qualified path to the file that implements the service, including arguments.


--

*`windows.service.state`*::
Expand Down
2 changes: 1 addition & 1 deletion metricbeat/module/windows/fields.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions metricbeat/module/windows/service/_meta/fields.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@
The startup type of the service. The possible values are `Automatic`,
`Boot`, `Disabled`, `Manual`, and `System`.
- name: start_name
type: keyword
example: NT AUTHORITY\LocalService
description: >
Account name under which a service runs.
- name: path_name
type: keyword
example: C:\WINDOWS\system32\svchost.exe -k LocalService -p
description: >
Fully qualified path to the file that implements the service,
including arguments.
- name: state
type: keyword
description: >
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ type Win32Service struct {
ProcessId uint32
DisplayName string
State string
StartName string
PathName string
}

func TestData(t *testing.T) {
Expand All @@ -58,7 +60,8 @@ func TestReadService(t *testing.T) {

var wmiSrc []Win32Service

// Get services from WMI.
// Get services from WMI, set NonePtrZero so nil fields are turned to empty strings
wmi.DefaultClient.NonePtrZero = true
err = wmi.Query("SELECT * FROM Win32_Service ", &wmiSrc)
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -87,6 +90,15 @@ func TestReadService(t *testing.T) {
assert.Equal(t, w.DisplayName, s["display_name"],
"Display name of service %v does not match", w.Name)
}
// some services come back without PathName or StartName from WMI, just skip them
if s["path_name"] != nil && w.PathName != "" {
assert.Equal(t, w.PathName, s["path_name"],
"Path name of service %v does not match", w.Name)
}
if s["start_name"] != nil && w.StartName != "" {
assert.Equal(t, w.StartName, s["start_name"],
"Start name of service %v does not match", w.Name)
}
// Some services have changed state before the second retrieval.
if w.State != s["state"] {
changed := s
Expand Down
33 changes: 26 additions & 7 deletions metricbeat/module/windows/service/service_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,15 @@ var errorNames = map[uint32]string{
}

type ServiceStatus struct {
DisplayName string
ServiceName string
CurrentState string
StartType ServiceStartType
PID uint32 // ID of the associated process.
Uptime time.Duration
ExitCode uint32 // Exit code for stopped services.
DisplayName string
ServiceName string
CurrentState string
StartType ServiceStartType
PID uint32 // ID of the associated process.
Uptime time.Duration
ExitCode uint32 // Exit code for stopped services.
ServiceStartName string
BinaryPathName string
}

type ServiceReader struct {
Expand Down Expand Up @@ -373,6 +375,21 @@ func getAdditionalServiceInfo(serviceHandle ServiceHandle, service *ServiceStatu
}
serviceQueryConfig := (*QueryServiceConfig)(unsafe.Pointer(&buffer[0]))
service.StartType = ServiceStartType(serviceQueryConfig.DwStartType)
serviceStartNameOffset := uintptr(unsafe.Pointer(serviceQueryConfig.LpServiceStartName)) - (uintptr)(unsafe.Pointer(&buffer[0]))
binaryPathNameOffset := uintptr(unsafe.Pointer(serviceQueryConfig.LpBinaryPathName)) - (uintptr)(unsafe.Pointer(&buffer[0]))

strBuf := new(bytes.Buffer)
if err := sys.UTF16ToUTF8Bytes(buffer[serviceStartNameOffset:], strBuf); err != nil {
return err
}
service.ServiceStartName = strBuf.String()

strBuf.Reset()
if err := sys.UTF16ToUTF8Bytes(buffer[binaryPathNameOffset:], strBuf); err != nil {
return err
}
service.BinaryPathName = strBuf.String()

break
}

Expand Down Expand Up @@ -476,6 +493,8 @@ func (reader *ServiceReader) Read() ([]common.MapStr, error) {
"name": service.ServiceName,
"state": service.CurrentState,
"start_type": service.StartType.String(),
"start_name": service.ServiceStartName,
"path_name": service.BinaryPathName,
}

if service.CurrentState == "Stopped" {
Expand Down

0 comments on commit d421be8

Please sign in to comment.