service: add delayed_start and trigger_start labels to windows_service_info (#2768)

Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
Jan-Otto Kröpke
2026-10-16 21:30:11 +02:00
committed by GitHub
parent 4f3152d84d
commit 4f8fc2baef
8 changed files with 289 additions and 57 deletions
+55 -11
View File
@@ -30,22 +30,24 @@ Recommended to keep down number of returned metrics. Default: `auto,boot,manual,
## Configuration cache
The service configuration (display name, start mode, path and account, used by
`windows_service_info` and `windows_service_start_mode`) is cached between scrapes.
The service configuration (display name, start mode, delayed start, triggers, path and
account, used by `windows_service_info` and `windows_service_start_mode`) is cached between scrapes.
The collector watches the registry key `HKLM\SYSTEM\CurrentControlSet\Services`. When a
service's own key changes, for example after `sc config`, a change in the Services console
or a reinstall, its configuration is queried again on the next scrape. All configurations
are queried again at the latest every 10 minutes. The service state and process are queried
on every scrape.
on every scrape. Reading the delayed start flag and the triggers takes extra calls per service,
which run when a configuration is queried: on a cache miss, or on every scrape if the registry
key can't be watched and the cache is disabled.
## Metrics
| Name | Description | Type | Labels |
|------------------------------|-----------------------------------------------------------------------------------------------|-------|---------------------------------------|
| `windows_service_info` | Contains service information run as user in labels, constant 1 | gauge | service, display_name, run_as, path_name |
| `windows_service_start_mode` | The start mode of the service, 1 if the current start mode, 0 otherwise | gauge | service, start_mode |
| `windows_service_state` | The state of the service, 1 if the current state, 0 otherwise | gauge | service, state |
| `windows_service_process` | Process of started service. The value is the creation time of the process as a Unix timestamp | gauge | service, process_id |
| Name | Description | Type | Labels |
|------------------------------|-----------------------------------------------------------------------------------------------|-------|--------------------------------------------------------------------------|
| `windows_service_info` | Contains service information run as user in labels, constant 1 | gauge | service, display_name, run_as, path_name, delayed_start, trigger_start |
| `windows_service_start_mode` | The start mode of the service, 1 if the current start mode, 0 otherwise | gauge | service, start_mode |
| `windows_service_state` | The state of the service, 1 if the current state, 0 otherwise | gauge | service, state |
| `windows_service_process` | Process of started service. The value is the creation time of the process as a Unix timestamp | gauge | service, process_id |
### States
@@ -69,6 +71,22 @@ A service can have the following start modes:
Note that there is some overlap with service state.
### Delayed and trigger start
The Services console shows "Automatic (Delayed Start)" and "(Trigger Start)" in addition to
the start mode. `windows_service_start_mode` reports these services with their start mode
(`auto` or `manual`); the labels of `windows_service_info` tell them apart:
- `delayed_start` is `true` for an `auto` service that starts after the other automatic
services, `false` otherwise. Windows ignores the delayed start setting of services that
don't start automatically, so it is always `false` for them.
- `trigger_start` is `true` if the service has triggers, which start or stop it when an event
occurs, for example when a device arrives, the computer joins a domain or a network becomes
available. Such a service can stop by design while its start mode is `auto`.
Both labels are empty if the service configuration, or the delayed start flag and triggers,
can't be read. The other labels are still published in the second case.
### Run As
Account name under which a service runs. Depending on the service type, the account name may be in the form of "DomainName\Username" or UPN format ("Username@DomainName").
@@ -78,8 +96,8 @@ Account name under which a service runs. Depending on the service type, the acco
```
# HELP windows_service_info A metric with a constant '1' value labeled with service information
# TYPE windows_service_info gauge
windows_service_info{display_name="Declared Configuration(DC) service",service="dcsvc",path_name="C:\\WINDOWS\\system32\\svchost.exe -k netsvcs -p",run_as="LocalSystem"} 1
windows_service_info{display_name="Designs",service="Themes",path_name="C:\\WINDOWS\\System32\\svchost.exe -k netsvcs -p",run_as="LocalSystem"} 1
windows_service_info{delayed_start="false",display_name="Declared Configuration(DC) service",service="dcsvc",path_name="C:\\WINDOWS\\system32\\svchost.exe -k netsvcs -p",run_as="LocalSystem",trigger_start="true"} 1
windows_service_info{delayed_start="false",display_name="Designs",service="Themes",path_name="C:\\WINDOWS\\System32\\svchost.exe -k netsvcs -p",run_as="LocalSystem",trigger_start="false"} 1
# HELP windows_service_process Process of started service. The value is the creation time of the process as a unix timestamp.
# TYPE windows_service_process gauge
windows_service_process{service="Themes",process_id="2856"} 1.7244891e+09
@@ -148,3 +166,29 @@ groups:
description: "Service {{ $labels.service }} on instance {{ $labels.instance }} has been down for more than 3 minutes."
```
In this example, `instance` is the target label of the host. So each alert will be processed per host, which is then used in the alert description.
The next rule alerts on every automatic service that is not running, except trigger-start
services, which stop by design:
```yaml
groups:
- name: Windows services
rules:
# Sends an alert when a service with start mode auto and without triggers is not running for 15 minutes.
- alert: WindowsAutoServiceNotRunning
expr: |
windows_service_state{state="running"} == 0
and on (instance, service) windows_service_start_mode{start_mode="auto"} == 1
unless on (instance, service) windows_service_info{trigger_start="true"}
for: 15m
labels:
severity: warning
annotations:
summary: "Service {{ $labels.service }} not running"
description: "Automatic service {{ $labels.service }} on instance {{ $labels.instance }} has not been running for more than 15 minutes."
```
Delayed-start services start about two minutes after the other automatic services, so the
`for` duration covers them after a reboot. To leave them out as well, add
`unless on (instance, service) windows_service_info{delayed_start="true"}`.
+1
View File
@@ -900,6 +900,7 @@ windows_service_state{state="running"} == 0
### Label changes
- `windows_os_info` has an `installation_type` label, for example `Server` or `Client`.
- `windows_service_info` has the labels `delayed_start` and `trigger_start` (`true` or `false`), which tell "Automatic (Delayed Start)" and trigger-start services apart. `windows_service_start_mode` is unchanged.
- The IIS HTTP request queue metrics (`windows_iis_http_requests_*`) have the label `app` instead of `site`. The value is unchanged: it always was the application pool that owns the HTTP.sys request queue, not a site. They are now filtered with `--collector.iis.app-include` and `--collector.iis.app-exclude` instead of the site filters.
- All `windows_netframework_*` metrics have a `process_id` label, so processes with the same name, for example IIS worker processes (`w3wp`), can be joined with the `process` collector metrics. Only `.NET CLR Memory` reports the process ID; the other metrics take it from the `.NET CLR Memory` instance of the same sample and have an empty `process_id` if there is none. The new `--collector.netframework.process-include` and `--collector.netframework.process-exclude` flags filter the processes. The label changes the series identity: a restarted process, for example a recycled `w3wp`, starts a new series instead of continuing `process="w3wp"`. To keep the 0.31 series, aggregate with `without (process_id)` or `by (process)`.
- In the `windows_hyperv_dynamic_memory_vm_*` metrics, unnamed VM instances have `vm="(unknown)"` (or `(unknown)#N`) instead of `vm="------"`.