-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
New windows service metricset #5332
Changes from 51 commits
1ef849c
d414d86
b9878d7
d7d0aa1
a5bd839
65ea2f7
a0c7f13
d5be9ed
8fea616
6fd5d02
eb3ecd2
73ef011
3fe19b7
51f64db
ff57f2b
df94026
ae9de49
6ade0fc
49430ff
e3b71ce
78f4a34
8ffd2c6
7dff37d
ed94168
239d774
8f0dcc6
89f6ce8
076e376
b0dde4e
999e2b5
088389f
63df59e
75958f9
57a47a3
570d828
2f98979
8577fc4
8654ee8
fa8ef48
120c8f8
2a172bb
e534732
e504e6f
884212e
0489cf8
63d735b
4ff7381
12b78b2
55751ae
4eb1120
99fbfd1
563f487
9d83f1e
aecd50b
e9409e8
17ac114
cb4cf55
e743b68
5ca5ebe
b98d69b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
//// | ||
This file is generated! See scripts/docs_collector.py | ||
//// | ||
|
||
[[metricbeat-metricset-windows-services]] | ||
include::../../../module/windows/services/_meta/docs.asciidoc[] | ||
|
||
|
||
==== Fields | ||
|
||
For a description of each field in the metricset, see the | ||
<<exported-fields-windows,exported fields>> section. | ||
|
||
Here is an example document generated by this metricset: | ||
|
||
[source,json] | ||
---- | ||
include::../../../module/windows/services/_meta/data.json[] | ||
---- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package helper | ||
|
||
import ( | ||
"sync" | ||
"syscall" | ||
|
||
"github.com/pkg/errors" | ||
|
||
"github.com/elastic/gosigar/sys/windows" | ||
|
||
"github.com/elastic/beats/libbeat/logp" | ||
) | ||
|
||
var once sync.Once | ||
|
||
// errMissingSeDebugPrivilege indicates that the SeDebugPrivilege is not | ||
// present in the process's token. This is distinct from disabled. The token | ||
// would be missing if the user does not have "Debug programs" rights. By | ||
// default, only administrators and LocalSystem accounts have the privileges to | ||
// debug programs. | ||
var errMissingSeDebugPrivilege = errors.New("Metricbeat is running without " + | ||
"SeDebugPrivilege, a Windows privilege that allows it to collect metrics " + | ||
"from other processes. The user running Metricbeat may not have the " + | ||
"appropriate privileges or the security policy disallows it.") | ||
|
||
// enableSeDebugPrivilege enables the SeDebugPrivilege if it is present in | ||
// the process's token. | ||
func enableSeDebugPrivilege() error { | ||
self, err := syscall.GetCurrentProcess() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var token syscall.Token | ||
err = syscall.OpenProcessToken(self, syscall.TOKEN_QUERY|syscall.TOKEN_ADJUST_PRIVILEGES, &token) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if err = windows.EnableTokenPrivileges(token, windows.SeDebugPrivilege); err != nil { | ||
return errors.Wrap(err, "EnableTokenPrivileges failed") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// CheckAndEnableSeDebugPrivilege checks if the process's token has the | ||
// SeDebugPrivilege and enables it if it is disabled. | ||
func CheckAndEnableSeDebugPrivilege() error { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm thinking this should be This way only the system module or the windows module will do the initialization, but not both. |
||
var err error | ||
once.Do(func() { | ||
err = checkAndEnableSeDebugPrivilege() | ||
}) | ||
return err | ||
} | ||
|
||
func checkAndEnableSeDebugPrivilege() error { | ||
info, err := windows.GetDebugInfo() | ||
if err != nil { | ||
return errors.Wrap(err, "GetDebugInfo failed") | ||
} | ||
logp.Info("Metricbeat process and system info: %v", info) | ||
|
||
seDebug, found := info.ProcessPrivs[windows.SeDebugPrivilege] | ||
if !found { | ||
return errMissingSeDebugPrivilege | ||
} | ||
|
||
if seDebug.Enabled { | ||
logp.Info("SeDebugPrivilege is enabled. %v", seDebug) | ||
return nil | ||
} | ||
|
||
if err = enableSeDebugPrivilege(); err != nil { | ||
logp.Warn("Failure while attempting to enable SeDebugPrivilege. %v", err) | ||
} | ||
|
||
info, err = windows.GetDebugInfo() | ||
if err != nil { | ||
return errors.Wrap(err, "GetDebugInfo failed") | ||
} | ||
|
||
seDebug, found = info.ProcessPrivs[windows.SeDebugPrivilege] | ||
if !found { | ||
return errMissingSeDebugPrivilege | ||
} | ||
|
||
if !seDebug.Enabled { | ||
return errors.Errorf("Metricbeat failed to enable the "+ | ||
"SeDebugPrivilege, a Windows privilege that allows it to collect "+ | ||
"metrics from other processes. %v", seDebug) | ||
} | ||
|
||
logp.Info("SeDebugPrivilege is now enabled. %v", seDebug) | ||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,90 +1,12 @@ | ||
package system | ||
|
||
import ( | ||
"syscall" | ||
|
||
"github.com/pkg/errors" | ||
|
||
"github.com/elastic/beats/libbeat/logp" | ||
"github.com/elastic/gosigar/sys/windows" | ||
"github.com/elastic/beats/metricbeat/helper" | ||
) | ||
|
||
// errMissingSeDebugPrivilege indicates that the SeDebugPrivilege is not | ||
// present in the process's token. This is distinct from disabled. The token | ||
// would be missing if the user does not have "Debug programs" rights. By | ||
// default, only administrators and LocalSystem accounts have the privileges to | ||
// debug programs. | ||
var errMissingSeDebugPrivilege = errors.New("Metricbeat is running without " + | ||
"SeDebugPrivilege, a Windows privilege that allows it to collect metrics " + | ||
"from other processes. The user running Metricbeat may not have the " + | ||
"appropriate privileges or the security policy disallows it.") | ||
|
||
func initModule() { | ||
if err := checkAndEnableSeDebugPrivilege(); err != nil { | ||
if err := helper.CheckAndEnableSeDebugPrivilege(); err != nil { | ||
logp.Warn("%v", err) | ||
} | ||
} | ||
|
||
// checkAndEnableSeDebugPrivilege checks if the process's token has the | ||
// SeDebugPrivilege and enables it if it is disabled. | ||
func checkAndEnableSeDebugPrivilege() error { | ||
info, err := windows.GetDebugInfo() | ||
if err != nil { | ||
return errors.Wrap(err, "GetDebugInfo failed") | ||
} | ||
logp.Info("Metricbeat process and system info: %v", info) | ||
|
||
seDebug, found := info.ProcessPrivs[windows.SeDebugPrivilege] | ||
if !found { | ||
return errMissingSeDebugPrivilege | ||
} | ||
|
||
if seDebug.Enabled { | ||
logp.Info("SeDebugPrivilege is enabled. %v", seDebug) | ||
return nil | ||
} | ||
|
||
if err = enableSeDebugPrivilege(); err != nil { | ||
logp.Warn("Failure while attempting to enable SeDebugPrivilege. %v", err) | ||
} | ||
|
||
info, err = windows.GetDebugInfo() | ||
if err != nil { | ||
return errors.Wrap(err, "GetDebugInfo failed") | ||
} | ||
|
||
seDebug, found = info.ProcessPrivs[windows.SeDebugPrivilege] | ||
if !found { | ||
return errMissingSeDebugPrivilege | ||
} | ||
|
||
if !seDebug.Enabled { | ||
return errors.Errorf("Metricbeat failed to enable the "+ | ||
"SeDebugPrivilege, a Windows privilege that allows it to collect "+ | ||
"metrics from other processes. %v", seDebug) | ||
} | ||
|
||
logp.Info("SeDebugPrivilege is now enabled. %v", seDebug) | ||
return nil | ||
} | ||
|
||
// enableSeDebugPrivilege enables the SeDebugPrivilege if it is present in | ||
// the process's token. | ||
func enableSeDebugPrivilege() error { | ||
self, err := syscall.GetCurrentProcess() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var token syscall.Token | ||
err = syscall.OpenProcessToken(self, syscall.TOKEN_QUERY|syscall.TOKEN_ADJUST_PRIVILEGES, &token) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if err = windows.EnableTokenPrivileges(token, windows.SeDebugPrivilege); err != nil { | ||
return errors.Wrap(err, "EnableTokenPrivileges failed") | ||
} | ||
|
||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add a |
||
"@timestamp": "2016-05-23T08:05:34.853Z", | ||
"@metadata": { | ||
"beat": "noindex", | ||
"type": "doc", | ||
"version": "1.2.3" | ||
}, | ||
"beat": { | ||
"name": "host.example.com", | ||
"hostname": "host.example.com" | ||
}, | ||
"windows": { | ||
"services": { | ||
"display_name": "AllJoyn-Routerdienst", | ||
"service_name": "AJRouter", | ||
"state": "ServiceStopped", | ||
"start_type": "ServiceDemandStart" | ||
} | ||
}, | ||
"metricset": { | ||
"module": "windows", | ||
"name": "services", | ||
"rtt": 115 | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
=== windows services MetricSet | ||
|
||
The `services` metricset of the Windows module reads the status for Windows | ||
Services. | ||
|
||
[float] | ||
=== Configuration | ||
|
||
[source,yaml] | ||
---- | ||
- module: windows | ||
metricsets: ["services"] | ||
period: 10s | ||
---- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
- name: services | ||
type: group | ||
description: > | ||
`services` contains the status for windows services. | ||
fields: | ||
- name: uptime.ms | ||
type: long | ||
format: duration | ||
input_format: milliseconds | ||
description: > | ||
`uptime` contains the service uptime metric. | ||
|
||
- name: service_name | ||
type: keyword | ||
description: > | ||
The service name. | ||
|
||
- name: display_name | ||
type: keyword | ||
description: > | ||
The display name of the service. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the fields that are enums it would be nice to document what the possible values are. I would simply add a sentence that says "The possible values are x, y, and z". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some special format for the values like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you like 👍 |
||
|
||
- name: start_type | ||
type: keyword | ||
description: > | ||
The start type of the service. | ||
The possible values are `ServiceAutoStart`, `ServiceBootStart`, `ServiceDemandStart`, `ServiceDisabled`, and `ServiceSystemStart`. | ||
|
||
- name: state | ||
type: keyword | ||
description: > | ||
The actual state of the service. | ||
The possible values are `ServiceContinuePending`, `ServicePausePending`, `ServicePaused`, `ServiceRuning`, `ServiceStartPending`, | ||
`ServiceStopPending`, and `ServiceStopped`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I read through these keys I am thinking we should call this the windows service metricset (not plural). Similar to how the system process metricset is not plural. Then the field names here make more sense.
Additionally, if it is renamed then I would change
windows.services.service_name
towindows.service.name
to removing the stuttering.