How to Collect Data About a Windows Service in Prometheus
Monitoring Windows services with Prometheus requires a different approach than Linux-based monitoring. Prometheus was designed with a pull-based model and native Linux support, so collecting Windows service metrics means bridging that gap with the right tooling and configuration. Here's what that process looks like — and what shapes the outcome for different environments.
Why Prometheus Doesn't Collect Windows Data Natively
Prometheus scrapes metrics from HTTP endpoints that expose data in its own text-based format. On Linux, exporters integrate directly with system internals through the proc filesystem. Windows doesn't have that, so you need an intermediary — an exporter that reads Windows-specific data sources (like the Windows Registry, WMI, or the Service Control Manager) and translates them into Prometheus-readable metrics.
The standard tool for this is the Windows Exporter (formerly called wmi_exporter). It runs as a Windows service itself, exposes a local HTTP endpoint (default port 9182), and Prometheus scrapes that endpoint on a schedule you define.
Setting Up the Windows Exporter
Installation
The Windows Exporter is distributed as a .msi installer or a standalone .exe. Installing via MSI is the most common approach because it registers the exporter as a Windows service automatically, so it starts on boot without manual intervention.
During installation — or via command-line flags — you configure which collectors to enable. Collectors are modular components that gather specific categories of metrics. For Windows service monitoring, the key collector is:
service— exposes the state, start type, and process ID of Windows services
By default, not all collectors are enabled. You need to explicitly include the service collector if it isn't active in your deployment.
Enabling the Service Collector
When starting the Windows Exporter, you pass the --collectors.enabled flag with a comma-separated list of collectors. For example:
windows_exporter.exe --collectors.enabled="cpu,memory,service" If you installed via MSI, this flag can be set during installation or by editing the service configuration afterward.
Filtering Which Services Are Monitored 🔍
By default, the service collector attempts to expose data for all Windows services — and there can be hundreds. That creates metric bloat and unnecessary load. Most teams filter this down using the --collector.service.services-where flag, which accepts a WQL (WMI Query Language) filter clause.
For example, to monitor only services with names matching a pattern:
--collector.service.services-where="Name='nginx' OR Name='postgresql'" Or using a wildcard-style approach with LIKE:
--collector.service.services-where="Name LIKE 'sql%'" This lets you scope collection tightly to the services that actually matter for your monitoring goals.
What Metrics the Service Collector Exposes
Once running, the Windows Exporter publishes metrics at http://<host>:9182/metrics. For the service collector, the primary metric is:
| Metric | Description |
|---|---|
windows_service_state | Current state of the service (running, stopped, paused, etc.) |
windows_service_start_mode | How the service is configured to start (auto, manual, disabled) |
windows_service_process_id | The PID associated with the service, if running |
windows_service_status | Overall status reported by the Service Control Manager |
Each metric is labeled with the service name and display name, making it straightforward to filter in PromQL or build dashboards around specific services.
Configuring Prometheus to Scrape the Exporter
On the Prometheus server side, you add a scrape config pointing at the Windows Exporter's endpoint. In your prometheus.yml:
scrape_configs: - job_name: 'windows_services' static_configs: - targets: ['<windows-host-ip>:9182'] The scrape_interval can be set globally or overridden per job. For service state monitoring, intervals of 15–60 seconds are typical — short enough to detect failures promptly, long enough to avoid unnecessary overhead.
If you're monitoring multiple Windows hosts, each needs its own exporter instance, and you list all targets under static_configs or use service discovery mechanisms (DNS-based, file-based, or via integrations like Consul) to manage them dynamically.
Querying Service Data in PromQL
Once Prometheus is scraping the data, you query it using PromQL. A common starting point is checking whether a specific service is in the "running" state:
windows_service_state{name="nginx", state="running"} == 0 A result of 0 means the service is not in the running state — useful for alerting. You can wire this into Alertmanager to fire notifications when a critical service goes down.
Variables That Shape Your Setup 🛠️
How straightforward this process is depends on several factors:
- Network architecture — Is Prometheus on the same network as your Windows hosts, or does traffic cross firewalls? Port
9182needs to be reachable by the Prometheus server. - Number of Windows hosts — A single host with static config is simple. Dozens of hosts benefits from service discovery.
- Windows version and permissions — The exporter process needs sufficient permissions to query the Service Control Manager. Running it under an appropriate service account matters in locked-down environments.
- Collector selection — Enabling too many collectors on resource-constrained machines increases CPU and memory usage on the host itself.
- Security requirements — Some environments require TLS on the exporter endpoint and authentication, which the Windows Exporter supports but requires additional configuration.
Different Setups, Different Outcomes ⚙️
A developer monitoring a local Windows dev machine can install the exporter in minutes with default settings and start seeing service states immediately. An enterprise team managing hundreds of Windows servers in a regulated environment will likely invest time in collector filtering, TLS configuration, service discovery integration, and alerting rules before the setup is production-ready.
Teams already running Grafana alongside Prometheus will find pre-built dashboards available for Windows Exporter metrics, reducing the visualization work considerably. Those building from scratch in plain Prometheus will need to construct their own alerting and recording rules.
The technical steps are consistent across environments — exporter, scrape config, PromQL queries — but the complexity of each layer scales with the size, security requirements, and operational maturity of the environment it's being deployed into. Whether the default collector settings are appropriate, which services warrant alerting, and how granular the filtering should be are decisions that depend entirely on what's actually running in a given environment.