Skip to content

CheckSystem

Various system related checks, such as CPU load, process state, service state memory usage and PDH counters.

Various system related checks, such as CPU load, process state and memory.

Enable module

To enable this module and allow using the commands you need to add CheckSystem = enabled to the [/modules] section in nsclient.ini:

[/modules]
CheckSystem = enabled

Queries

A quick reference for all available queries (check commands) in the CheckSystem module.

List of commands:

A list of all available queries (check commands)

Command Description
check_battery Check battery status including charge level, power source, and battery health.
check_cpu Check that the load of the CPU(s) are within bounds.
check_cpu_frequency Check CPU clock frequency (current vs max) per processor.
check_cpu_utilization Check CPU utilization broken down by user/system/iowait/steal/guest.
check_hardware Check hardware inventory (vendor, model, serial, chassis type, memory modules) with pinned-expectation alerting: serial changed, DIMM dropped, laptop in a server fleet.
check_hostname Check host identity: hostname, FQDN, DNS domain and domain-join state, with drift detection for the name mismatches that silently break auth and monitoring.
check_installed_software Check installed software from the registry Uninstall hives (64-bit, 32-bit and per-user views): inventory, unwanted/EOL software policy and recent-install detection.
check_kernel_memory Check kernel memory-manager health: paged/nonpaged pool bytes, file-cache bytes and page-fault rates — the pool-exhaustion and hard-fault-storm signals free-RAM thresholds miss.
check_kernel_stats Check system-wide kernel activity: context-switch and system-call rates plus live process and thread counts.
check_load Check the system load average (1/5/15 minutes), synthesised from the processor queue length plus busy cores.
check_memory Check free/used memory on the system.
check_network Check network interface status.
check_os_updates Check for available Windows updates via the Windows Update Agent (WUA) API.
check_os_version Check the version of the underlying OS.
check_pagefile Check the size of the system pagefile(s).
check_patch_age Check installed-hotfix hygiene: how long since the newest hotfix was installed and whether specific required hotfixes are present.
check_pdh Check the value of a performance (PDH) counter on the local or remote system.
check_pending_reboot Check whether the system is waiting for a reboot, aggregating the servicing, Windows Update, file-rename, computer-rename and domain-join signals.
check_printjobs Check individual Windows print jobs: document, owner, size, pages, age and spooler status of every queued job.
check_printqueue Check Windows print queues: queue depth, oldest-job age, offline and error states plus the driver, port and sharing of each printer.
check_process Check state/metrics of one or more of the processes running on the computer.
check_process_history Check the history of processes that have been running since NSClient++ started. Useful for verifying if certain applications have been executed.
check_process_history_new Check for new processes that appeared within a specified time window. Useful for detecting unexpected or unauthorized applications.
check_registry_key Check existence, last-write time, and child counts of one or more Windows registry keys.
check_registry_value Check the type, content, and size of one or more Windows registry values.
check_service Check the state of one or more of the computer services.
check_swap_io Check system paging (swap) I/O rates: pages/bytes paged in and out per second.
check_temperature Check ACPI thermal zone temperatures.
check_uptime Check time since last server re-boot.
check_w32time Check the Windows Time service: whether the machine is following a time source at all, which one, the computed clock offset and the configured peers.

List of command aliases:

A list of all short hand aliases for queries (check commands)

Command Description
check_counter Alias for: :query:check_pdh

check_battery

Check battery status including charge level, power source, and battery health.

About check_battery

check_battery reports the state of the machine’s batteries: charge level, which power source it is on, and battery health. One record is returned per battery.

The default filter is battery_present = 'true', and the thresholds are charge < 20 (warning) and charge < 10 (critical).

On a machine with no battery — a desktop, a server, a VM — the filter matches nothing, and the empty state is warning, so the check reports WARNING: No battery found. That is almost never what you want on infrastructure: set empty-state=ok (or empty-state=ignored) on any host where a missing battery is normal, otherwise every server running this check sits permanently in WARNING.

The three questions it answers

“Is this laptop about to die?” is the default, and rarely the interesting one on monitored infrastructure.

“Is this machine on mains power?” is often the real check. power_source reads ac, battery or unknown, so a UPS-backed or laptop-as-server host can alert the moment it drops to battery, long before the charge level matters:

check_battery "crit=power_source = 'battery'" "warn=none"

“Is the battery worn out?” is what health is for — full charge capacity as a percentage of design capacity. A battery at 60% health still charges to “100%” and looks fine to a charge-level check while holding barely half its rated runtime:

check_battery "warn=health < 70" "crit=health < 50"

health is emitted as performance data, so the decline is visible as a trend long before it crosses a threshold.

Runtime and rates

time_remaining is the estimated seconds left, and is -1 when unknown or on AC — so guard any threshold on it with a power_source = 'battery' clause, otherwise time_remaining < 600 fires on every mains-powered host. charge_rate and discharge_rate (mW) and the design_capacity / full_capacity / remaining_capacity triple (mWh) are available for the detailed view.

Data sources

On Windows the data comes from the Windows power/battery APIs. On Linux it is read from /sys/class/power_supply, so batteries exposed by the ACPI or platform driver are visible; a battery behind a vendor-specific driver that does not populate sysfs will not be. battery_status carries the charging state (status is a deprecated alias — the name clashes with the generic status summary keyword and resolves to that in top-syntax).

Check battery charge level, power source and health.

About check_battery

check_battery reports the state of the machine’s batteries: charge level, which power source it is on, and battery health. One record is returned per battery.

The default filter is battery_present = 'true', and the thresholds are charge < 20 (warning) and charge < 10 (critical).

On a machine with no battery — a desktop, a server, a VM — the filter matches nothing, and the empty state is warning, so the check reports WARNING: No battery found. That is almost never what you want on infrastructure: set empty-state=ok (or empty-state=ignored) on any host where a missing battery is normal, otherwise every server running this check sits permanently in WARNING.

The three questions it answers

“Is this laptop about to die?” is the default, and rarely the interesting one on monitored infrastructure.

“Is this machine on mains power?” is often the real check. power_source reads ac, battery or unknown, so a UPS-backed or laptop-as-server host can alert the moment it drops to battery, long before the charge level matters:

check_battery "crit=power_source = 'battery'" "warn=none"

“Is the battery worn out?” is what health is for — full charge capacity as a percentage of design capacity. A battery at 60% health still charges to “100%” and looks fine to a charge-level check while holding barely half its rated runtime:

check_battery "warn=health < 70" "crit=health < 50"

health is emitted as performance data, so the decline is visible as a trend long before it crosses a threshold.

Runtime and rates

time_remaining is the estimated seconds left, and is -1 when unknown or on AC — so guard any threshold on it with a power_source = 'battery' clause, otherwise time_remaining < 600 fires on every mains-powered host. charge_rate and discharge_rate (mW) and the design_capacity / full_capacity / remaining_capacity triple (mWh) are available for the detailed view.

Data sources

On Windows the data comes from the Windows power/battery APIs. On Linux it is read from /sys/class/power_supply, so batteries exposed by the ACPI or platform driver are visible; a battery behind a vendor-specific driver that does not populate sysfs will not be. battery_status carries the charging state (status is a deprecated alias — the name clashes with the generic status summary keyword and resolves to that in top-syntax).

Jump to section:

Sample Commands

A host with no battery:

The default filter is battery_present = 'true', and the empty state is warning — so a desktop, server or VM reports WARNING out of the box.

check_battery
WARNING: No battery found

Which is almost never what you want on infrastructure:

check_battery "empty-state=ok"
OK: No battery found

Set empty-state=ok (or ignored) on every host where a missing battery is normal, or the check sits permanently in WARNING.

Default check on a laptop (charge < 20 warns, < 10 is critical):

check_battery
OK: BAT0: 87% (ac, charging)|'BAT0_charge'=87%;20;10;0;100 'BAT0_health'=92%;0;0;0;100

Alert the moment the host drops off mains power:

Often the real check on a UPS-backed or laptop-as-server host — long before the charge level matters.

check_battery "crit=power_source = 'battery'" "warn=none"
CRITICAL: BAT0: 87% (battery, discharging)

Alert on a worn-out battery:

health is full charge capacity as a percentage of design capacity. A battery at 60% health still charges to “100%” and looks fine to a charge-level check.

check_battery "warn=health < 70" "crit=health < 50"
WARNING: BAT0: 100% (ac, full)|'BAT0_health'=64%;70;50;0;100

Threshold on remaining runtime — guard it with a power-source clause:

time_remaining is -1 when unknown or on AC, so an unguarded threshold fires on every mains-powered host.

check_battery "crit=power_source = 'battery' and time_remaining < 600" "detail-syntax=${name}: ${charge}% ${time_remaining}s left"
OK: BAT0: 87% -1s left

Inspect the capacity figures:

check_battery "detail-syntax=${name} rem=${remaining_capacity} full=${full_capacity} design=${design_capacity} rate=${discharge_rate}"
OK: BAT0 rem=48120 full=55300 design=60000 rate=0

Command-line Arguments

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter battery_present = ‘true’
warning charge < 20
warn
critical charge < 10
crit
ok
debug false
show-all false
empty-state warning
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax %(status): No battery found or all batteries ok.
empty-syntax No battery found
detail-syntax ${name}: ${charge}% (${power_source}, ${battery_status})
perf-syntax ${name}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
battery_present Whether a battery is present: ‘true’ or ‘false’
battery_status Battery status: ‘charging’, ‘discharging’, ‘high’, ‘low’, ‘critical’, ‘no_battery’, or ‘unknown’
charge Battery charge level in percent (0-100)
charge_rate Current charge rate in mW (when charging)
design_capacity Design capacity in mWh
discharge_rate Current discharge rate in mW (when discharging)
full_capacity Current full charge capacity in mWh
health Battery health in percent (full_capacity / design_capacity * 100)
name Battery name/identifier
power_source Power source: ‘ac’, ‘battery’, or ‘unknown’
remaining_capacity Current remaining capacity in mWh
time_remaining Estimated time remaining in seconds (-1 if unknown or on AC)

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

Option Description
battery_present Whether a battery is present: ‘true’ or ‘false’
battery_status Charge status
charge Battery charge percent
charge_rate Current charge rate in mW (when charging)
design_capacity Design capacity in mWh
discharge_rate Current discharge rate in mW (when discharging)
full_capacity Current full charge capacity in mWh
health Battery health percent (full/design capacity)
name Battery name
power_source Power source: ac/battery/unknown
present Alias for battery_present
remaining_capacity Current remaining capacity in mWh
time_remaining Estimated time remaining in seconds (-1 if unknown or on AC)

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_cpu

Check that the load of the CPU(s) are within bounds.

The check_cpu command is a query based command which means it has a filter where you can use a filter expression with filter keywords to define which rows are relevant to the check. The filter is written using the filter query language and in it you can use various filter keywords to define the filtering logic. The filter keywords can also be used to create the bound expressions for the warning and critical which defines when a check returns warning or critical.

How CPU load is measured (historical buffer)

check_cpu does not measure the CPU load at the moment the check is executed. Instead, NSClient++ runs a background collector thread that samples the CPU load roughly once per second and pushes each sample into an in-memory ring buffer. Whenever you run check_cpu the values reported are averages computed from this buffer for one or more time windows.

The time windows are controlled by the time= option. The default is to compute three averages: 5m, 1m and 5s (which is why the default output contains rows like total 5m load, total 1m load and total 5s load). You can override this with one or more time= arguments, for example time=10m or time=30s time=2m.

Buffer size and configuration

The size of the historical buffer is controlled by the default buffer length setting on the CheckSystem section. The default is 1h, meaning the last hour of samples is retained. The buffer size puts an upper bound on the time windows you can use:

  • If you ask for a window that is shorter than or equal to the buffer length, the result is the average of all samples collected during that window.
  • If you ask for a window that is longer than the buffer length, the result will only cover the samples that are actually present in the buffer (effectively capped to the buffer length).
  • If NSClient++ was started less time ago than the requested window, the result will only reflect the samples collected since startup. Right after start-up 5m and 1m averages will therefore be based on fewer samples than they normally would be.

If you need to check on longer windows (for example 2h or 6h) you must increase default buffer length accordingly. Note that a larger buffer uses more memory, so only increase it as far as you actually need.

Impact on measurements

Because every value reported by check_cpu is an average over a time window, the choice of time= has a direct impact on what the check sees:

  • Short windows (e.g. 5s, 10s) are very reactive and will show short spikes in CPU load, but they also produce a lot of noise. They are useful for catching transient bursts but can also generate flapping alerts.
  • Medium windows (e.g. 1m, 5m) are a good compromise for most monitoring use cases. They smooth out short spikes while still reacting to sustained load within a few minutes.
  • Long windows (e.g. 15m, 1h) smooth out almost all transients and only fire when the CPU has been busy for an extended period of time. They are well suited to detecting sustained load but will be slow to react and slow to recover.

A common pattern is to combine windows, for example warning on a long window and critical on a short one (or vice versa), so that the check both catches sustained problems and ignores brief spikes. The default check (5m, 1m, 5s) is an example of this approach.

Because the values are averages, they will not match the instantaneous CPU load shown by tools such as top at the moment the check is executed, and very short spikes that fall between collection ticks may be missed entirely.

Interaction with the disable setting (Windows only)

On Windows the collector that feeds this buffer can be turned off with disable = cpu in [/settings/system/windows]. In that case check_cpu returns UNKNOWN with an explanatory message rather than reporting values from a buffer that is no longer updated. The entries in disable are matched as whole tokens, so disable = cpu_frequency only disables the CPU frequency collector and leaves check_cpu unaffected.

The Linux module has no disable setting; its collector is always running.

Check that the load of the CPU(s) are within bounds.

How CPU load is measured (historical buffer)

check_cpu does not measure the CPU load at the moment the check is executed. Instead, NSClient++ runs a background collector thread that samples the CPU load roughly once per second and pushes each sample into an in-memory ring buffer. Whenever you run check_cpu the values reported are averages computed from this buffer for one or more time windows.

The time windows are controlled by the time= option. The default is to compute three averages: 5m, 1m and 5s (which is why the default output contains rows like total 5m load, total 1m load and total 5s load). You can override this with one or more time= arguments, for example time=10m or time=30s time=2m.

Buffer size and configuration

The size of the historical buffer is controlled by the default buffer length setting on the CheckSystem section. The default is 1h, meaning the last hour of samples is retained. The buffer size puts an upper bound on the time windows you can use:

  • If you ask for a window that is shorter than or equal to the buffer length, the result is the average of all samples collected during that window.
  • If you ask for a window that is longer than the buffer length, the result will only cover the samples that are actually present in the buffer (effectively capped to the buffer length).
  • If NSClient++ was started less time ago than the requested window, the result will only reflect the samples collected since startup. Right after start-up 5m and 1m averages will therefore be based on fewer samples than they normally would be.

If you need to check on longer windows (for example 2h or 6h) you must increase default buffer length accordingly. Note that a larger buffer uses more memory, so only increase it as far as you actually need.

Impact on measurements

Because every value reported by check_cpu is an average over a time window, the choice of time= has a direct impact on what the check sees:

  • Short windows (e.g. 5s, 10s) are very reactive and will show short spikes in CPU load, but they also produce a lot of noise. They are useful for catching transient bursts but can also generate flapping alerts.
  • Medium windows (e.g. 1m, 5m) are a good compromise for most monitoring use cases. They smooth out short spikes while still reacting to sustained load within a few minutes.
  • Long windows (e.g. 15m, 1h) smooth out almost all transients and only fire when the CPU has been busy for an extended period of time. They are well suited to detecting sustained load but will be slow to react and slow to recover.

A common pattern is to combine windows, for example warning on a long window and critical on a short one (or vice versa), so that the check both catches sustained problems and ignores brief spikes. The default check (5m, 1m, 5s) is an example of this approach.

Because the values are averages, they will not match the instantaneous CPU load shown by tools such as top at the moment the check is executed, and very short spikes that fall between collection ticks may be missed entirely.

Interaction with the disable setting (Windows only)

On Windows the collector that feeds this buffer can be turned off with disable = cpu in [/settings/system/windows]. In that case check_cpu returns UNKNOWN with an explanatory message rather than reporting values from a buffer that is no longer updated. The entries in disable are matched as whole tokens, so disable = cpu_frequency only disables the CPU frequency collector and leaves check_cpu unaffected.

The Linux module has no disable setting; its collector is always running.

Jump to section:

Sample Commands

Default check:

check_cpu
CPU Load ok
'total 5m load'=0%;80;90 'total 1m load'=0%;80;90 'total 5s load'=7%;80;90

Checking all cores by adding filter=none (disabling the default filter):

check_cpu filter=none "warn=load > 80" "crit=load > 90"
CPU Load ok
'core 0 5m kernel'=1%;10;0 'core 0 5m load'=3%;80;90 'core 1 5m kernel'=0%;10;0 'core 1 5m load'=0%;80;90 ...  'core 7 5s load'=15%;80;90 'total 5s kernel'=3%;10;0 'total 5s load'=7%;80;90

Adding kernel times to the check:

check_cpu filter=none "warn=kernel > 10 or load > 80" "crit=load > 90" "top-syntax=${list}"
core 0 > 3, core 1 > 0, core 2 > 0, core  ... , core 7 > 15, total > 7
'core 0 5m kernel'=1%;10;0 'core 0 5m load'=3%;80;90 'core 1 5m kernel'=0%;10;0 'core 1 5m load'=0%;80;90 ...  'core 7 5s load'=15%;80;90 'total 5s kernel'=3%;10;0 'total 5s load'=7%;80;90

Default check via NRPE:

check_nscp --host 192.168.56.103 --command check_cpu
CPU Load ok|'total 5m'=16%;80;90 'total 1m'=13%;80;90 'total 5s'=13%;80;90

Customizing the output syntax to include CPU load in text:

check_cpu "top-syntax=%(status): %(list)"
L        cli OK: OK: 5m: 16%, 1m: 30%, 5s: 23%

Customizing the output syntax to only show CPU load as text:

check_cpu "top-syntax=%(status): Cpu usage is %(list)" time=5m "detail-syntax=%(load) %"
L        cli OK: OK: Cpu usage is 26 %

Full user/system/idle breakdown as perfdata (parity with the Linux check_cpu_utilization graph):

idle and system now emit perfdata (previously only usage/user did), so the full breakdown graphs without a custom top-syntax. kernel is a deprecated alias of system and intentionally emits no separate perf column; total is a deprecated alias of usage (the name clashes with the generic total summary keyword).

check_cpu "warn=idle < 5"
CPU Load ok
'total 5m load'=7%;80;90 'total 5m user'=4%;;; 'total 5m system'=3%;;; 'total 5m idle'=93%;;; ...

Command-line Arguments

Option Default Value Description
time The time to check
cores N/A This will remove the filter to include the cores, if you use filter dont use this as well.

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter core = ‘total’
warning load > 80
warn
critical load > 90
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${problem_list}
ok-syntax %(status): CPU load is ok.
empty-syntax
detail-syntax ${time}: ${load}%
perf-syntax ${core} ${time}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Option Default Value Description
time The time to check
cores N/A This will remove the filter to include the cores, if you use filter don’t use this as well.

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter core = ‘total’
warning load > 80
warn
critical load > 90
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${problem_list}
ok-syntax %(status): CPU load is ok.
empty-syntax
detail-syntax ${time}: ${load}%
perf-syntax ${core} ${time}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
core The core to check (total or core ##)
core_id The core to check (total or core_##)
idle The current idle load for a given core
kernel deprecated (use system instead)
load deprecated (use usage instead)
system The current load used by the system (kernel)
time The time frame to check
usage The current load used by user and system
user The current load used by user applications

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

Option Description
core The core to check (total or core ##)
core_id The core to check (total or core_##)
idle The current idle load for a given core
kernel deprecated (use system instead)
load The current load for a given core (deprecated, use usage)
system The current load used by the system (kernel)
time The time frame to check
usage The current load used by user and system
user The current load used by user applications

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_cpu_frequency

Check CPU clock frequency (current vs max) per processor.

Reports per-CPU-socket frequency, load and hardware inventory, sourced from the Win32_Processor WMI class (one instance per physical socket).

There are no default warning/critical thresholds: modern CPUs legitimately clock far below their maximum at idle, so a frequency_pct default would warn on every idle machine. Use load_pct for a per-socket utilisation alert. WMI does not always have a load sample ready: on such a cycle load_pct renders as no load sample, compares false against every numeric threshold and emits no perfdata (it is never a fabricated 0, which is a valid idle reading); load_pct = 'no load sample' is the presence test. The inventory columns (architecture, l2_cache, l3_cache) make the check double as the per-socket CPU hardware inventory; pin them to detect a re-imaged or migrated box (crit=architecture != 'x64').

Check the CPU clock frequency (current vs max) per core.

Reports per-CPU-socket frequency, load and hardware inventory, sourced from the Win32_Processor WMI class (one instance per physical socket).

There are no default warning/critical thresholds: modern CPUs legitimately clock far below their maximum at idle, so a frequency_pct default would warn on every idle machine. Use load_pct for a per-socket utilisation alert. WMI does not always have a load sample ready: on such a cycle load_pct renders as no load sample, compares false against every numeric threshold and emits no perfdata (it is never a fabricated 0, which is a valid idle reading); load_pct = 'no load sample' is the presence test. The inventory columns (architecture, l2_cache, l3_cache) make the check double as the per-socket CPU hardware inventory; pin them to detect a re-imaged or migrated box (crit=architecture != 'x64').

Jump to section:

Sample Commands

Default check:

check_cpu_frequency
OK: Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz: 2900/4800 MHz (60%)
'Intel...'=2900MHz;;; 'Intel..._max_mhz'=4800MHz;;; 'Intel..._frequency_pct'=60%;;; 'Intel..._load_pct'=12%;;;

Per-socket filtering and load:

Win32_Processor returns one row per physical CPU socket, exposed via socket_id (DeviceID, e.g. CPU0) and socket (SocketDesignation, e.g. CPU 1). The load_pct keyword reports Win32_Processor.LoadPercentage per socket.

check_cpu_frequency "filter=socket_id = 'CPU0'" "warn=load_pct > 90" "detail-syntax=${socket}: ${load_pct}% @ ${current_mhz}MHz"
OK: CPU 1: 12% @ 2900MHz
'Intel..._load_pct'=12%;90;;

CPU hardware inventory (model, architecture, cores/threads, cache):

check_cpu_frequency "detail-syntax=${name}: ${architecture}, ${cores}c/${logical_processors}t, L2 ${l2_cache}, L3 ${l3_cache}"
OK: Intel(R) Core(TM) Ultra 7 265H: x64, 16c/16t, L2 28MB, L3 24MB

Pin expected hardware (re-imaged / migrated box detection):

check_cpu_frequency "warn=l3_cache < 1M" "crit=architecture != 'x64'"
OK: Intel(R) Core(TM) Ultra 7 265H: 2200/2200 MHz (100%)

Command-line Arguments

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning
warn
critical
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax %(status): All CPU frequencies seem ok.
empty-syntax
detail-syntax ${name}: ${current_mhz}/${max_mhz} MHz (${frequency_pct}%)
perf-syntax ${name}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
architecture Processor architecture (x86, x64, ARM64, …)
cores Number of physical cores
current_mhz Current clock speed in MHz (perfdata)
frequency_pct Current frequency as percentage of maximum (perfdata)
l2_cache L2 cache size (size units work, e.g. ‘l2_cache < 1M’); renders human-readable; 0 when not reported
l3_cache L3 cache size; 0 when not reported (common on VMs)
load_pct Per-socket CPU load as reported by Win32_Processor.LoadPercentage (perfdata); ‘no load sample’ when WMI has no reading this cycle
logical_processors Number of logical processors (threads)
max_mhz Maximum clock speed in MHz (perfdata)
name CPU name / model string
socket Socket designation (e.g. “CPU 1”), for per-socket filtering
socket_id Socket device id (e.g. CPU0), for per-socket filtering

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_cpu_utilization

Available on Linux only.

Check CPU utilization broken down by user/system/iowait/steal/guest.

About check_cpu_utilization

check_cpu_utilization reports how the CPU’s time is being spent, broken down by mode. It reads the aggregate cpu line from /proc/stat, waits ~1 second, reads it again, and reports the delta as percentages — so it measures live utilization over that sampling window rather than since boot.

All numeric keywords are percentages (0–100).

Default thresholds: warning usage > 90, critical usage > 95 (total still works as a deprecated alias for usage; it was renamed to avoid clashing with the generic total summary keyword). This differs from check_cpu, which averages utilization over rolling time windows (1m/5m/15m) from the background collector; check_cpu_utilization takes a single fresh 1-second sample and exposes the per-mode breakdown, which is what you want to distinguish user vs. iowait vs. steal pressure.

Jump to section:

Sample Commands

CPU utilization broken down by mode:

check_cpu_utilization
OK: user: 1.39% system: 1.54% iowait: 0% steal: 0% idle: 95.73%
L        cli  Performance data: 'cpu_usage'=4.27;90;95 'cpu_user'=1.39;0;0 'cpu_system'=1.54;0;0 'cpu_iowait'=0;0;0 'cpu_steal'=0;0;0 'cpu_idle'=95.73;0;0 ...

Custom thresholds on total busy percentage (the default is usage > 90 / > 95):

check_cpu_utilization "warn=usage > 80" "crit=usage > 95"
OK: user: 2.1% system: 1.8% iowait: 0.2% steal: 0% idle: 95.9%

Alert specifically on I/O wait (storage saturation):

check_cpu_utilization "warn=iowait > 20" "crit=iowait > 50"
OK: user: 1.4% system: 1.5% iowait: 0% steal: 0% idle: 95.7%

Alert on steal time (noisy-neighbour on a VM):

check_cpu_utilization "warn=steal > 5" "crit=steal > 15"
OK: user: 1.4% system: 1.5% iowait: 0% steal: 0% idle: 95.7%

Command-line Arguments

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning usage > 90
warn
critical usage > 95
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax user: ${user}% system: ${system}% iowait: ${iowait}% steal: ${steal}% idle: ${idle}%
perf-syntax cpu
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
guest CPU time spent running a guest under this kernel, in percent (incl. guest_nice)
idle Idle CPU in percent
iowait I/O-wait CPU utilization in percent
irq Hardware-interrupt CPU utilization in percent
name Always ‘total’ (single aggregate row)
softirq Soft-interrupt CPU utilization in percent
steal CPU time stolen by the hypervisor in percent (VM guests)
system System/kernel CPU utilization in percent
usage Non-idle CPU utilization in percent (100 - idle - iowait)
user User (incl. nice) CPU utilization in percent

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_hardware

Available on Windows only.

Check hardware inventory (vendor, model, serial, chassis type, memory modules) with pinned-expectation alerting: serial changed, DIMM dropped, laptop in a server fleet.

About check_hardware

check_hardware reports BIOS/chassis/memory hardware inventory from WMI (root\CIMV2): Win32_ComputerSystemProduct (vendor, model, UUID, serial), Win32_SystemEnclosure (chassis type, enclosure serial, asset tag), Win32_PhysicalMemory (per-DIMM inventory) and Win32_PhysicalMemoryArray (total sockets). It complements check_os_version — that check answers “what OS am I running” (and carries the BIOS serial/version for back-compat), this one answers “what box am I”.

The useful alerts are pinned expectations and changes, not thresholds on a moving value:

  • “Did the hardware change?”crit=serial != 'ABC1234' catches a re-imaged, replaced or cloned box.
  • “Did a DIMM drop?”warn=modules < 8 / crit=memory < 64G catch a failed module long before the OS-level memory checks look abnormal.
  • “Is this the right kind of machine?”crit=chassis like 'Laptop' in a server fleet, or warn=modules < slots-style capacity planning via the slots count.

There are no default thresholds (a bare call is an inventory line); memory and modules are always emitted as perf data (hardware_memory, hardware_modules). Per-item keywords such as module_list belong in detail-syntax (the default top-syntax embeds them via ${list}).

Caveats: VMs and OEM boards frequently report blank or placeholder values — serials like To be filled by O.E.M., chassis Other, slots 0 — so baseline a host before pinning expectations on it. Each WMI class is read best-effort: a class that is missing (stripped-down VMs) leaves its fields empty rather than failing the check, and the check only errors when no class answers (WMI down). ConfiguredClockSpeed falls back to the raw Speed on older Windows.

Jump to section:

Sample Commands

Default check (inventory line with memory/module perf):

check_hardware
OK: Dell Inc. Dell Pro Max 16 MC16250 (Notebook), serial=ABC1234, 2 memory module(s), 32GB|'hardware_memory'=34359738368;0;0 'hardware_modules'=2;0;0

Pin the expected serial (CRITICAL when the box was replaced or re-imaged):

check_hardware "crit=serial != 'ABC1234'"
OK: Dell Inc. Dell Pro Max 16 MC16250 (Notebook), serial=ABC1234, 2 memory module(s), 32GB

check_hardware "crit=serial != 'XYZ0000'"
CRITICAL: Dell Inc. Dell Pro Max 16 MC16250 (Notebook), serial=ABC1234, 2 memory module(s), 32GB

Detect a dropped DIMM (module count or total capacity shrank):

check_hardware "warn=modules < 2" "crit=memory < 16G"
OK: Dell Inc. Dell Pro Max 16 MC16250 (Notebook), serial=ABC1234, 2 memory module(s), 32GB|'hardware_memory'=34359738368;0;17179869184 'hardware_modules'=2;2;0

Enforce machine class (no laptops in the server fleet):

check_hardware "warn=chassis like 'Laptop' or chassis like 'Notebook'"
WARNING: Dell Inc. Dell Pro Max 16 MC16250 (Notebook), serial=ABC1234, 2 memory module(s), 32GB

Per-DIMM inventory and socket usage:

check_hardware "detail-syntax=${module_list} (slots=${slots}, speed=${memory_speed}MHz, chassis=${chassis})"
OK: DIMM A: 16GB@5600MHz; DIMM B: 16GB@5600MHz (slots=2, speed=5600MHz, chassis=Notebook)

Over NRPE against a remote host:

check_nscp_client --host 192.168.56.103 --command check_hardware --argument "crit=serial != 'ABC1234'"
OK: Dell Inc. Dell Pro Max 16 MC16250 (Notebook), serial=ABC1234, 2 memory module(s), 32GB

Command-line Arguments

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning
warn
critical
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax ${vendor} ${model} (${chassis}), serial=${serial}, ${modules} memory module(s), ${memory}
perf-syntax hardware
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
asset_tag SMBIOS asset tag
chassis Chassis type name (Desktop, Laptop, Rack Mount Chassis, …)
chassis_serial Enclosure serial number
chassis_type Raw SMBIOS chassis type number (0 when unknown)
memory Total installed memory (supports size units, e.g. ‘memory < 64G’); renders human-readable
memory_speed Slowest populated module’s configured clock in MHz (0 when unknown)
model System model / product name
module_list Semicolon-separated per-DIMM inventory (slot: size@speed, e.g. ‘DIMM_A1: 32GB@4800MHz’)
modules Number of populated memory modules
serial System serial number (often blank or placeholder on VMs and OEM boards)
slots Total memory sockets on the board (0 when not reported)
uuid SMBIOS system UUID
vendor System vendor/manufacturer

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_hostname

Check host identity: hostname, FQDN, DNS domain and domain-join state, with drift detection for the name mismatches that silently break auth and monitoring.

About check_hostname

check_hostname reports host identity — hostname, FQDN and DNS domain (plus domain-join state on Windows) — and detects the name drift that silently breaks Kerberos auth, certificate validation and monitoring host-matching.

The shared keywords (hostname, fqdn, domain, fqdn_consistent) carry the same meaning on both platforms. The check returns a single aggregate row, has no default thresholds — whether workgroup is wrong is site policy — and emits no performance data (there is no meaningful number here). Comparisons are case-insensitive, since DNS is case-insensitive and case differences are not drift.

Windows

Reads GetComputerNameEx (NetBIOS name, DNS hostname, DNS suffix, FQDN) and NetGetJoinInformation (joined domain or workgroup); no WMI involved. Two extra keywords are available here: join / join_name (Active Directory membership) and netbios_matches_dns.

The useful alerts are pinned expectations:

  • “Is this box still on the domain?”crit=join != 'domain' or crit=domain != 'corp.example.com' catches domain-join / workgroup drift.
  • “Is the name coherent?”warn=fqdn_consistent = 0 (the FQDN no longer equals dns_hostname.domain: DNS-suffix drift) and warn=netbios_matches_dns = 0 (NetBIOS name diverged from the DNS hostname after a rename or re-image).
  • “Is this the host I think it is?”crit=hostname != 'WEB01' on cloned/re-imaged machines.

A host with no DNS suffix reports fqdn == hostname as consistent, not as drift, and the NetBIOS comparison tolerates the 15-character truncation of longer DNS names.

Linux

Reads gethostname() and canonicalises it with getaddrinfo(AI_CANONNAME); when the host cannot be resolved (containers, hosts without DNS) the FQDN falls back to the bare hostname, which is treated as consistent rather than as drift. join / join_name / netbios_matches_dns have no clean Linux equivalent and are absent here.

The useful alerts are pinned expectations:

  • “Is this the host I think it is?”crit=hostname != 'web01', crit=domain != 'corp.example.com'.
  • “Is the name coherent?”warn=fqdn_consistent = 0 flags the resolver canonicalising this host under a different name (stale /etc/hosts entries, CNAME chains, re-imaged boxes keeping an old DNS record).
See also

CheckSecurity’s check_nla covers the runtime side of the same question — which network profile (domain/private/public) the host is currently on.

Check host identity: hostname, canonical FQDN and DNS domain, with drift detection for the name mismatches that silently break auth and monitoring.

About check_hostname

check_hostname reports host identity — hostname, FQDN and DNS domain (plus domain-join state on Windows) — and detects the name drift that silently breaks Kerberos auth, certificate validation and monitoring host-matching.

The shared keywords (hostname, fqdn, domain, fqdn_consistent) carry the same meaning on both platforms. The check returns a single aggregate row, has no default thresholds — whether workgroup is wrong is site policy — and emits no performance data (there is no meaningful number here). Comparisons are case-insensitive, since DNS is case-insensitive and case differences are not drift.

Windows

Reads GetComputerNameEx (NetBIOS name, DNS hostname, DNS suffix, FQDN) and NetGetJoinInformation (joined domain or workgroup); no WMI involved. Two extra keywords are available here: join / join_name (Active Directory membership) and netbios_matches_dns.

The useful alerts are pinned expectations:

  • “Is this box still on the domain?”crit=join != 'domain' or crit=domain != 'corp.example.com' catches domain-join / workgroup drift.
  • “Is the name coherent?”warn=fqdn_consistent = 0 (the FQDN no longer equals dns_hostname.domain: DNS-suffix drift) and warn=netbios_matches_dns = 0 (NetBIOS name diverged from the DNS hostname after a rename or re-image).
  • “Is this the host I think it is?”crit=hostname != 'WEB01' on cloned/re-imaged machines.

A host with no DNS suffix reports fqdn == hostname as consistent, not as drift, and the NetBIOS comparison tolerates the 15-character truncation of longer DNS names.

Linux

Reads gethostname() and canonicalises it with getaddrinfo(AI_CANONNAME); when the host cannot be resolved (containers, hosts without DNS) the FQDN falls back to the bare hostname, which is treated as consistent rather than as drift. join / join_name / netbios_matches_dns have no clean Linux equivalent and are absent here.

The useful alerts are pinned expectations:

  • “Is this the host I think it is?”crit=hostname != 'web01', crit=domain != 'corp.example.com'.
  • “Is the name coherent?”warn=fqdn_consistent = 0 flags the resolver canonicalising this host under a different name (stale /etc/hosts entries, CNAME chains, re-imaged boxes keeping an old DNS record).
See also

CheckSecurity’s check_nla covers the runtime side of the same question — which network profile (domain/private/public) the host is currently on.

Jump to section:

Sample Commands

Default check (identity line):

check_hostname
OK: WEB01 (web01.corp.example.com), domain=corp.example.com

On a Windows workgroup machine:

check_hostname
OK: MYPC (MyPC), workgroup=WORKGROUP

On a Linux host without DNS (e.g. a container), the FQDN falls back to the hostname:

check_hostname
OK: container123 (container123), domain=

Pin the expected identity (cloned or re-imaged box detection):

check_hostname "crit=hostname != 'web01' or domain != 'corp.example.com'"
OK: web01 (web01.corp.example.com), domain=corp.example.com

Detect name drift (the resolver canonicalises this host under another name):

check_hostname "warn=fqdn_consistent = 0"
WARNING: web01 (web01-old.corp.example.com), domain=corp.example.com

Require domain membership — Windows only (CRITICAL on domain-join / workgroup drift):

check_hostname "crit=join != 'domain'"
CRITICAL: MYPC (MyPC), workgroup=WORKGROUP

check_hostname "crit=join != 'domain' or domain != 'corp.example.com'"
OK: WEB01 (web01.corp.example.com), domain=corp.example.com

Detect NetBIOS drift — Windows only:

check_hostname "warn=fqdn_consistent = 0 or netbios_matches_dns = 0"
OK: WEB01 (web01.corp.example.com), domain=corp.example.com

Inspect all identity fields:

check_hostname "detail-syntax=h=${hostname} f=${fqdn} d=${domain} ok=${fqdn_consistent}"
OK: h=web01 f=web01.corp.example.com d=corp.example.com ok=1

On Windows the NetBIOS and DNS names are separate fields:

check_hostname "detail-syntax=nb=${hostname} dns=${dns_hostname} dom=${domain} fq=${fqdn} ok=${fqdn_consistent}/${netbios_matches_dns}"
OK: nb=WEB01 dns=web01 dom=corp.example.com fq=web01.corp.example.com ok=1/1

Over NRPE against a remote host:

check_nrpe --host 192.168.56.103 --command check_hostname --arguments "crit=domain != 'corp.example.com'"
OK: web01 (web01.corp.example.com), domain=corp.example.com

Command-line Arguments

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning
warn
critical
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax ${hostname} (${fqdn}), ${join}=${join_name}
perf-syntax hostname
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning
warn
critical
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax ${hostname} (${fqdn}), domain=${domain}
perf-syntax hostname
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
dns_hostname DNS hostname (the local label)
domain Primary DNS suffix (empty when none is configured)
fqdn Fully qualified DNS name
fqdn_consistent True when fqdn == dns_hostname[.domain] (case-insensitive); false flags DNS-suffix drift
hostname NetBIOS computer name (max 15 characters)
join Join state: domain, workgroup, standalone or unknown
join_name The joined domain or workgroup name
netbios_matches_dns True when the NetBIOS name matches the first 15 characters of the DNS hostname; false flags rename/imaging drift

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

Option Description
domain DNS domain (the FQDN with the first label removed; empty when none)
fqdn Canonical fully qualified name from the resolver (hostname when unresolvable)
fqdn_consistent True when the FQDN equals, or starts with, the configured hostname; false flags DNS drift (the resolver canonicalises this host under a different name)
hostname Configured hostname (gethostname)

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_installed_software

Check installed software from the registry Uninstall hives (64-bit, 32-bit and per-user views): inventory, unwanted/EOL software policy and recent-install detection.

About check_installed_software

check_installed_software inventories installed software and answers three operator questions:

  • “Is unwanted or EOL software present?”crit=name like 'BitTorrent' (an empty match set is OK, so an absence probe is cheap).
  • “What was installed recently?”warn=install_date > -7d correlates incidents with fresh installs.
  • “What is installed at all?” — a bare call is an OK inventory with the package count as perf data.

Each installed product is one row. There are no default thresholds (a bare call is an inventory), an empty match set returns OK, and the matched package count is emitted as count perf data. The shared keywords (name, version, publisher, install_date, size, architecture) carry the same meaning on both platforms; version comparisons are plain string comparisons everywhere, so pin patterns (e.g. version like '7.') rather than relying on numeric ordering across multi-digit components.

Windows

Reads the registry Uninstall hives — HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall in both the 64-bit and 32-bit (Wow6432Node) views, plus every loaded per-user hive under HKEY_USERS (which covers per-user installs such as VS Code, JetBrains IDEs and Electron apps, regardless of the account the service runs as). The hive keyword says which view a row came from.

The default filter is system_component = 0, matching what Add/Remove Programs shows; pass filter=none to include runtime/driver components.

Caveats: InstallDate is best-effort — many installers never write it (the install_date expressions simply never match such entries), and MSI stamps it on every repair/modify, not only the original install. Legacy patch entries (children with ParentKeyName) and entries without a DisplayName are skipped.

Linux

Reads the system package manager — dpkg-query on Debian/Ubuntu, rpm -qa on RHEL/Fedora/SUSE, pacman -Q on Arch (detected in that order, dpkg first because Debian-family hosts frequently carry an rpm binary too). The manager keyword says which one was used.

Only packages whose dpkg state is exactly installed are listed: removed (not-installed), config-files leftovers and broken (half-installed, unpacked) packages are skipped, while held packages (hold ok installed) are kept. If the package-manager query itself fails, the check returns UNKNOWN rather than an empty “no installed software found” inventory, so a broken package database can never read as a clean OK.

Caveats: install dates are exact on rpm (INSTALLTIME); dpkg does not record them, so they are approximated from the mtime of the package’s /var/lib/dpkg/info/<name>[:<arch>].list file (rewritten on upgrade — treat as “last installed/upgraded”). pacman -Q exposes only name and version, so publisher, size and install_date stay unset there.

Check installed software packages via the system package manager (dpkg/rpm/pacman): inventory, unwanted/EOL software policy and recent-install detection.

About check_installed_software

check_installed_software inventories installed software and answers three operator questions:

  • “Is unwanted or EOL software present?”crit=name like 'BitTorrent' (an empty match set is OK, so an absence probe is cheap).
  • “What was installed recently?”warn=install_date > -7d correlates incidents with fresh installs.
  • “What is installed at all?” — a bare call is an OK inventory with the package count as perf data.

Each installed product is one row. There are no default thresholds (a bare call is an inventory), an empty match set returns OK, and the matched package count is emitted as count perf data. The shared keywords (name, version, publisher, install_date, size, architecture) carry the same meaning on both platforms; version comparisons are plain string comparisons everywhere, so pin patterns (e.g. version like '7.') rather than relying on numeric ordering across multi-digit components.

Windows

Reads the registry Uninstall hives — HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall in both the 64-bit and 32-bit (Wow6432Node) views, plus every loaded per-user hive under HKEY_USERS (which covers per-user installs such as VS Code, JetBrains IDEs and Electron apps, regardless of the account the service runs as). The hive keyword says which view a row came from.

The default filter is system_component = 0, matching what Add/Remove Programs shows; pass filter=none to include runtime/driver components.

Caveats: InstallDate is best-effort — many installers never write it (the install_date expressions simply never match such entries), and MSI stamps it on every repair/modify, not only the original install. Legacy patch entries (children with ParentKeyName) and entries without a DisplayName are skipped.

Linux

Reads the system package manager — dpkg-query on Debian/Ubuntu, rpm -qa on RHEL/Fedora/SUSE, pacman -Q on Arch (detected in that order, dpkg first because Debian-family hosts frequently carry an rpm binary too). The manager keyword says which one was used.

Only packages whose dpkg state is exactly installed are listed: removed (not-installed), config-files leftovers and broken (half-installed, unpacked) packages are skipped, while held packages (hold ok installed) are kept. If the package-manager query itself fails, the check returns UNKNOWN rather than an empty “no installed software found” inventory, so a broken package database can never read as a clean OK.

Caveats: install dates are exact on rpm (INSTALLTIME); dpkg does not record them, so they are approximated from the mtime of the package’s /var/lib/dpkg/info/<name>[:<arch>].list file (rewritten on upgrade — treat as “last installed/upgraded”). pacman -Q exposes only name and version, so publisher, size and install_date stay unset there.

Jump to section:

Sample Commands

Default check (inventory: package count as status and perf):

check_installed_software
OK: 101 software packages installed.|'count'=101;0;0

Alert when unwanted software is present (an absent product is OK):

check_installed_software "crit=name like 'Notepad++'"
CRITICAL: Notepad++ (64-bit x64) 1.0.0 (Notepad++ Team)|'count'=101;0;0

check_installed_software "crit=name like 'BitTorrent'"
OK: 101 software packages installed.|'count'=101;0;0

Detect recent installs (correlate incidents with software changes):

check_installed_software "warn=install_date > -30d" "top-syntax=${status}: ${warn_count} recent installs: ${warn_list}"
WARNING: 2 recent installs: PowerToys (Preview) 0.100.2 (Microsoft Corporation), Microsoft Edge 151.0.4129.72 (Microsoft Corporation)|'count'=101;0;0

Threshold on installed size (large packages):

check_installed_software "warn=size > 500M" "top-syntax=${status}: ${warn_count} packages over 500M"
WARNING: 3 packages over 500M|'count'=428;0;0

Over NRPE against a remote host:

check_nrpe --host 192.168.56.103 --command check_installed_software --arguments "crit=name like 'TeamViewer'"
OK: 101 software packages installed.
Windows

Flag EOL software by version (string comparison — pin the major with like):

check_installed_software "filter=name like 'Java 7'" "crit=version like '7.'"
CRITICAL: Java 7 Update 51 7.0.510 (Oracle)|'count'=1;0;0

List per-user installs (software outside the machine-wide hives):

check_installed_software "filter=hive = 'user'" "top-syntax=${status}: ${count} per-user packages: ${list}"
OK: 18 per-user packages: GitHub Desktop 3.6.3 (GitHub, Inc.), CLion 2026.2 (JetBrains s.r.o.), Microsoft Visual Studio Code (User) 1.115.0 (Microsoft Corporation), ...|'count'=18;0;0

Only 32-bit software installed on a 64-bit host:

check_installed_software "filter=architecture = 'x86'" "top-syntax=${status}: ${count} 32-bit packages"
OK: 51 32-bit packages|'count'=51;0;0

Include SystemComponent entries (hidden from Add/Remove Programs):

check_installed_software filter=none
OK: 233 software packages installed.|'count'=233;0;0
Linux

Alert when unwanted software is present:

check_installed_software "crit=name like 'telnetd'"
CRITICAL: telnetd 0.17-41 (Debian telnet maintainers)|'count'=428;0;0

Flag EOL software (pin the version prefix with like):

check_installed_software "filter=name like 'openjdk-7'" "crit=version like '7u'"
CRITICAL: openjdk-7-jre 7u51-2.4.6-1 (Debian Java Maintainers)|'count'=1;0;0

Custom output showing the detected package manager:

check_installed_software "filter=name = 'bash'" "top-syntax=${status}: ${list}" "detail-syntax=${name} ${version} via ${manager}"
OK: bash 5.2.21-2 via dpkg|'count'=1;0;0

Command-line Arguments

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter system_component = 0
warning
warn
critical
crit
ok
debug false
show-all false
empty-state ok
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${problem_list}
ok-syntax %(status): %(count) software packages installed.
empty-syntax %(status): No installed software found
detail-syntax ${name} ${version} (${publisher})
perf-syntax ${name}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning
warn
critical
crit
ok
debug false
show-all false
empty-state ok
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${problem_list}
ok-syntax %(status): %(count) software packages installed.
empty-syntax %(status): No installed software found
detail-syntax ${name} ${version} (${publisher})
perf-syntax ${name}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
architecture ‘x64’ or ‘x86’ (registry view); empty for per-user installs
hive ‘machine’ (HKLM) or ‘user’ (per-user install)
install_date Install date (supports date expressions such as ‘install_date > -30d’); unset when Windows did not record one
install_date_s Raw InstallDate string as recorded (usually YYYYMMDD; often empty)
install_location Install folder (InstallLocation)
key Uninstall registry sub-key name (product GUID or slug)
name Product display name
publisher Publisher / vendor
size Estimated install size (from EstimatedSize); 0 when not recorded
system_component True for entries flagged SystemComponent (hidden from Add/Remove Programs); excluded by the default filter
uninstall_string Uninstall command line (UninstallString)
user Account (‘DOMAIN\name’ or SID) owning a per-user install; empty for machine-wide
version Display version string (comparisons are lexical, not semver-aware)
windows_installer True when the product was installed via Windows Installer (MSI)

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

Option Description
architecture Package architecture (amd64, x86_64, noarch, …)
install_date Install date (supports date expressions such as ‘install_date > -30d’); unset when the manager does not record one
install_date_s Install date as YYYY-MM-DD; empty when unknown
manager Package manager the entry came from (dpkg, rpm, pacman)
name Package name
package_status Package state; always ‘installed’ for listed packages
publisher Maintainer (dpkg, email stripped) / vendor (rpm); empty for pacman
size Installed size in bytes; 0 when not recorded
version Version string (rpm: version-release); comparisons are lexical, not version-aware

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_kernel_memory

Check kernel memory-manager health: paged/nonpaged pool bytes, file-cache bytes and page-fault rates — the pool-exhaustion and hard-fault-storm signals free-RAM thresholds miss.

About check_kernel_memory

check_kernel_memory reports kernel memory-manager health: kernel-allocation gauges, cache bytes and page-fault rates. It complements check_memory (used/free/size of physical/committed/virtual) — kernel-side leaks and hard-fault storms are the classic server failure modes that free-RAM thresholds do not catch. The fault counters are rates, so the check samples a 1-second window (like check_swap_io).

The check returns a single aggregate row. All gauges and rates are always emitted as perf data (kernel_cache, kernel_page_faults_per_sec, …), which is what makes a slow kernel-allocation leak visible: it is inherently a trend signal, so let the backend graph it. There are no default thresholds.

cache and page_faults_per_sec are shared; the kernel-allocation gauges and the hard-fault rate keep their platform-native names (pool_* / hard_faults_per_sec on Windows, slab_* / major_faults_per_sec on Linux), the same convention as hive vs manager in check_installed_software.

Windows

Sourced from the PDH Memory counter set. Keywords: pool_paged, pool_nonpaged, cache, page_faults_per_sec, transition_faults_per_sec and hard_faults_per_sec.

hard_faults_per_sec counts hard-fault events (Page Reads/sec), not the pages they bring in: check_swap_io reports the latter as swap_in (Pages Input/sec), and a read that pages in a whole cluster makes swap_in several times larger than the fault rate. Read the two side by side to tell a fault storm from a paging storm.

Linux

Sourced from /proc/meminfo and /proc/vmstat. Keywords: slab, slab_reclaimable, slab_unreclaimable, cache, page_faults_per_sec and major_faults_per_sec. slab_unreclaimable is the gauge that exposes a slow kernel-side leak — reclaimable slab grows and shrinks with cache pressure and is not by itself a problem.

Check kernel memory-manager health: slab bytes (reclaimable/unreclaimable), page-cache bytes and page-fault rates — the kernel-leak and fault-storm signals free-RAM thresholds miss.

About check_kernel_memory

check_kernel_memory reports kernel memory-manager health: kernel-allocation gauges, cache bytes and page-fault rates. It complements check_memory (used/free/size of physical/committed/virtual) — kernel-side leaks and hard-fault storms are the classic server failure modes that free-RAM thresholds do not catch. The fault counters are rates, so the check samples a 1-second window (like check_swap_io).

The check returns a single aggregate row. All gauges and rates are always emitted as perf data (kernel_cache, kernel_page_faults_per_sec, …), which is what makes a slow kernel-allocation leak visible: it is inherently a trend signal, so let the backend graph it. There are no default thresholds.

cache and page_faults_per_sec are shared; the kernel-allocation gauges and the hard-fault rate keep their platform-native names (pool_* / hard_faults_per_sec on Windows, slab_* / major_faults_per_sec on Linux), the same convention as hive vs manager in check_installed_software.

Windows

Sourced from the PDH Memory counter set. Keywords: pool_paged, pool_nonpaged, cache, page_faults_per_sec, transition_faults_per_sec and hard_faults_per_sec.

hard_faults_per_sec counts hard-fault events (Page Reads/sec), not the pages they bring in: check_swap_io reports the latter as swap_in (Pages Input/sec), and a read that pages in a whole cluster makes swap_in several times larger than the fault rate. Read the two side by side to tell a fault storm from a paging storm.

Linux

Sourced from /proc/meminfo and /proc/vmstat. Keywords: slab, slab_reclaimable, slab_unreclaimable, cache, page_faults_per_sec and major_faults_per_sec. slab_unreclaimable is the gauge that exposes a slow kernel-side leak — reclaimable slab grows and shrinks with cache pressure and is not by itself a problem.

Jump to section:

Sample Commands

Windows

Default check (inventory of the kernel memory gauges and fault rates):

check_kernel_memory
OK: paged pool 1.685GB, nonpaged pool 2.571GB, cache 284.676MB, 57.2 hard faults/s|'kernel_cache'=298504192;0;0 'kernel_hard_faults_per_sec'=57.2;0;0 'kernel_page_faults_per_sec'=16617.16;0;0 'kernel_pool_nonpaged'=2760646656;0;0 'kernel_pool_paged'=1809305600;0;0 'kernel_transition_faults_per_sec'=4624.68;0;0

Note the shape of a healthy host: five-digit total faults/s (soft) but only a handful of hard faults/s.

Detect a nonpaged-pool leak (baseline the host, then pin absolute bytes):

check_kernel_memory "warn=pool_nonpaged > 3G" "crit=pool_nonpaged > 4G"
OK: paged pool 1.685GB, nonpaged pool 2.571GB, cache 284.676MB, 57.2 hard faults/s

Alert on a hard-fault storm (memory pressure forcing disk reads):

check_kernel_memory "warn=hard_faults_per_sec > 200" "crit=hard_faults_per_sec > 1000"
OK: paged pool 1.685GB, nonpaged pool 2.571GB, cache 284.676MB, 57.2 hard faults/s

Combine pool and fault policy in one check:

check_kernel_memory "warn=pool_paged > 4G or pool_nonpaged > 3G" "crit=hard_faults_per_sec > 1000"
OK: paged pool 1.685GB, nonpaged pool 2.571GB, cache 284.676MB, 57.2 hard faults/s

Inspect the fault breakdown (soft vs hard):

check_kernel_memory "detail-syntax=faults=${page_faults_per_sec}/s (soft ${transition_faults_per_sec}/s, hard ${hard_faults_per_sec}/s)"
OK: faults=16617.16/s (soft 4624.68/s, hard 57.2/s)

Over NRPE against a remote host:

check_nrpe --host 192.168.56.103 --command check_kernel_memory --arguments "crit=hard_faults_per_sec > 1000"
OK: paged pool 1.685GB, nonpaged pool 2.571GB, cache 284.676MB, 57.2 hard faults/s
Linux

Default check (inventory of the kernel memory gauges and fault rates):

check_kernel_memory
OK: slab 512MB (128MB unreclaimable), cache 4GB, 2 major faults/s|'kernel_cache'=4294967296;0;0 'kernel_major_faults_per_sec'=2;0;0 'kernel_page_faults_per_sec'=25000;0;0 'kernel_slab'=536870912;0;0 'kernel_slab_reclaimable'=402653184;0;0 'kernel_slab_unreclaimable'=134217728;0;0

Detect an unreclaimable-slab leak (baseline the host, then pin absolute bytes):

check_kernel_memory "warn=slab_unreclaimable > 1G" "crit=slab_unreclaimable > 2G"
OK: slab 512MB (128MB unreclaimable), cache 4GB, 2 major faults/s

Alert on a major-fault storm (memory pressure forcing disk reads):

check_kernel_memory "warn=major_faults_per_sec > 200" "crit=major_faults_per_sec > 1000"
OK: slab 512MB (128MB unreclaimable), cache 4GB, 2 major faults/s

Inspect the fault breakdown (total vs major):

check_kernel_memory "detail-syntax=faults=${page_faults_per_sec}/s (major ${major_faults_per_sec}/s), slab=${slab}"
OK: faults=25000/s (major 2/s), slab=512MB

Over NRPE against a remote host:

check_nrpe --host 192.168.56.103 --command check_kernel_memory --arguments "crit=major_faults_per_sec > 1000"
OK: slab 512MB (128MB unreclaimable), cache 4GB, 2 major faults/s

Command-line Arguments

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning
warn
critical
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax paged pool ${pool_paged}, nonpaged pool ${pool_nonpaged}, cache ${cache}, ${hard_faults_per_sec} hard faults/s
perf-syntax kernel
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning
warn
critical
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax slab ${slab} (${slab_unreclaimable} unreclaimable), cache ${cache}, ${major_faults_per_sec} major faults/s
perf-syntax kernel
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
cache System file-cache working set in bytes (counter ‘Cache Bytes’)
hard_faults_per_sec Hard faults per second (Page Reads/sec): faults that had to read from disk — the fault-storm signal
page_faults_per_sec Total page faults per second (counter ‘Page Faults/sec’, soft + hard). Dominated by cheap soft faults and routinely very large on a healthy host — alert on hard_faults_per_sec instead
pool_nonpaged Nonpaged pool bytes (counter ‘Pool Nonpaged Bytes’) — steady growth here is the classic driver-leak signal
pool_paged Paged pool bytes (counter ‘Pool Paged Bytes’; supports size units, e.g. ‘pool_paged > 2G’); renders human-readable
transition_faults_per_sec Transition (soft) faults per second (counter ‘Transition Faults/sec’), resolved without disk I/O — the dominant soft-fault kind

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

Option Description
cache Page-cache bytes (Cached in /proc/meminfo)
major_faults_per_sec Major (hard) faults per second (pgmajfault in /proc/vmstat): faults that had to read from disk — the fault-storm signal
page_faults_per_sec Total page faults per second, soft + hard (pgfault in /proc/vmstat). Dominated by cheap soft faults and routinely very large on a healthy host — alert on major_faults_per_sec instead
slab Total kernel slab allocator bytes (Slab in /proc/meminfo; supports size units, e.g. ‘slab > 2G’)
slab_reclaimable Reclaimable slab bytes the kernel can drop under pressure, e.g. dentry/inode caches (SReclaimable in /proc/meminfo)
slab_unreclaimable Unreclaimable (pinned) slab bytes (SUnreclaim in /proc/meminfo) — steady growth here is the classic kernel/driver leak signal

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_kernel_stats

Check system-wide kernel activity: context-switch and system-call rates plus live process and thread counts.

About check_kernel_stats

check_kernel_stats reports system-wide kernel activity as one row per metric. The rate counters are sampled over a 1-second window. Use type= (repeatable) to restrict which rows are returned; the default is all of them.

Row keywords are the same on both platforms — name, label, human, rate (perf; 0 for the gauge rows) and current (perf) — but current does not mean the same thing on both. On Windows it is the gauge value, or the rounded per-second rate for a rate row; on Linux it is the raw cumulative counter read from /proc/stat for a rate row, which only ever grows.

Threshold on rate when you mean a per-second value: a threshold written against current from the Windows reading fires permanently on Linux, where the same keyword is a counter in the millions.

The default thresholds are thread-count guardrails on both platforms: warn = name = 'threads' and current > 8000, crit = name = 'threads' and current > 10000. Override them (warn=none) or threshold the rates explicitly, e.g. crit=name = 'ctxt' and rate > 500000 — context-switch storms are workload-relative, so baseline before pinning.

Windows

Sourced from the PDH System counter set.

Row (name) Counter Kind Description
ctxt Context Switches/sec rate Scheduler churn; storms indicate lock contention
syscalls System Calls/sec rate Kernel-transition rate (Windows only)
processes Processes gauge Current process count
threads Threads gauge Current thread count

Windows exposes no cumulative counter here, so current on the rate rows is the rounded rate rather than a running total. Processor Queue Length and System Up Time from the same counter set are deliberately not duplicated — check_load and check_uptime own those.

Linux
Row (name) Source Kind Description
ctxt /proc/stat rate Context switches per second
processes /proc/stat rate Process/fork creations per second
threads /proc/*/task gauge Live thread count (instantaneous)
Platform differences

Linux’s processes row is a fork rate; Windows has no process-creation-rate counter in this set, so its processes row is a gauge (current count). Windows adds the syscalls row, which Linux does not have.

Check kernel activity: context-switch rate, fork rate and live thread count.

About check_kernel_stats

check_kernel_stats reports system-wide kernel activity as one row per metric. The rate counters are sampled over a 1-second window. Use type= (repeatable) to restrict which rows are returned; the default is all of them.

Row keywords are the same on both platforms — name, label, human, rate (perf; 0 for the gauge rows) and current (perf) — but current does not mean the same thing on both. On Windows it is the gauge value, or the rounded per-second rate for a rate row; on Linux it is the raw cumulative counter read from /proc/stat for a rate row, which only ever grows.

Threshold on rate when you mean a per-second value: a threshold written against current from the Windows reading fires permanently on Linux, where the same keyword is a counter in the millions.

The default thresholds are thread-count guardrails on both platforms: warn = name = 'threads' and current > 8000, crit = name = 'threads' and current > 10000. Override them (warn=none) or threshold the rates explicitly, e.g. crit=name = 'ctxt' and rate > 500000 — context-switch storms are workload-relative, so baseline before pinning.

Windows

Sourced from the PDH System counter set.

Row (name) Counter Kind Description
ctxt Context Switches/sec rate Scheduler churn; storms indicate lock contention
syscalls System Calls/sec rate Kernel-transition rate (Windows only)
processes Processes gauge Current process count
threads Threads gauge Current thread count

Windows exposes no cumulative counter here, so current on the rate rows is the rounded rate rather than a running total. Processor Queue Length and System Up Time from the same counter set are deliberately not duplicated — check_load and check_uptime own those.

Linux
Row (name) Source Kind Description
ctxt /proc/stat rate Context switches per second
processes /proc/stat rate Process/fork creations per second
threads /proc/*/task gauge Live thread count (instantaneous)
Platform differences

Linux’s processes row is a fork rate; Windows has no process-creation-rate counter in this set, so its processes row is a gauge (current count). Windows adds the syscalls row, which Linux does not have.

Jump to section:

Sample Commands

Watch only the thread count with custom limits:

check_kernel_stats type=threads "warn=current > 5000" "crit=current > 8000"
OK - Threads 3417|'threads'=3417;5000;8000

Alert on a runaway context-switch rate (baseline the host first):

check_kernel_stats "warn=name = 'ctxt' and rate > 100000" "crit=name = 'ctxt' and rate > 500000"
OK - Context Switches 57111.0/s, Process Creations 317.0/s, Threads 363

Select several rows and render the raw values:

check_kernel_stats type=ctxt type=processes "detail-syntax=${name}=${current}"
OK - ctxt=119059, processes=628
Windows

Default check (all four rows; thread-count guardrails apply):

check_kernel_stats
OK - Context Switches 119058.5/s, System Calls 268702.6/s, Processes 628, Threads 3417|'ctxt'=119059;8000;10000 'syscalls'=268703;8000;10000 'processes'=628;8000;10000 'threads'=3417;8000;10000

Over NRPE against a remote host:

check_nrpe --host 192.168.56.103 --command check_kernel_stats --arguments "warn=none" --arguments "crit=name = 'threads' and current > 20000"
OK - Context Switches 119058.5/s, System Calls 268702.6/s, Processes 628, Threads 3417
Linux

Default check (context-switch rate, fork rate and live thread count):

check_kernel_stats
OK - Context Switches 57111.0/s, Process Creations 317.0/s, Threads 363|'ctxt'=2747325827;8000;10000 'processes'=2888772;8000;10000 'threads'=363;8000;10000

Note that on Linux current for the rate rows is the cumulative counter read from /proc/stat, which is why ctxt shows a very large number in perf data while the message shows the per-second rate.

Only context switches and forks (repeat type=):

check_kernel_stats type=ctxt type=processes
OK - Context Switches 57111.0/s, Process Creations 317.0/s

Command-line Arguments

Option Default Value Description
type Select metric type(s) to show: ctxt, syscalls, processes or threads (repeatable; default: all)

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning name = ‘threads’ and current > 8000
warn
critical name = ‘threads’ and current > 10000
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status} - ${list}
ok-syntax
empty-syntax
detail-syntax ${label} ${human}
perf-syntax ${name}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Option Default Value Description
type Select metric type(s) to show: ctxt, processes or threads (repeatable; default: all)

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning name = ‘threads’ and current > 8000
warn
critical name = ‘threads’ and current > 10000
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status} - ${list}
ok-syntax
empty-syntax
detail-syntax ${label} ${human}
perf-syntax ${name}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
current Gauge value (process/thread count); for the rate rows the rounded per-second rate
human Human-readable value
label Human-friendly metric label
name Metric name: ctxt, syscalls, processes or threads
rate Per-second rate (0 for the processes/threads gauge rows)

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

Option Description
current Current raw value (cumulative counter, or thread count)
human Human-readable value
label Human-friendly metric label (Context Switches, Threads, …)
name Metric name: ctxt, processes or threads
rate Per-second rate (0 for the threads row)

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_load

Check the system load average (1/5/15 minutes), synthesised from the processor queue length plus busy cores.

About check_load

check_load reports 1/5/15-minute load averages — utilization tells you how busy the CPUs are, load tells you how much work is queued for them, which is the saturation signal utilization alone cannot give (100% CPU with an empty queue is a busy box; 100% with a deep queue is an overloaded one).

Linux

The averages come straight from /proc/loadavg — the kernel’s own 1-, 5- and 15-minute run-queue averages.

Windows

Windows has no kernel-maintained load average, so the CheckSystem background collector synthesises one: every second it folds the instantaneous value

load = processor queue length + busy cores

into three exponential moving averages (the Linux loadavg formula sampled at 1 Hz). Each fold decays over the interval actually measured rather than an assumed second, so the averages stay correct when a collector tick overruns the 1-second cadence — which is exactly what happens on the loaded hosts this check exists for. The queue length is the PDH counter \System\Processor Queue Length (threads ready to run but not running, system-wide) and busy cores is cores x CPU busy% from the same tick. This reproduces Linux semantics — running + runnable tasks — so a fully-busy 8-core box reads ~8.0 and a saturated one reads above it, and the familiar threshold conventions (warn=load > <cores>, or percpu=true with warn=load > 1) transfer as-is.

Common behaviour

The check returns a single aggregate row and the keyword vocabulary is identical on both platforms, so warning/critical expressions and detail-syntax port between them. With percpu=true each figure is divided by the number of CPUs so thresholds port across hosts with different core counts (the row’s type then reads scaled instead of total).

There are no default thresholds; the three averages are always emitted as perf data (total_load1 etc., scaled_* with percpu=true). queue is never divided by percpu — it is an absolute thread count.

Windows caveats: the averages live in the collector, so the check reports “Load average data is not available yet” right after service start. If the \System\Processor Queue Length counter is unavailable (corrupt perflib), the load degrades to the CPU-utilization component and a warning is logged. Some hypervisors report a small nonzero queue on idle guests — the smoothing absorbs the noise, but baseline before alerting tightly on queue. Load sampling can be turned off with disable = load in /settings/system/windows (the check then reports data-unavailable rather than zeros).

Check the system load average (1/5/15 minutes).

About check_load

check_load reports 1/5/15-minute load averages — utilization tells you how busy the CPUs are, load tells you how much work is queued for them, which is the saturation signal utilization alone cannot give (100% CPU with an empty queue is a busy box; 100% with a deep queue is an overloaded one).

Linux

The averages come straight from /proc/loadavg — the kernel’s own 1-, 5- and 15-minute run-queue averages.

Windows

Windows has no kernel-maintained load average, so the CheckSystem background collector synthesises one: every second it folds the instantaneous value

load = processor queue length + busy cores

into three exponential moving averages (the Linux loadavg formula sampled at 1 Hz). Each fold decays over the interval actually measured rather than an assumed second, so the averages stay correct when a collector tick overruns the 1-second cadence — which is exactly what happens on the loaded hosts this check exists for. The queue length is the PDH counter \System\Processor Queue Length (threads ready to run but not running, system-wide) and busy cores is cores x CPU busy% from the same tick. This reproduces Linux semantics — running + runnable tasks — so a fully-busy 8-core box reads ~8.0 and a saturated one reads above it, and the familiar threshold conventions (warn=load > <cores>, or percpu=true with warn=load > 1) transfer as-is.

Common behaviour

The check returns a single aggregate row and the keyword vocabulary is identical on both platforms, so warning/critical expressions and detail-syntax port between them. With percpu=true each figure is divided by the number of CPUs so thresholds port across hosts with different core counts (the row’s type then reads scaled instead of total).

There are no default thresholds; the three averages are always emitted as perf data (total_load1 etc., scaled_* with percpu=true). queue is never divided by percpu — it is an absolute thread count.

Windows caveats: the averages live in the collector, so the check reports “Load average data is not available yet” right after service start. If the \System\Processor Queue Length counter is unavailable (corrupt perflib), the load degrades to the CPU-utilization component and a warning is logged. Some hypervisors report a small nonzero queue on idle guests — the smoothing absorbs the noise, but baseline before alerting tightly on queue. Load sampling can be turned off with disable = load in /settings/system/windows (the check then reports data-unavailable rather than zeros).

Jump to section:

Sample Commands

Show the system load average (1 / 5 / 15 minutes):

check_load
OK: total load average: 2.33528, 1.84625, 1.74261|'total_load1'=2.33528;0;0 'total_load5'=1.84625;0;0 'total_load15'=1.74261;0;0

Normalise the load per CPU (divide by the core count):

check_load percpu=true
OK: scaled load average: 0.145955, 0.115391, 0.108913|'scaled_load1'=0.14595;0;0 'scaled_load5'=0.11539;0;0 'scaled_load15'=0.10891;0;0

Warn / critical on any load window (load is the max of the three):

check_load "warn=load > 20" "crit=load > 40"
OK: total load average: 2.33528, 1.84625, 1.74261|'total_load'=2.33528;20;40 'total_load1'=2.33528;0;0 'total_load5'=1.84625;0;0 'total_load15'=1.74261;0;0

Threshold on a specific window, e.g. the 1-minute average:

check_load "warn=load1 > 4" "crit=load1 > 8"
OK: total load average: 2.33528, 1.84625, 1.74261

Per-CPU thresholds (portable across differently-sized hosts):

check_load percpu=true "warn=load > 1" "crit=load > 2"
OK: scaled load average: 0.145955, 0.115391, 0.108913

Inspect the run-queue counters:

check_load "detail-syntax=run=${procs_running} total=${procs_total}"
OK: run=1 total=11221
Windows

The synthesised collector exposes three extra keywords — queue (the raw \System\Processor Queue Length saturation signal), cores and samples (collector ticks folded into the averages so far).

Inspect the raw saturation signal and the collector state:

check_load "detail-syntax=q=${queue} run=${procs_running} total=${procs_total} cores=${cores} samples=${samples}"
OK: q=0.0294169 run=1 total=11221 cores=16 samples=31

Alert on sustained queueing regardless of utilization (USE-method saturation):

check_load "warn=queue > 16" "crit=queue > 32"
OK: total load average: 2.33528, 1.84625, 1.74261

Command-line Arguments

Option Default Value Description
percpu false Divide the load averages by the number of CPUs (reports the ‘scaled’ per-core load)
percpu:

Divide the load averages by the number of CPUs (reports the ‘scaled’ per-core load)

Default Value: false

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning
warn
critical
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax ${type} load average: ${load1}, ${load5}, ${load15}
perf-syntax ${type}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
load The largest of load1, load5 and load15
load1 Load average over the last 1 minute
load15 Load average over the last 15 minutes
load5 Load average over the last 5 minutes
procs_running Number of currently runnable kernel scheduling entities
procs_total Total number of kernel scheduling entities
type ‘total’ or (with –percpu) ‘scaled’

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_memory

Check free/used memory on the system.

Kinds of memory

There are several different kinds of memory that a computer system uses to manage data and processes. Here are the main types:

  • physical Memory (RAM): This is the actual, tangible memory chips installed in your computer. It’s often referred to as RAM (Random Access Memory).
  • committed Memory: Committed memory refers to the amount of virtual memory that has been reserved by processes. When a program requests memory from the operating system, that memory is “committed.” This committed memory is guaranteed to be available to the process, meaning Windows has set aside enough resources (either physical RAM or space in the page file) to back that memory.
  • virtual Memory: Virtual memory is an abstraction layer created by the operating system (Windows) to provide a larger, contiguous address space to each process than the physical RAM actually available.

Memory paging rate (\Memory\Pages/sec)

A sustained high hard-page-fault rate is one of the strongest signals of memory pressure. NSClient++ collects \Memory\Pages/sec by default under the alias memory_pages_sec, so you can alert on it directly with check_pdh without declaring the counter yourself:

check_pdh "counter=memory_pages_sec" "warn=value > 1000" "crit=value > 5000"

Jump to section:

Sample Commands

Default check:

check_memory
OK memory within bounds.
'page used'=8G;19;21 'page used %'=33%;79;89 'physical used'=7G;9;10 'physical used %'=65%;79;89

Using –show-all to show the result:

check_memory "warn=free < 20%" "crit=free < 10G" --show-all
page = 8.05G, physical = 7.85G
'page free'=15G;4;2 'page free %'=66%;19;9 'physical free'=4G;2;1 'physical free %'=34%;19;9

Changing the return syntax to include more information::

check_memory "top-syntax=${list}" "detail-syntax=${type} free: ${free} used: ${used} size: ${size}"
page free: 16G used: 7.98G size: 24G, physical free: 4.18G used: 7.8G size: 12G

Default check via NRPE::

check_nrpe --host 192.168.56.103 --command check_memory
OK memory within bounds.|'page'=531G;3;3;0;3 'page %'=12%;79;89;0;100 'physical'=530G;1;1;0;1 'physical %'=25%;79;89;0;100
Overriding the unit:

Most “byte” checks such as memory have an auto scaling feature which means values will go from 800M to 1.2G between checks. Some graphing systems does not honor the units in performance data in which case you can get unexpected large values (such as 800G). To remedy this you can lock the unit by adding perf-config=*(unit:G)

check_memory perf-config=*(unit:G)
page = 8.05G, physical = 7.85G
'page free'=15G;4;2 'page free %'=66%;19;9 'physical free'=4G;2;1 'physical free %'=34%;19;9

Command-line Arguments

Option Default Value Description
type The type of memory to check (physical = Physical memory (RAM), committed = total memory (RAM+PAGE)

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning used > 80%
warn
critical used > 90%
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax ${type}: ${used}/${size}
perf-syntax ${type}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Option Default Value Description
type The type of memory to check (physical = Physical memory (RAM), committed = total memory (RAM+PAGE)

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning used > 80%
warn
critical used > 90%
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax ${type} = ${used}
perf-syntax ${type}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
convert_bytes() Convert a byte count to a specific unit and return the numeric value (1024-based). Useful in thresholds.
format_bytes() Format a number as a human-readable byte string.
format_number() Render a number with a fixed number of decimals, using the check’s decimal and thousands separators.
free Free memory in bytes (g,m,k,b) or percentages %
free_pct % free memory
scale() Divide a value by a divisor. Useful for arbitrary unit conversions (e.g. decimal Mbps with scale(value, 1000000)).
size Total size of memory
type The type of memory to check
used Used memory in bytes (g,m,k,b) or percentages %
used_pct % used memory

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

Option Description
free Free memory in bytes (g,m,k,b) or percentages %
size Total size of memory
type The type of memory to check
used Used memory in bytes (g,m,k,b) or percentages %

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_network

Check network interface status.

Choosing a mode

check_network collects throughput counters from one of two WMI classes. Which one to use is controlled by the mode= argument:

  • interface (default) — Counters are read from Win32_PerfRawData_Tcpip_NetworkInterface. This is the historical behaviour and reports one row per physical network interface. NIC team aggregates (the virtual adapter that represents the team as a whole) are not visible here, only the underlying physical adapters. Use this mode unless you specifically need team statistics — it preserves the output that existing dashboards and thresholds were built against.

  • adapter — Counters are read from Win32_PerfRawData_Tcpip_NetworkAdapter. This superset also reports the aggregated team adapter (e.g. a row called “Production Network” alongside the physical team members), which is what you want when monitoring traffic across an LBFO/Switch-Embedded team rather than individual ports. Note that the friendly Windows adapter name is used here, so interface names may differ slightly from interface mode for the same physical NIC.

  • both — Every adapter is reported twice, once from each source. The source filter keyword (source = 'interface' or source = 'adapter') can then be used inside warning/critical/filter expressions to distinguish them. This mode is mainly useful when you want to alert on the team aggregate and the individual members from one check.

A source filter keyword is available in every mode (its value is the literal string interface or adapter), so you can write expressions such as source = 'adapter' and throughput > 100000000 to scope thresholds to a particular source.

Identifying teamed adapters

Team aggregates only have perfraw data; they have no matching Win32_NetworkAdapter row, so MAC, speed, enabled and net_connection_id are empty for them. You can identify them with MAC = '' in a filter expression when running in adapter or both mode.

The speed, speed_bps, usage_in, usage_out and usage_total variables all derive from the Windows Win32_NetworkAdapter.Speed property. That property is the negotiated link speed, which is not always the same thing as the actual usable throughput. The check reports what Windows tells it; it does not measure the link.

When the reported speed is unreliable or missing:

  • Virtual adapters (VPN tunnels, loopback, Hyper-V vNICs, some VMware paravirtual NICs) frequently report Speed as “Unknown” or empty. The check stores speed_bps = 0 for those.
  • NIC team aggregates (visible in mode=adapter or mode=both) may report 0, ~0ULL, or an arithmetically inconsistent value depending on the driver and team mode (LACP vs switch-independent vs static). Sometimes the team aggregate’s Speed is the sum of member-link speeds; sometimes it is a single member-link’s speed.
  • Wireless adapters typically report the negotiated PHY rate (for example 866 Mbps for 802.11ac). Real-world throughput is usually 40-60% of that because of MAC overhead, retransmits and rate adaptation, so a saturated wireless link may read as ~50% in usage_* rather than the 100% you’d expect.
  • Drivers that report a stale value during link renegotiation can briefly show the wrong rate immediately after a cable change or speed switch.

Variables affected by this:

Variable Best-effort behaviour when Speed is unknown
speed Raw string from WMI - may be "Unknown" or empty
speed_bps Reads as 0 (the “unknown” sentinel)
usage_in Reads as 0 - indistinguishable from a genuinely idle link
usage_out Reads as 0 - indistinguishable from a genuinely idle link
usage_total Reads as 0 - indistinguishable from a genuinely idle link

The byte-rate variables (received, sent, throughput) and their *_human companions are not derived from Speed and are unaffected by these caveats. They come straight from Win32_PerfRawData_Tcpip_NetworkInterface / NetworkAdapter cumulative counters.

Writing reliable percent-based alerts:

The 0-when-unknown sentinel was chosen so dashboards and <-style alert rules behave naturally without special-casing. The trade-off is that an unknown-speed link looks identical to a genuinely idle one. If you need to distinguish them, filter on speed_bps > 0 before applying the percent threshold:

check_network "filter=speed_bps > 0" \
              "warning=usage_total > 80" \
              "critical=usage_total > 95"

For environments where percent thresholds are not viable (mixed wireless, heavy NIC-team use, lots of virtual adapters), prefer absolute byte-rate thresholds against received/sent/throughput, scoped to specific interfaces by name:

check_network "filter=name = 'Ethernet 1'" \
              "warning=throughput > 800000000" \
              "critical=throughput > 950000000"

Both styles can be combined in a single check by using filter to scope which interfaces participate, then warning/critical to set the threshold.

Packet, error and discard counters

In addition to the byte-rate counters, check_network exposes per-second packet, error and discard rates. Each is derived from the cumulative Win32_PerfRawData_Tcpip_Network* counters, so a healthy NIC reports approximately 0 errors/discards per second and any sustained non-zero rate is an alertable signal. All six emit perfdata.

Variable Description
packets_in Packets received per second.
packets_out Packets sent per second.
errors_in Inbound packet errors per second.
errors_out Outbound packet errors per second.
discards_in Inbound packets discarded per second.
discards_out Outbound packets discarded per second.
check_network "filter=name = 'Ethernet 1'" \
              "warning=errors_in > 0 or errors_out > 0" \
              "critical=discards_in > 10 or discards_out > 10"

NIC team membership

When the Windows LBFO WMI provider is available (ROOT\StandardCimv2\MSFT_NetLbfoTeamMember), each adapter is annotated with its team:

Variable Description
team Name of the NIC team this adapter belongs to. Empty when the adapter is not a team member, or when the LBFO provider is unavailable (client SKUs, older Windows, no teams configured).
team_status The raw MSFT_NetLbfoTeamMember.OperationalStatus of this team member, rendered as a string. Empty for non-members.

Team annotation is best-effort and self-disabling: if the provider or namespace is absent, the fields stay empty and the check does not fail. Use team != '' to scope a check to teamed adapters.

Check network interface status and throughput.

Choosing a mode

check_network collects throughput counters from one of two WMI classes. Which one to use is controlled by the mode= argument:

  • interface (default) — Counters are read from Win32_PerfRawData_Tcpip_NetworkInterface. This is the historical behaviour and reports one row per physical network interface. NIC team aggregates (the virtual adapter that represents the team as a whole) are not visible here, only the underlying physical adapters. Use this mode unless you specifically need team statistics — it preserves the output that existing dashboards and thresholds were built against.

  • adapter — Counters are read from Win32_PerfRawData_Tcpip_NetworkAdapter. This superset also reports the aggregated team adapter (e.g. a row called “Production Network” alongside the physical team members), which is what you want when monitoring traffic across an LBFO/Switch-Embedded team rather than individual ports. Note that the friendly Windows adapter name is used here, so interface names may differ slightly from interface mode for the same physical NIC.

  • both — Every adapter is reported twice, once from each source. The source filter keyword (source = 'interface' or source = 'adapter') can then be used inside warning/critical/filter expressions to distinguish them. This mode is mainly useful when you want to alert on the team aggregate and the individual members from one check.

A source filter keyword is available in every mode (its value is the literal string interface or adapter), so you can write expressions such as source = 'adapter' and throughput > 100000000 to scope thresholds to a particular source.

Identifying teamed adapters

Team aggregates only have perfraw data; they have no matching Win32_NetworkAdapter row, so MAC, speed, enabled and net_connection_id are empty for them. You can identify them with MAC = '' in a filter expression when running in adapter or both mode.

The speed, speed_bps, usage_in, usage_out and usage_total variables all derive from the Windows Win32_NetworkAdapter.Speed property. That property is the negotiated link speed, which is not always the same thing as the actual usable throughput. The check reports what Windows tells it; it does not measure the link.

When the reported speed is unreliable or missing:

  • Virtual adapters (VPN tunnels, loopback, Hyper-V vNICs, some VMware paravirtual NICs) frequently report Speed as “Unknown” or empty. The check stores speed_bps = 0 for those.
  • NIC team aggregates (visible in mode=adapter or mode=both) may report 0, ~0ULL, or an arithmetically inconsistent value depending on the driver and team mode (LACP vs switch-independent vs static). Sometimes the team aggregate’s Speed is the sum of member-link speeds; sometimes it is a single member-link’s speed.
  • Wireless adapters typically report the negotiated PHY rate (for example 866 Mbps for 802.11ac). Real-world throughput is usually 40-60% of that because of MAC overhead, retransmits and rate adaptation, so a saturated wireless link may read as ~50% in usage_* rather than the 100% you’d expect.
  • Drivers that report a stale value during link renegotiation can briefly show the wrong rate immediately after a cable change or speed switch.

Variables affected by this:

Variable Best-effort behaviour when Speed is unknown
speed Raw string from WMI - may be "Unknown" or empty
speed_bps Reads as 0 (the “unknown” sentinel)
usage_in Reads as 0 - indistinguishable from a genuinely idle link
usage_out Reads as 0 - indistinguishable from a genuinely idle link
usage_total Reads as 0 - indistinguishable from a genuinely idle link

The byte-rate variables (received, sent, throughput) and their *_human companions are not derived from Speed and are unaffected by these caveats. They come straight from Win32_PerfRawData_Tcpip_NetworkInterface / NetworkAdapter cumulative counters.

Writing reliable percent-based alerts:

The 0-when-unknown sentinel was chosen so dashboards and <-style alert rules behave naturally without special-casing. The trade-off is that an unknown-speed link looks identical to a genuinely idle one. If you need to distinguish them, filter on speed_bps > 0 before applying the percent threshold:

check_network "filter=speed_bps > 0" \
              "warning=usage_total > 80" \
              "critical=usage_total > 95"

For environments where percent thresholds are not viable (mixed wireless, heavy NIC-team use, lots of virtual adapters), prefer absolute byte-rate thresholds against received/sent/throughput, scoped to specific interfaces by name:

check_network "filter=name = 'Ethernet 1'" \
              "warning=throughput > 800000000" \
              "critical=throughput > 950000000"

Both styles can be combined in a single check by using filter to scope which interfaces participate, then warning/critical to set the threshold.

Packet, error and discard counters

In addition to the byte-rate counters, check_network exposes per-second packet, error and discard rates. Each is derived from the cumulative Win32_PerfRawData_Tcpip_Network* counters, so a healthy NIC reports approximately 0 errors/discards per second and any sustained non-zero rate is an alertable signal. All six emit perfdata.

Variable Description
packets_in Packets received per second.
packets_out Packets sent per second.
errors_in Inbound packet errors per second.
errors_out Outbound packet errors per second.
discards_in Inbound packets discarded per second.
discards_out Outbound packets discarded per second.
check_network "filter=name = 'Ethernet 1'" \
              "warning=errors_in > 0 or errors_out > 0" \
              "critical=discards_in > 10 or discards_out > 10"

NIC team membership

When the Windows LBFO WMI provider is available (ROOT\StandardCimv2\MSFT_NetLbfoTeamMember), each adapter is annotated with its team:

Variable Description
team Name of the NIC team this adapter belongs to. Empty when the adapter is not a team member, or when the LBFO provider is unavailable (client SKUs, older Windows, no teams configured).
team_status The raw MSFT_NetLbfoTeamMember.OperationalStatus of this team member, rendered as a string. Empty for non-members.

Team annotation is best-effort and self-disabling: if the provider or namespace is absent, the fields stay empty and the check does not fail. Use team != '' to scope a check to teamed adapters.

Jump to section:

Sample Commands

Default check (one record per interface):

The defaults threshold total throughput: throughput > 10000 warns and > 100000 is critical, in bytes per second.

check_network
OK: eth0 >659B/s <659B/s, ifb0 >0B/s <0B/s, ifb1 >0B/s <0B/s, lo >0B/s <0B/s|'eth0'=1318Bps;10000;100000 'ifb0'=0Bps;10000;100000 'ifb1'=0Bps;10000;100000 'lo'=0Bps;10000;100000

The message renders the human-readable sent_human / received_human; the performance data carries the raw throughput in bytes per second.

Exclude loopback and virtual interfaces:

check_network "filter=name not like 'lo' and name not like 'ifb'"
OK: eth0 >659B/s <659B/s|'eth0'=1318Bps;10000;100000

Do this before setting any fleet-wide threshold — a container host has a lot of veth/docker interfaces that will otherwise each become a record and a performance-data series.

Alert when a link is not up:

Note that a loopback interface reports unknown rather than up, so filter it out or this will fire on every host.

check_network "crit=link_status != 'up'" "warn=none" "detail-syntax=${name}: ${link_status}"
CRITICAL: eth0: up, ifb0: down, ifb1: down, lo: unknown

Alert on interface errors rather than volume:

Errors and drops are a cabling, driver or duplex-mismatch signal, and are invisible to a throughput threshold. They are cumulative counters since boot, so alert on any increase from your own baseline rather than on an absolute number.

check_network "crit=rx_errors > 0 or tx_errors > 0" "warn=none" "detail-syntax=${name}: rx_err=${rx_errors} tx_err=${tx_errors}"
OK: eth0: rx_err=0 tx_err=0, ifb0: rx_err=0 tx_err=0, ifb1: rx_err=0 tx_err=0, lo: rx_err=0 tx_err=0|'eth0_rx_errors'=0;0;0 'eth0_tx_errors'=0;0;0 'ifb0_rx_errors'=0;0;0 'ifb0_tx_errors'=0;0;0

Threshold on link utilisation instead of raw bytes:

usage_in / usage_out / usage_total are percentages of the link speed, which ports across differently-sized links. They are 0 whenever speed_bps is unknown — as it is on virtual interfaces and in many VMs — so pair the threshold with a speed_bps > 0 guard rather than trusting a 0% reading.

check_network "warn=usage_total > 60" "crit=usage_total > 85" "detail-syntax=${name}: ${usage_total}% of ${speed_bps}bps"
OK: eth0: 0% of 0bps, ifb0: 0% of 0bps, ifb1: 0% of 0bps, lo: 0% of 0bps|'eth0_usage_total'=0%;60;85 'ifb0_usage_total'=0%;60;85

Inspect the raw fields:

check_network "detail-syntax=${name} link=${link_status} rx=${received} tx=${sent} speed=${speed_bps}"
OK: eth0 link=up rx=659 tx=659 speed=0, ifb0 link=down rx=0 tx=0 speed=0, ifb1 link=down rx=0 tx=0 speed=0, lo link=unknown rx=0 tx=0 speed=0

Right after the agent starts:

The rates come from the 1 Hz background collector, so the first seconds after a restart report no data rather than zeros.

check_network
UNKNOWN: No network data available yet (collector still initializing)

Over NRPE against a remote host:

check_nrpe --host 192.168.56.103 --command check_network --arguments "crit=rx_errors > 100"
OK: eth0 >659B/s <659B/s, lo >0B/s <0B/s

Command-line Arguments

Option Default Value Description
mode interface Which WMI source to report from: ‘interface’ (default; Win32_PerfRawData_Tcpip_NetworkInterface, physical adapters only), ‘adapter’ (Win32_PerfRawData_Tcpip_NetworkAdapter, includes NIC team aggregates), or ‘both’ (every interface reported under both sources)

mode:

Which WMI source to report from: ‘interface’ (default; Win32_PerfRawData_Tcpip_NetworkInterface, physical adapters only), ‘adapter’ (Win32_PerfRawData_Tcpip_NetworkAdapter, includes NIC team aggregates), or ‘both’ (every interface reported under both sources)

Default Value: interface

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning throughput > 10000
warn
critical throughput > 100000
crit
ok
debug false
show-all false
empty-state critical
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax %(status): Network interfaces seem ok.
empty-syntax
detail-syntax ${name} >${sent_human}/s <${received_human}/s
perf-syntax ${name}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning throughput > 10000
warn
critical throughput > 100000
crit
ok
debug false
show-all false
empty-state critical
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax %(status): Network interfaces seem ok.
empty-syntax
detail-syntax ${name} >${sent_human}/s <${received_human}/s
perf-syntax ${name}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
MAC The MAC address
convert_bytes() Convert a byte count to a specific unit and return the numeric value (1024-based). Useful in thresholds.
discards_in Inbound packets discarded per second
discards_out Outbound packets discarded per second
enabled True if the network interface is enabled
errors_in Inbound packet errors per second
errors_out Outbound packet errors per second
format_bytes() Format a number as a human-readable byte string.
format_number() Render a number with a fixed number of decimals, using the check’s decimal and thousands separators.
link_status Network connection status
name Network interface name
net_connection_id Network connection id
packets_in Packets received per second
packets_out Packets sent per second
received Bytes received per second
received_human Bytes received per second, formatted as a human-readable string (auto-scaled).
scale() Divide a value by a divisor. Useful for arbitrary unit conversions (e.g. decimal Mbps with scale(value, 1000000)).
sent Bytes sent per second
sent_human Bytes sent per second, formatted as a human-readable string (auto-scaled).
source WMI source: ‘interface’ or ‘adapter’
speed The network interface speed (raw WMI value, e.g. “1000000000” or “Unknown”)
speed_bps Negotiated link speed in bits/sec, parsed from the WMI Speed property. BEST-EFFORT: 0 when the speed is Unknown/empty (virtual adapters, some teams). Filter on speed_bps > 0 before relying on usage_in/out/total.
team NIC team this adapter belongs to (empty if not a team member / LBFO unavailable)
team_status Raw MSFT_NetLbfoTeamMember.OperationalStatus of this team member (empty if not a team member)
throughput Bytes total per second
total_human Bytes total per second, formatted as a human-readable string (auto-scaled).
usage_in Percent of negotiated link speed used by received traffic. BEST-EFFORT: reads as 0 when speed is unknown - filter on speed_bps > 0 to distinguish idle from unknown.
usage_out Percent of negotiated link speed used by sent traffic. BEST-EFFORT: reads as 0 when speed is unknown - filter on speed_bps > 0 to distinguish idle from unknown.
usage_total Percent of negotiated link speed used by total traffic. BEST-EFFORT: reads as 0 when speed is unknown - filter on speed_bps > 0 to distinguish idle from unknown.

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

Option Description
MAC The hardware (MAC) address
convert_bytes() Convert a byte count to a specific unit and return the numeric value (1024-based). Useful in thresholds.
enabled True if the interface link is up
format_bytes() Format a number as a human-readable byte string.
format_number() Render a number with a fixed number of decimals, using the check’s decimal and thousands separators.
link_status Link operational state (up/down/unknown)
name Network interface name
received Bytes received per second
received_human Bytes received per second (human readable, auto-scaled)
received_packets Packets received per second
rx_errors Cumulative receive errors since boot
scale() Divide a value by a divisor. Useful for arbitrary unit conversions (e.g. decimal Mbps with scale(value, 1000000)).
sent Bytes sent per second
sent_human Bytes sent per second (human readable, auto-scaled)
sent_packets Packets sent per second
speed_bps Link speed in bits/sec (0 when unknown, e.g. virtual interfaces)
throughput Bytes total (received + sent) per second
total_human Bytes total per second (human readable, auto-scaled)
tx_errors Cumulative transmit errors since boot
usage_in Percent of link speed used by received traffic (0 when speed unknown)
usage_out Percent of link speed used by sent traffic (0 when speed unknown)
usage_total Percent of link speed used by total traffic (0 when speed unknown)

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_os_updates

Check for available Windows updates via the Windows Update Agent (WUA) API.

Checking for pending OS updates

check_os_updates reports the updates the system is waiting to install. The counters (updates, security, …) are record keywords: reference them from detail-syntax (rendered per record and included in ${list}), not from top-syntax, where they read as 0. On both platforms the default warning filter is updates > 0, so a bare call warns whenever anything is pending:

check_os_updates
Windows

Sourced from the Windows Update Agent (WUA) API. Results can be filtered by severity, reboot requirements and other attributes.

Checking for critical updates

Often, you only want to be alerted if there are security or critical updates missing. You can configure this using the warning and critical filters:

check_os_updates "warning=important > 0" "critical=security > 0 or critical > 0"

This will return WARNING if there are updates with the ‘Important’ severity, and CRITICAL if there are any security updates or updates explicitly marked ‘Critical’.

Checking if a reboot is required

If you want to know if the system needs a reboot after installing updates:

check_os_updates "warning=reboot_required > 0"

reboot_required counts updates that would require a reboot once installed. To detect a reboot that is already pending system-wide — including reboots queued by updates that have already been installed (which reboot_required no longer reflects) — use reboot_pending, sourced from the Windows Update RebootRequired registry key:

check_os_updates "crit=reboot_pending = 1" "detail-syntax=reboot pending: ${reboot_pending}"

Defender / definition and rollup categories

Defender/antivirus definition updates churn several times a day, so most admins threshold them separately from OS patches. defender counts updates in the Definition Updates / Microsoft Defender Antivirus categories, and rollups counts monthly Update Rollup updates:

check_os_updates "warning=updates - defender > 0" "detail-syntax=${updates} total, ${defender} defender, ${rollups} rollups"

Filtering by title

update-filter=<substring> restricts the check to updates whose title contains the (case-insensitive) substring; all counters (updates, security, …) are then recomputed over just the matching subset:

check_os_updates update-filter=".NET" "detail-syntax=${updates} .NET updates: ${titles}"

Note: the WUA search criteria is Type='Software', so driver updates are excluded by design. This keeps the count focused on OS/application patches.

Linux

Sourced from the system package manager — apt, dnf, yum, zypper or pacman, whichever the host uses. The manager keyword names the one that was queried, and count remains a deprecated alias for updates.

Checking for security updates only

Often, you only want to be alerted for security updates. You can configure this using the warning and critical filters:

check_os_updates "warning=none" "critical=security > 0"

This will return CRITICAL if any security updates are pending and otherwise OK regardless of the number of ordinary updates.

Customizing the output

You can use the syntax options to format the output string:

check_os_updates "top-syntax=${status}: ${list}" "detail-syntax=Found ${updates} missing updates. Security: ${security}, Critical: ${critical} - ${titles}"

On Linux, list the pending package names and the package manager that reported them:

check_os_updates "detail-syntax=${updates} updates via ${manager}: ${packages}" show-all

Check for available OS package updates via the system package manager (apt/dnf/yum/zypper/pacman).

Checking for pending OS updates

check_os_updates reports the updates the system is waiting to install. The counters (updates, security, …) are record keywords: reference them from detail-syntax (rendered per record and included in ${list}), not from top-syntax, where they read as 0. On both platforms the default warning filter is updates > 0, so a bare call warns whenever anything is pending:

check_os_updates
Windows

Sourced from the Windows Update Agent (WUA) API. Results can be filtered by severity, reboot requirements and other attributes.

Checking for critical updates

Often, you only want to be alerted if there are security or critical updates missing. You can configure this using the warning and critical filters:

check_os_updates "warning=important > 0" "critical=security > 0 or critical > 0"

This will return WARNING if there are updates with the ‘Important’ severity, and CRITICAL if there are any security updates or updates explicitly marked ‘Critical’.

Checking if a reboot is required

If you want to know if the system needs a reboot after installing updates:

check_os_updates "warning=reboot_required > 0"

reboot_required counts updates that would require a reboot once installed. To detect a reboot that is already pending system-wide — including reboots queued by updates that have already been installed (which reboot_required no longer reflects) — use reboot_pending, sourced from the Windows Update RebootRequired registry key:

check_os_updates "crit=reboot_pending = 1" "detail-syntax=reboot pending: ${reboot_pending}"

Defender / definition and rollup categories

Defender/antivirus definition updates churn several times a day, so most admins threshold them separately from OS patches. defender counts updates in the Definition Updates / Microsoft Defender Antivirus categories, and rollups counts monthly Update Rollup updates:

check_os_updates "warning=updates - defender > 0" "detail-syntax=${updates} total, ${defender} defender, ${rollups} rollups"

Filtering by title

update-filter=<substring> restricts the check to updates whose title contains the (case-insensitive) substring; all counters (updates, security, …) are then recomputed over just the matching subset:

check_os_updates update-filter=".NET" "detail-syntax=${updates} .NET updates: ${titles}"

Note: the WUA search criteria is Type='Software', so driver updates are excluded by design. This keeps the count focused on OS/application patches.

Linux

Sourced from the system package manager — apt, dnf, yum, zypper or pacman, whichever the host uses. The manager keyword names the one that was queried, and count remains a deprecated alias for updates.

Checking for security updates only

Often, you only want to be alerted for security updates. You can configure this using the warning and critical filters:

check_os_updates "warning=none" "critical=security > 0"

This will return CRITICAL if any security updates are pending and otherwise OK regardless of the number of ordinary updates.

Customizing the output

You can use the syntax options to format the output string:

check_os_updates "top-syntax=${status}: ${list}" "detail-syntax=Found ${updates} missing updates. Security: ${security}, Critical: ${critical} - ${titles}"

On Linux, list the pending package names and the package manager that reported them:

check_os_updates "detail-syntax=${updates} updates via ${manager}: ${packages}" show-all

Jump to section:

Sample Commands

Linux

Default check (any pending update warns):

check_os_updates
CRITICAL: 176 updates available (152 security) via apt|'updates_security'=152;0;0 'updates'=176;0;0

The default critical threshold is security > 0, so a host with pending security updates goes critical rather than merely warning.

Only care about security updates:

check_os_updates "warning=none" "critical=security > 0"
CRITICAL: 176 updates available (152 security) via apt|'updates_security'=152;0;0

Tolerate a backlog of ordinary updates:

check_os_updates "warning=updates > 200" "critical=updates > 500"
OK: 176 updates available (152 security) via apt|'updates'=176;200;500

Show which package manager answered:

check_os_updates "detail-syntax=${updates} updates via ${manager}"
CRITICAL: 176 updates via apt|'updates_security'=152;0;0 'updates'=176;0;0

List the pending package names:

check_os_updates "detail-syntax=${updates}: ${packages}" show-all
CRITICAL: 176: bsdutils, bzip2, ca-certificates, containerd.io, coreutils, curl, diffutils, dirmngr, distro-info-data, docker-buildx-plugin, ...
Windows

Default check:

check_os_updates
WARNING: 7 updates available (2 security)|'updates'=7;0;0 'updates_security'=2;0;0

Alert only on security and critical updates:

check_os_updates "warning=important > 0" "critical=security > 0 or critical > 0"
CRITICAL: 7 updates available (2 security)

Detect a pending reboot:

reboot_required counts updates that would need a reboot once installed; reboot_pending reports a reboot that is already queued system-wide.

check_os_updates "crit=reboot_pending = 1" "detail-syntax=reboot pending: ${reboot_pending}"
CRITICAL: reboot pending: 1

Threshold OS patches separately from Defender definitions:

check_os_updates "warning=updates - defender > 0" "detail-syntax=${updates} total, ${defender} defender, ${rollups} rollups"
WARNING: 7 total, 3 defender, 1 rollups

Restrict to updates whose title matches a substring:

All the counters are recomputed over just the matching subset.

check_os_updates update-filter=".NET" "detail-syntax=${updates} .NET updates: ${titles}"
WARNING: 2 .NET updates: 2026-08 Cumulative Update for .NET Framework 4.8, Update for .NET 8.0.14

Over NRPE against a remote host:

check_nrpe --host 192.168.56.103 --command check_os_updates --arguments "critical=security > 0"
OK: 0 updates available (0 security)

Command-line Arguments

Option Default Value Description
update-filter Only count updates whose title contains this (case-insensitive) substring. The counters and titles are recomputed over the matching subset.

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning updates > 0
warn
critical security > 0 or critical > 0
crit
ok
debug false
show-all false
empty-state ok
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax %(status): No updates available.
empty-syntax
detail-syntax ${updates} updates available (${security} security, ${critical} critical)
perf-syntax updates
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning updates > 0
warn
critical security > 0
crit
ok
debug false
show-all false
empty-state ok
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax %(status): No updates available.
empty-syntax
detail-syntax ${updates} updates available (${security} security) via ${manager}
perf-syntax updates
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
critical Number of critical updates
defender Number of Defender/definition updates (churn daily; threshold separately)
error Last error message from the WUA search (if any)
important Number of updates with MSRC severity ‘Important’
reboot_pending 1 if the system has a pending reboot queued (registry RebootRequired), even from already-installed updates
reboot_required Number of updates requiring a reboot
rollups Number of update-rollup updates
security Number of security updates
titles Semicolon separated list of available update titles
update_status Aggregated status: ok, warning, critical, pending, error
updates Total number of available updates

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

Option Description
manager Package manager used to query updates
packages Comma separated list of available package updates
security Number of available security updates
updates Total number of available updates

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_os_version

Check the version of the underlying OS.

Reports the version of the underlying Windows OS, sourced from the OS version information, the registry (UBR), GetNativeSystemInfo for the processor architecture, and Win32_BIOS (WMI) for the inventory fields.

The default warning/critical thresholds (version <= 50, i.e. pre-Windows-XP) exist only to flag ancient/unsupported platforms; they never trip on a supported OS. Set your own threshold on build/ubr to alert on a minimum patch level, or filter on arch to assert a fleet’s architecture.

serial, bios_version and manufacturer are inventory-only: they are read best-effort from WMI, are empty when WMI is unavailable, are not part of the default output, and are not intended for alerting. Reference them in a custom detail-syntax (or top-syntax) to pull inventory.

Jump to section:

Sample Commands

Default check:

check_os_Version
L     client CRITICAL: Windows 7 (6.1.7601)
L     client  Performance data: 'version'=61;50;50

Making sure the OS version is Windows 8:

check_os_Version "warn=version < 62"
L     client WARNING: Windows 7 (6.1.7601)
L     client  Performance data: 'version'=61;62;0

Default check via NRPE:

check_nrpe --host 192.168.56.103 --command check_os_version
Windows 2012 (6.2.9200)|'version'=62;50;50

Kernel version and architecture (the default output is now ${version} (${kernel_version}) ${arch}, where kernel_version is the full major.minor.build.ubr):

check_os_version
OK: Windows 11 23H2 (10.0.22631.3810) x64|'version'=110;50;50 'major'=10 'minor'=0 'build'=22631

Alert on a minimum patch level using ubr, and assert a 64-bit fleet:

check_os_version "warn=ubr < 3800" "crit=arch != 'x64'"
OK: Windows 11 23H2 (10.0.22631.3810) x64|'version'=110;50;50 'major'=10 'minor'=0 'build'=22631

Inventory pull — BIOS serial / version / manufacturer via a custom detail-syntax (these fields never alert and are empty if WMI is unavailable):

check_os_version "detail-syntax=${serial} / ${manufacturer} BIOS ${bios_version} / ${kernel_version} ${arch}"
OK: 5CG1234ABC / American Megatrends Inc. BIOS 1.7.0 / 10.0.22631.3810 x64|'version'=110;50;50 'major'=10 'minor'=0 'build'=22631

Command-line Arguments

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning version <= 50
warn
critical version <= 50
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax ${version} (${kernel_version}) ${arch}
perf-syntax version
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning
warn
critical
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax ${os} (kernel ${kernel_release})
perf-syntax kernel_release
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
arch Native processor architecture: x64, x86, arm64, arm, ia64 or unknown (via GetNativeSystemInfo, so a 32-bit agent under WOW64 still reports the true hardware architecture)
bios_version BIOS version (Win32_BIOS.SMBIOSBIOSVersion); inventory only, empty when WMI is unavailable
build Build version number (perfdata)
kernel_version NT kernel version as major.minor.build.ubr (on Windows the kernel version tracks the OS version)
major Major version number (perfdata)
manufacturer BIOS manufacturer / vendor (Win32_BIOS.Manufacturer); inventory only, empty when WMI is unavailable
minor Minor version number (perfdata)
serial BIOS/system serial number (Win32_BIOS.SerialNumber); inventory only, empty when WMI is unavailable
suite Which suites are installed on the machine (Microsoft BackOffice, Web Edition, Compute Cluster Edition, Datacenter Edition, Enterprise Edition, Embedded, Home Edition, Remote Desktop Support, Small Business Server, Storage Server, Terminal Services, Home Server)
ubr Update Build Revision — the patch level within a build (the .3803 in 10.0.19045.3803), read from the registry; 0 when unavailable (e.g. pre-Windows 10)
version System version: numeric for thresholds (major*10+minor, e.g. ‘version <= 50’), rendered as the friendly product name (e.g. ‘Windows 11 23H2’)

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

Option Description
distribution Distribution id, e.g. ‘ubuntu’ (from /etc/os-release ID)
distribution_name Distribution name, e.g. ‘Ubuntu’ (from NAME)
family Distribution family, e.g. ‘debian’ (from ID_LIKE/ID)
kernel_name Kernel name
kernel_release Kernel release
kernel_version Kernel version
machine Machine hardware name
nodename Network node hostname
os Operating system (distribution pretty name, or kernel when unknown)
processor Processor / machine architecture
version Distribution version, e.g. ‘22.04’ (from VERSION_ID)

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_pagefile

Check the size of the system pagefile(s).

About check_pagefile

check_pagefile reports the size and usage of the system’s paging space. It returns one record per paging file (Windows) or swap device (Linux), plus a synthetic total record aggregating all of them — which is what you almost always want to threshold on, since a host with several pagefiles will otherwise alert per file.

The defaults are used > 60% for warning and used > 80% for critical. Thresholds accept both absolute sizes and percentages, so crit=used > 8G and crit=used > 80% are both valid; free_pct / used_pct are available when you want the percentage as a plain number.

What it does and does not tell you

This is a capacity check: how much paging space is committed, not how hard the machine is paging. A box can sit with swap 90% full and be perfectly healthy — pages written out long ago and never needed again — while a box with 5% swap used can be thrashing badly. For the pressure signal, use check_swap_io, which reports the paging rate, and read the two together.

Windows

peak_used reports the high-water mark of commit charge for each pagefile since boot. That is often the more useful alert than instantaneous usage: it catches the nightly job that briefly exhausted the pagefile hours before the check ran.

check_pagefile "crit=peak_used > 90%"
Linux

Each swap device (or swap file) is one record, and name is its path. A host with swap disabled entirely reports only the total record with a size of zero; guard against that with filter=size > 0 if a zero-sized total would otherwise read as 100% used in your dashboards.

Jump to section:

Sample Commands

Default options:

check_pagefile
L     client WARNING: \Device\HarddiskVolume2\pagefile.sys 24.3M (32M)
L     client  Performance data: '\??\D:\pagefile.sys'=1G;14;19;0;23 '\??\D:\pagefile.sys %'=6%;59;79;0;100 '\Device\HarddiskVolume2\pagefile.sys'=24M;19;25;0;32 '\Device\HarddiskVolume2\pagefile.sys %'=75%;59;79;0;100 'total'=1G;14;19;0;23 'total %'=6%;59;79;0;100

Only showing the total amount of pagefile usage::

check_pagefile "filter=name = 'total'" "top-syntax=${list}"
OK: total 1.66G (24G)
Performance data: 'total'=1G;14;19;0;23 'total %'=6%;59;79;0;100

Alerting on the peak commit charge since boot (high-water mark), not just current usage::

check_pagefile "warn=peak_used_pct > 80" "crit=peak_used_pct > 90" "detail-syntax=${name} peak ${peak_used} (${peak_used_pct}%)"
OK: total peak 3.1G (12%)
Performance data: 'total peak_used'=3G;... 'total peak_used_pct'=12;80;90

The peak_used (bytes, scaled) and peak_used_pct keywords expose SystemPageFileInformation’s PeakUsage — the highest pagefile commit reached since boot — so a machine that spiked and recovered still alerts.

Getting help on available options::

check_pagefile help
...
  filter=ARG           Filter which marks interesting items.
                       Interesting items are items which will be included in
                       the check.
                       They do not denote warning or critical state but they
                       are checked use this to filter out unwanted items.
                           Available options:
                       free          Free memory in bytes (g,m,k,b) or percentages %
                       name          The name of the page file (location)
                       size          Total size of pagefile
                       used          Used memory in bytes (g,m,k,b) or percentages %
                       count         Number of items matching the filter
                       total         Total number of items
                       ok_count      Number of items matched the ok criteria
                       warn_count    Number of items matched the warning criteria
                       crit_count    Number of items matched the critical criteria
                       problem_count Number of items matched either warning or critical criteria
...

Command-line Arguments

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning used > 60%
warn
critical used > 80%
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax ${name} ${used} (${size})
perf-syntax ${name}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
free Free memory in bytes (g,m,k,b) or percentages %
free_pct % free memory
name The name of the page file (location)
peak_used Peak used memory in bytes (g,m,k,b) since boot
peak_used_pct % peak used memory since boot
size Total size of pagefile
used Used memory in bytes (g,m,k,b) or percentages %
used_pct % used memory

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

Option Description
free Free memory in bytes (g,m,k,b) or percentages %
name The name of the page file (swap)
size Total size of pagefile/swap
used Used memory in bytes (g,m,k,b) or percentages %

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_patch_age

Available on Windows only.

Check installed-hotfix hygiene: how long since the newest hotfix was installed and whether specific required hotfixes are present.

About check_patch_age

check_patch_age reports the installed side of Windows patching — the counterpart to check_os_updates, which reports what is still pending. It enumerates installed hotfixes from Win32_QuickFixEngineering and answers the two questions operators actually ask:

  • “When was this box last patched?” — via age, the number of days since the newest hotfix was installed.
  • “Is KB\<n> installed?” — via the hotfix= option (vulnerability-response patch verification), or by testing the ids list directly.

The default threshold is crit=missing > 0, which is inert unless you pass one or more hotfix= options (a bare number is matched with an implicit KB prefix, so hotfix=5034441 == hotfix=KB5034441). Age alerting is opt-in via warn=age > N / crit=age > N.

Caveat: Win32_QuickFixEngineering reports only servicing-stack / Component-Based-Servicing hotfixes (the KB list), not every cumulative-update component, and its InstalledOn field is frequently blank or locale-formatted. The check parses the common M/D/YYYY and YYYYMMDD forms; hotfixes whose date cannot be parsed are excluded from the age calculation (and age is -1 only when no hotfix has a parseable date). Treat age as “days since the newest dated hotfix”, not an exact patch SLA clock.

Jump to section:

Sample Commands

Default check (reports install count and how long since the newest hotfix):

check_patch_age
OK: 42 hotfixes installed, newest KB5034441 on 3/12/2024 (18d ago)

Warn if the box has not been patched in 40 days, critical after 90:

check_patch_age "warn=age > 40" "crit=age > 90"
WARNING: 42 hotfixes installed, newest KB5034441 on 3/12/2024 (57d ago)

Verify a specific hotfix is installed (vulnerability response) — CRITICAL if missing:

check_patch_age hotfix=KB5034441
CRITICAL: 42 hotfixes installed, newest KB5030211 on 1/9/2024 (94d ago); missing: KB5034441

Verify several required hotfixes at once (bare numbers get an implicit KB prefix):

check_patch_age hotfix=KB5034441 hotfix=5030211
OK: 42 hotfixes installed, newest KB5034441 on 3/12/2024 (18d ago)

Test presence via the ids list instead of the hotfix= option:

check_patch_age "crit=ids not like 'KB5034441'"
OK: 42 hotfixes installed, newest KB5034441 on 3/12/2024 (18d ago)

Custom output listing the newest hotfix only:

check_patch_age "top-syntax=%(status): %(list)" "detail-syntax=newest %(newest_id) (%(age)d ago), %(patches) installed"
OK: newest KB5034441 (18d ago), 42 installed

Over NRPE against a remote host:

check_nscp_client --host 192.168.56.103 --command check_patch_age --argument "warn=age > 40"
OK: 42 hotfixes installed, newest KB5034441 on 3/12/2024 (18d ago)

Command-line Arguments

Option Default Value Description
hotfix A required HotFixID (repeatable). The check is CRITICAL when a requested hotfix is not installed. A bare number is matched with an implicit ‘KB’ prefix (hotfix=5034441 == hotfix=KB5034441).

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning
warn
critical missing > 0
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax ${message}
perf-syntax patch
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
age Days since the newest hotfix was installed (-1 if the install date is unknown)
ids Semicolon-separated list of all installed HotFixIDs (use ‘ids like KBxxxxxxx’ to test presence)
message Full status sentence used as the default detail line
missing Number of requested hotfixes that are not installed
missing_ids Semicolon-separated list of the requested hotfixes that are missing
newest_id HotFixID of the most recently installed hotfix
newest_installed Install date of the newest hotfix (as reported by Windows)
patches Total number of installed hotfixes
required Number of hotfixes requested via the hotfix= option

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_pdh

Available on Windows only.

Check the value of a performance (PDH) counter on the local or remote system. The counters can also be added and polled periodically to get average values. Performance Log Users group membership is required to check performance counters.

About check_pdh

check_pdh reads Windows performance (PDH) counters and turns each one into a filter record. It is the general-purpose escape hatch for anything the purpose-built checks do not cover — if it shows up in Performance Monitor, this can alert on it.

Counters are named with counter= (repeatable), and can also be passed positionally. There are no default thresholds, so a bare call reports the values and returns OK; a call with no counter at all is an error rather than an empty OK.

The alias check_counter is accepted for backwards compatibility.

Instantaneous versus averaged counters

Many PDH counters are rates and are meaningless from a single sample — a single read of \Processor(_Total)\% Processor Time returns whatever the last interval happened to be, or zero. averages=true takes two samples a second apart and reports the difference, which is what you want for any /sec or % counter.

For anything you check often, prefer the configured collection path instead: add the counter under [/settings/system/windows/counters] so the background collector samples it continuously, then reference it by its configured name. That makes the check itself instant, and lets time= ask for an average over a window (time=5m) rather than a one-second snapshot. time= may be repeated to report several windows at once, in which case the default perf and detail syntax automatically grow a ${time} component so the series stay distinct.

Localized counter names

Counter names are localized, so \Processor(_Total)\% Processor Time does not exist on a German or French Windows. resolution= decides how the name is looked up:

  • auto (default) — try the localized name, then the English API, then index expansion. This is what makes a single portable configuration work across language variants.
  • english — force English names regardless of the system language.
  • index — expand numeric counter indexes to their localized names, which is what expand-index=true does explicitly.
Instances, types and error handling

instances=true expands a wildcard instance (\Process(*)\...) into one record per instance. type= picks the value format (double, long, large, default large) and flags= passes PDH format flags (nocap100, 1000, noscale) — nocap100 is the one you want for a counter that legitimately exceeds 100%, such as multi-core % Processor Time.

reload=true re-reads the counter list on error, which helps with counters registered after boot by a service that starts late. ignore-errors=true makes a missing or invalid counter report 0 instead of failing the check — convenient for a configuration shared across differently-provisioned hosts, but be aware that it turns “the counter is gone” into a silent zero, which is exactly the kind of thing you may want to alert on.

Note that reading performance counters requires membership of the Performance Log Users group (or equivalent rights); a check that returns access-denied errors is usually a permissions problem, not a missing counter.

Jump to section:

Sample Commands

Checking specific Counter (\System\System Up Time):

check_pdh "counter=\\System\\System Up Time" "warn=value > 5" "crit=value > 9999"
\System\System Up Time = 204213
'\System\System Up Time value'=204213;5;9999

Using the expand index to check for translated counters::

check_pdh "counter=\\4\\30" "warn=value > 5" "crit=value > 9999" expand-index
Everything looks good
'\Minne\Dedikationsgräns value'=-2147483648;5;9999

Checking translated counters without expanding indexes::

check_pdh "counter=\\4\\30" "warn=value > 5" "crit=value > 9999"
Everything looks good
'\4\30 value'=-2147483648;5;9999

Checking large values using the type=large keyword::

check_pdh "counter=\\4\\30" "warn=value > 5" "crit=value > 9999" flags=nocap100 expand-index type=large
\Minne\Dedikationsgräns = 25729224704
'\Minne\Dedikationsgräns value'=25729224704;5;9999

Using real-time checks to check average values over time.

Here we configure a counter to be checked at regular intervals and the value is added to a rrd buffer. The configuration from nsclient.ini::

[/settings/system/windows/counters/foo]
collection strategy=rrd
type=large
counter=\Processor(_total)\% Processor Time

Then we can check the value (current snapshot)::

check_pdh "counter=foo" "warn=value > 80" "crit=value > 90"
Everything looks good
'foo value'=18;80;90

To check averages from the same counter we need to specify the time option::

check_pdh "counter=foo" "warn=value > 80" "crit=value > 90" time=30s
Everything looks good
'foo value'=3;80;90

Checking all instances of a given counter::

    check_pdh "counter=\Processor(*)\% processortid" instances
L     client OK: \\MIME-LAPTOP\Processor(0)\% processortid = 100, \\MIME-LAPTOP\Processor(1)\% processortid = 100, \\MIME-LAPTOP\Processor(2)\% processortid = 100, \\MIME-LAPTOP\Processor(3)\% processortid = 100, \\MIME-LAPTOP\Processor(4)\% processortid = 100, \\MIME-LAPTOP\Processor(5)\% processortid = 100, \\MIME-LAPTOP\Processor(6)\% processortid = 100, \\MIME-LAPTOP\Processor(7)\% processortid = 100, \\MIME-LAPTOP\Processor(_Total)\% processortid = 100
    L     client  Performance data: '\Processor(*)\% processortid_0'=100;0;0 '\Processor(*)\% processortid_1'=100;0;0 '\Processor(*)\% processortid_2'=100;0;0 '\Processor(*)\% processortid_3'=100;0;0 '\Processor(*)\% processortid_4'=100;0;0 '\Processor(*)\% processortid_5'=100;0;0 '\Processor(*)\% processortid_6'=100;0;0 '\Processor(*)\% processortid_7'=100;0;0 '\Processor(*)\% processortid__Total'=100;0;0

Command-line Arguments

Option Default Value Description
counter Performance counter to check
expand-index false Expand indexes in counter strings
resolution auto How to resolve counter names against the system locale: auto (try the localized name, then the English API, then index expansion - the default), english (force English counter names regardless of the system language) or index (expand numeric counter indexes to their localized names)
instances false Expand wildcards and fetch all instances
reload false Reload counters on errors (useful to check counters which are not added at boot)
averages false Check average values (ie. wait for 1 second to collecting two samples)
time Timeframe to use for named rrd counters
flags Extra flags to configure the counter (nocap100, 1000, noscale)
type large Format of value (double, long, large)
ignore-errors false If we should ignore errors when checking counters, for instance missing counters or invalid counters will return 0 instead of errors
expand-index:

Expand indexes in counter strings

Default Value: false

resolution:

How to resolve counter names against the system locale: auto (try the localized name, then the English API, then index expansion - the default), english (force English counter names regardless of the system language) or index (expand numeric counter indexes to their localized names)

Default Value: auto

instances:

Expand wildcards and fetch all instances

Default Value: false

reload:

Reload counters on errors (useful to check counters which are not added at boot)

Default Value: false

averages:

Check average values (ie. wait for 1 second to collecting two samples)

Default Value: false

type:

Format of value (double, long, large)

Default Value: large

ignore-errors:

If we should ignore errors when checking counters, for instance missing counters or invalid counters will return 0 instead of errors

Default Value: false

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning
warn
critical
crit
ok
debug false
show-all false
empty-state unknown
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax ${alias} = ${value}
perf-syntax ${alias}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
alias The counter alias
convert_bytes() Convert a byte count to a specific unit and return the numeric value (1024-based). Useful in thresholds.
counter The counter name
format_bytes() Format a number as a human-readable byte string.
format_number() Render a number with a fixed number of decimals, using the check’s decimal and thousands separators.
scale() Divide a value by a divisor. Useful for arbitrary unit conversions (e.g. decimal Mbps with scale(value, 1000000)).
time The time for rrd checks
value The counter value (either float or int)
value_f The counter value (force float value)
value_gb Counter value in GB (1024-based).
value_human Counter value formatted as a human-readable byte string, auto-scaled to B/KB/MB/GB/…
value_i The counter value (force int value)
value_kb Counter value in KB (1024-based).
value_mb Counter value in MB (1024-based).

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_pending_reboot

Available on Windows only.

Check whether the system is waiting for a reboot, aggregating the servicing, Windows Update, file-rename, computer-rename and domain-join signals.

About check_pending_reboot

check_pending_reboot answers a question no single Windows API does: is this machine waiting for a reboot, and why? A pending reboot is signalled independently by several subsystems, so the check reads each one and reports the union. This is the reliable way to catch servers that have applied updates but will not finish patching until they restart.

All signals are read from the 64-bit registry view, so a 32-bit agent under WOW64 still reads the native keys.

The default threshold is warn=pending = 1 (WARNING whenever a reboot is pending, no critical). Override it to escalate, to alert only on specific causes (e.g. crit=servicing = 1), or to suppress the default with warn=none. The check always returns a single aggregate row, so there is no empty state.

How long has the reboot been pending?

A reboot queued minutes ago by an update is expected; one still queued days later is usually the actionable case. The age and written keywords expose how long the reboot has been pending, e.g. crit=pending = 1 and age > 7d. The time comes from the last-write time of the Component Based Servicing / Windows Update registry key (each exists only while its reboot is queued); when both are set the oldest one wins. Three caveats:

  • Only those two signals carry a timestamp. A reboot signalled solely by a pending file rename, computer rename or domain join reports age/written as unknown, which never trips a numeric threshold (test for it explicitly with written = 'unknown').
  • Threshold staleness with a duration on age (age > 7d) or a relative date on written (written < -7d — the signal appeared more than seven days ago). A quoted date string (written < '2026-08-01 00:00:00') is not parsed as a date: it is compared as text against the raw timestamp and will not order correctly. The only quoted comparison with a defined meaning is the written = 'unknown' probe.
  • The registry records the key’s last write, not its creation: if servicing re-touches the key while the reboot is still queued, age restarts. Treat it as “pending at least this long since the last signal update”.

Jump to section:

Sample Commands

Default check on a clean system:

check_pending_reboot
OK: No reboot pending

Default check when a reboot is queued (default warn=pending = 1):

check_pending_reboot
WARNING: Reboot required: Windows Update (pending since 2026-08-16 09:41:12)

Warn on any pending reboot but escalate one that has been pending for over a week:

check_pending_reboot "warn=pending = 1" "crit=pending = 1 and age > 7d"
CRITICAL: Reboot required: Windows Update (pending since 2026-08-10 03:12:45)

The since-time is the last-write time of the Component Based Servicing / Windows Update registry key, which exists only while that reboot is queued. The other signals (file rename, computer rename, domain join) carry no timestamp, so age and written report unknown for them and never trip a numeric threshold (test for it with written = 'unknown').

Escalate a pending reboot to CRITICAL:

check_pending_reboot "crit=pending = 1"
CRITICAL: Reboot required: Component Based Servicing, Windows Update

Only alert on specific causes (ignore Windows Update, alert on servicing or a pending file rename):

check_pending_reboot "warn=none" "crit=servicing = 1 or file_rename = 1"
OK: No reboot pending

Custom output showing the number of signals and the reasons:

check_pending_reboot "top-syntax=%(status): %(list)" "detail-syntax=%(signals) signal(s): %(reasons)"
WARNING: 1 signal(s): pending file rename

Over NRPE against a remote host:

check_nscp_client --host 192.168.56.103 --command check_pending_reboot
OK: No reboot pending

Command-line Arguments

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning pending = 1
warn
critical
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax %(status): No reboot pending
empty-syntax
detail-syntax ${message}
perf-syntax reboot
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
age Seconds the reboot has been pending (since the oldest timestamped signal appeared); threshold with durations, e.g. pending = 1 and age > 7d
computer_rename 1 if the computer has been renamed but not yet rebooted (ActiveComputerName differs from the pending ComputerName)
domain_join 1 if a domain join / SPN update is pending in Netlogon (JoinDomain / AvoidSpnSet present)
file_rename 1 if ‘Session Manager\PendingFileRenameOperations’ is present and non-empty (a file replacement awaits reboot)
message Full status sentence, e.g. ‘Reboot required: Windows Update (pending since 2026-08-16 09:00:00)’
pending 1 if any pending-reboot signal is set (the aggregate flag most checks threshold on)
reasons Comma-separated human-readable list of pending-reboot causes (‘none’ if clear)
servicing 1 if Component Based Servicing (CBS) has queued a reboot (the ‘Component Based Servicing\RebootPending’ key exists)
signals Number of distinct pending-reboot signals currently set
windows_update 1 if Windows Update has queued a reboot (WindowsUpdate\Auto Update\RebootRequired)
written When the oldest timestamped pending-reboot signal appeared (last-write time of the CBS/Windows Update key), as epoch seconds. Threshold staleness with age or a relative date (written < -7d); a quoted date string is compared as text, not as a date. ‘unknown’ when only untimestamped signals are set (written = 'unknown' tests for it)
written_s Signal-appearance time as a human-readable string (‘unknown’ if no timestamped signal)

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_printjobs

Available on Windows only.

Check individual Windows print jobs: document, owner, size, pages, age and spooler status of every queued job.

About check_printjobs

check_printjobs reports the individual jobs sitting in the Windows spooler — one row per job — from Win32_PrintJob. Where check_printqueue tells you that a queue is backed up, this tells you what is stuck in it: which document, whose it is, how big it is, how long it has been waiting and what the spooler says about it.

Units in thresholds:

  • age takes durations — age > 30m, age > 2h — and a bare number still means seconds.
  • size takes byte units — size > 500M, size > 2G. A bare number is rejected for size keywords, so write size > 1K rather than size > 1024.

Defaults: CRITICAL when error = 1 or blocked = 1 or user_intervention = 1 — the three states the spooler cannot get out of by itself — and WARNING when age > 600 (ten minutes). A paused job is deliberately not critical: someone paused it on purpose. empty-state is OK, because an empty spooler is the normal state; the check then reports “No print jobs queued” and still emits count perfdata so queue depth can be graphed.

Perfdata is keyed <printer>_<job id>, so labels change as jobs come and go. That is fine for alerting; for graphing prefer the always-present count, or check_printqueue’s per-printer jobs series. Windows only.

Jump to section:

Sample Commands

Default check (stuck and failing jobs):

The default is critical on a job the spooler cannot clear on its own and warning on one that has been waiting more than ten minutes.

check_printjobs
OK: No print jobs queued|'count'=0;0;0
check_printjobs
OK: OneNote (Desktop): 'document' by micha (queued, 13s)|'OneNote (Desktop)_2_age'=13s;600;0 'count'=1;0;0
check_printjobs
CRITICAL: HP LaserJet: 'quarterly.pdf' by CORP\ann (error, 240s)|'HP LaserJet_42_age'=240s;600;0 'count'=1;0;0

Alert earlier on a queue that is not moving:

check_printjobs "warning=age > 1"
WARNING: OneNote (Desktop): 'document' by micha (queued, 23s)|'OneNote (Desktop)_2_age'=23s;1;0 'count'=1;0;0

Full per-job detail:

check_printjobs warning=none critical=none "top-syntax=${list}" "detail-syntax=printer=${printer} id=${id} doc='${document}' owner=${owner} status=${job_status} size=${size} pages=${pages}/${pages_printed} prio=${priority} age=${age} sub=${submitted}"
printer=OneNote (Desktop) id=2 doc='document' owner=micha status=queued size=53620 pages=1/0 prio=1 age=18 sub=2026-08-16 12:10:02|'count'=1;0;0

submitted is rendered in UTC; threshold on age (seconds) rather than on the timestamp.

Find who is filling the queue:

check_printjobs "filter=owner = 'CORP\\ann'" "warning=count > 20" "critical=none" "top-syntax=${count} job(s) from ann" "ok-syntax=${count} job(s) from ann"
3 job(s) from ann

Alert on a single very large job:

Size thresholds take byte units; a bare number is rejected, so write 500M rather than 524288000.

check_printjobs "warning=none" "critical=size > 500M"
CRITICAL: HP LaserJet: 'plot.ps' by CORP\bob (spooling, 45s)|'HP LaserJet_51_size'=734003200B;0;524288000 'count'=1;0;0

Only the jobs needing a person at the printer:

check_printjobs "filter=user_intervention = 1 or paper_out = 1" "critical=count > 0"
CRITICAL: HP LaserJet: 'invoice.pdf' by CORP\eve (user_intervention, paper_out, 512s)

Watch one queue on a print server, over NRPE:

check_nscp_client --host 192.168.56.103 --command check_printjobs --argument "filter=printer = 'HP LaserJet'" --argument "warning=age > 30m"
OK: All 2 job(s) ok.

Command-line Arguments

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning age > 600
warn
critical error = 1 or blocked = 1 or user_intervention = 1
crit
ok
debug false
show-all false
empty-state ok
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax %(status): All %(count) job(s) ok.
empty-syntax %(status): No print jobs queued
detail-syntax ${printer}: ‘${document}’ by ${owner} (${job_status}, ${age}s)
perf-syntax ${printer}_${id}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
age Seconds since the job was submitted (-1 when the spooler did not report a submit time); threshold with durations, e.g. age > 30m
blocked 1 when the job is blocked on the device queue
document Document name as the application submitted it
error 1 when the job is in an error state
id Spooler job id
job_status Job status words from the spooler: queued, printing, spooling, error, paused, blocked, …
offline 1 when the job’s printer is offline
owner User who submitted the job
pages Total pages in the job (0 when the driver does not report it)
pages_printed Pages printed so far
paper_out 1 when the job is waiting for paper
paused 1 when the job is paused
printer Printer / queue the job is waiting on
printing 1 when the job is printing
priority Job priority
size Job size in bytes; threshold with byte units, e.g. size > 500M
spooling 1 when the job is still spooling
status_mask Raw StatusMask bit field, for statuses without their own keyword
submitted When the job was submitted, in UTC, or ‘unknown’; threshold on age instead
user_intervention 1 when the job needs someone at the printer

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_printqueue

Available on Windows only.

Check Windows print queues: queue depth, oldest-job age, offline and error states plus the driver, port and sharing of each printer.

About check_printqueue

check_printqueue monitors Windows print queues — the classic “the print server is stuck” incident. It reads Win32_Printer (status, error state and the device inventory) and Win32_PrintJob (queued jobs), producing one row per printer with its queue depth and the age of the oldest waiting job.

For the individual jobs behind those counts — who submitted what, how big it is and how long it has been waiting — use check_printjobs, which reports one row per job.

The device keywords (driver, port, location, share, server, default, shared, network) are the inventory half of the check: they answer “is this queue still pointing at the driver and port it is supposed to”, which is the other common cause of “printing is broken” once the queue itself looks healthy. They are also useful as a filter — filter=shared = 1 to watch only what a print server actually publishes.

oldest_job_age is seconds and takes durations: oldest_job_age > 30m, oldest_job_age > 2h. A bare number still means seconds. An empty queue reports -1, which is below every threshold, so it cannot raise a stuck-queue alert.

Defaults: WARNING when jobs > 10, CRITICAL when error = 1. Offline printers are not alerted by default — virtual printers (Print to PDF, OneNote) and disconnected USB printers are routinely offline — so opt in with the offline keyword where it matters (e.g. a print server). empty-state is OK (a host with no printers is fine).

Jump to section:

Sample Commands

Default check (queue depth + printer errors):

check_printqueue
OK: All 6 printer(s) ok.

Default check with a backed-up or errored queue:

check_printqueue
CRITICAL: HP LaserJet: printing, 3 job(s)

Alert on offline printers too (typical for a print server):

check_printqueue "crit=error = 1 or offline = 1"
CRITICAL: HP LaserJet: offline, 0 job(s)

Alert on a stuck queue — a job waiting more than 30 minutes:

check_printqueue "warn=jobs > 10 or oldest_job_age > 30m"
WARNING: HP LaserJet: printing, 2 job(s)

Check one specific printer:

check_printqueue "filter=printer = 'HP LaserJet'" "crit=offline = 1 or error = 1"
OK: All 1 printer(s) ok.

Custom output with full per-printer detail:

check_printqueue "top-syntax=%(status): %(list)" "detail-syntax=%(printer): %(printer_status)/%(error_state) jobs=%(jobs) oldest=%(oldest_job_age)s offline=%(offline)"
OK: HP LaserJet: idle/no_error jobs=0 oldest=-1s offline=0, Microsoft Print to PDF: idle/no_error jobs=0 oldest=-1s offline=0

Over NRPE against a print server:

check_nscp_client --host 192.168.56.103 --command check_printqueue --argument "crit=error = 1 or offline = 1"
OK: All 4 printer(s) ok.

Show the device behind each queue (driver, port, sharing):

check_printqueue warning=none critical=none "top-syntax=${list}" "detail-syntax=${printer} [drv=${driver}] [port=${port}] def=${default} shared=${shared} net=${network}"
Microsoft Print to PDF [drv=Microsoft Print To PDF] [port=PORTPROMPT:] def=0 shared=0 net=0, HP Color LaserJet Pro MFP 4302 [drv=Microsoft IPP Class Driver] [port=WSD-7f7ab05a-2fe9-4ca8-84cb-2f4b45e3bc9a] def=1 shared=0 net=0

Alert when a queue moves to an unexpected driver or port:

check_printqueue "filter=printer = 'HP LaserJet'" "crit=driver != 'HP Universal Printing PCL 6'"
CRITICAL: HP LaserJet: idle, 0 job(s)

Only look at the shared queues on a print server:

check_printqueue "filter=shared = 1" "crit=error = 1 or offline = 1"
OK: All 4 printer(s) ok.

Command-line Arguments

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning jobs > 10
warn
critical error = 1
crit
ok
debug false
show-all false
empty-state ok
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax %(status): All %(count) printer(s) ok.
empty-syntax %(status): No printers found
detail-syntax ${printer}: ${printer_status}, ${jobs} job(s)
perf-syntax ${printer}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
default 1 if this is the default printer
driver Print driver the queue uses
error 1 if the printer is in a real error state (paper/toner/door/jam/service)
error_jobs Number of queued jobs in an error state
error_state Detected error state: no_error, no_paper, jammed, door_open, …
jobs Number of queued print jobs
location Location as configured on the queue (empty when unset)
network 1 if the queue is a network (rather than local) printer
offline 1 if the printer is offline
oldest_job_age Seconds since the oldest queued job (-1 if the queue is empty); threshold with durations, e.g. oldest_job_age > 30m
port Port the queue prints through (IP_x.x.x.x, USB001, PORTPROMPT:, …)
printer Printer / queue name
printer_status Printer status: idle, printing, offline, stopped_printing, warmup, …
server Print server hosting the queue (empty for a local queue)
share Share name (empty when the queue is not shared)
shared 1 if the queue is shared

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_process

Check state/metrics of one or more of the processes running on the computer.

Cross-agent portability keywords

check_process keeps a shared keyword vocabulary across the Windows and Linux agents: rss is a straight alias for working_set (same bytes and human value), and state accepts running as a synonym for started (the rendered value stays started), so the same expressions work on both platforms.

Process owner (username / uid)

Windows

resolve-owner (default false) turns on owner resolution: it reads each matching process’s token to populate username/uid. It is opt-in because LookupAccountSid can block for seconds on domain / Azure-AD accounts. Scope the check to specific processes when using it on a busy host.

check_process process=sqlservr.exe resolve-owner=true "crit=username not like 'NT SERVICE'" "detail-syntax=%(exe) owner=%(username)"
check_process process=nginx.exe "warn=state != 'running'" "crit=rss > 2G"
Linux

uid is always populated — it is read out of a file the check already opens, so it costs nothing — and it is numeric, so it can be thresholded directly:

check_process process=* "crit=uid = 0 and working_set > 1G" "detail-syntax=%(exe) uid=%(uid) ws=%(working_set)"
check_process process=* "filter=uid >= 1000" "warn=count > 200" "top-syntax=%(status): %(count) user processes"

resolve-owner (default false) additionally turns each uid into a user name. It is opt-in because the lookup goes through NSS, which can block for seconds when it is backed by a remote directory (LDAP/SSSD) — the same reason the Windows check gates owner resolution. Names are cached per uid for the lifetime of the agent, so the cost is one lookup per distinct owner, not per process.

check_process process=postgres resolve-owner=true "crit=username != 'postgres'" "detail-syntax=%(exe) owner=%(username)"

Process state: state vs proc_state (Linux)

Two different questions, two keywords: state is the cross-platform started/stopped verdict (also available on Windows), proc_state the raw Linux scheduler state.

state answers “is this process there and alive”; a zombie reports stopped there. proc_state answers “what is it doing”, which is what the two classic Linux alerts need:

check_process process=* "crit=proc_state = 'zombie'" "detail-syntax=%(exe) (pid %(pid)) is a zombie"
check_process process=* "warn=proc_state = 'disk_sleep'" "detail-syntax=%(exe) is blocked in uninterruptible I/O"

disk_sleep (D) is the useful I/O-hang signal: a process stuck there cannot be killed and usually means a wedged disk or an unresponsive NFS mount.

For readability the parser also accepts uninterruptible for disk_sleep, defunct for zombie and traced for tracing_stop.

Note that proc_state = 'stopped' means SIGSTOP’d / job-control stopped (T), which is not the same as state = 'stopped' (process not running).

ppid (Linux)

The parent process id, so process trees can be expressed:

check_process process=* "filter=ppid = 1" "warn=count < 10" "top-syntax=%(status): %(count) processes reparented to init"

It is also how kernel threads are excluded: on a standard Linux kernel every kernel thread is a child of kthreadd, which is pid 2, so

check_process process=* "filter=ppid != 2 and pid != 2" "warn=count > 500"

drops them all. (Note that some environments — WSL, and some container runtimes — do not run a kthreadd at pid 2, so check what pid 2 is on the host before relying on this.)

elapsed and rss (Linux)

elapsed is the “has this been running long enough / too long” check, which creation (an absolute timestamp) makes awkward:

check_process process=my-batch-job "crit=elapsed > 3600" "detail-syntax=%(exe) has been running for %(elapsed)s"
check_process process=nginx "crit=elapsed < 300" "top-syntax=%(status): nginx restarted recently"
check_process process=* "crit=rss > 2G" "detail-syntax=%(exe) rss=%(rss)"

Showing only the top processes (sorting and limiting)

check_process does not sort or limit its output: every matching process is evaluated and returned. To report only the few most interesting processes (for example the 10 biggest memory consumers) wrap the check in filter_perf, which post-processes the performance data produced by a check, sorting it (sort=normal, biggest first) and limiting it (limit=N).

For example, the top 10 processes by working set (RAM), excluding SQL Server:

filter_perf sort=normal limit=10 command=check_process arguments "filter=working_set > 0 and exe not in ('sqlservr.exe')" "warn=working_set > 3G" "crit=working_set > 5G" "detail-syntax=%(exe) ws=%(working_set)"

The same approach works for CPU usage. Pass delta=true so that %(time) (and %(kernel) / %(user)) report CPU usage over a one second window as a whole percentage of total CPU, instead of the cumulative CPU seconds since the process started, for example the top 10 processes by CPU:

filter_perf sort=normal limit=10 command=check_process arguments delta=true "warn=time > 50" "crit=time > 90" "detail-syntax=%(exe) cpu=%(time)%"

Note that limit only trims the performance data; the warning/critical status is still evaluated against every matching process, so an alert is raised even if the offending process is not among the items shown.

delta=true and the per-process CPU collector (Windows)

Unlike earlier releases, delta=true no longer samples, sleeps a second, then samples again inside the check. Instead the CPU percentage is taken from a background collector that diffs the system process table once a second, so the check returns immediately with a always-fresh rolling one-second reading (and memory/handle fields report their real absolute values, not a one-second change).

Because that collector is off by default, you must enable it once:

[/settings/system/windows]
process cpu = true

Until it is enabled, check_process delta=true returns UNKNOWN with a message naming the setting (it fails fast on the flag, whether or not time/kernel/ user appear in the syntax) rather than reporting misleading numbers. Cumulative CPU seconds (delta omitted) need no collector and are unaffected.

Jump to section:

Sample Commands

Windows

Default check:

check_process
SetPoint.exe=hung
Performance data: 'taskhost.exe'=1;1;0 'dwm.exe'=1;1;0 'explorer.exe'=1;1;0 ... 'chrome.exe'=1;1;0 'vcpkgsrv.exe'=1;1;0 'vcpkgsrv.exe'=1;1;0 

Default check via NRPE::

check_nrpe --host 192.168.56.103 --command check_process
SetPoint.exe=hung|'smss.exe state'=1;0;0 'csrss.exe state'=1;0;0...

Check that specific process are running::

check_process process=explorer.exe process=foo.exe
foo.exe=stopped
Performance data: 'explorer.exe'=1;1;0 'foo.exe'=0;1;0

Check memory footprint from specific processes::

check_process process=explorer.exe "warn=working_set > 70m"
explorer.exe=started
Performance data: 'explorer.exe ws_size'=73M;70;0

Extend the syntax to display the attributes we are interested in::

check_process process=explorer.exe "warn=working_set > 70m" "detail-syntax=${exe} ws:${working_set}, handles: ${handles}, user time:${user}s"
WARNING: Explorer.EXE ws:431.812MB, handles: 5639, user time:2535s
Performance data: 'explorer.exe ws_size'=73M;70;0

List all processes which use more then 200m virtual memory Default check via NRPE::

check_nrpe --host 192.168.56.103 --command check_process --arguments "filter=virtual > 200m"
OK all processes are ok.|'csrss.exe state'=1;0;0 'svchost.exe state'=1;0;0 'AvastSvc.exe state'=1;0;0 ...

Thread count::

check_process process=chrome.exe "warn=thread_count > 400" "detail-syntax=${exe}: ${thread_count} threads"
OK: chrome.exe: 212 threads
Performance data: 'chrome.exe threads'=212;400;0

Percentage-of-RAM / percentage-of-commit thresholds::

check_process process=sqlservr.exe "warn=working_set_pct > 25" "crit=working_set_pct > 40" "detail-syntax=${exe}: ${working_set_pct}% RAM, ${pagefile_pct}% commit"
OK: sqlservr.exe: 12% RAM, 8% commit
Performance data: 'sqlservr.exe ws_pct'=12%;25;40 'sqlservr.exe pf_pct'=8%;;

working_set_pct is the process working set as a percentage of total physical RAM; pagefile_pct is its pagefile (commit) usage as a percentage of the system commit limit (RAM + pagefile). Both work with total=true aggregation.

Linux

Show the owner, parent and state of every matching process:

check_process process=bash "top-syntax=${list}" "detail-syntax=${exe} uid=${uid} ppid=${ppid} proc_state=${proc_state} elapsed=${elapsed}s"
bash uid=1000 ppid=385 proc_state=sleeping elapsed=961739s, bash uid=1000 ppid=381 proc_state=sleeping elapsed=961715s, bash uid=0 ppid=12728 proc_state=sleeping elapsed=961693s

Resolve uids to user names (opt-in, resolve-owner=true):

check_process process=bash resolve-owner=true "top-syntax=${list}" "detail-syntax=${exe} uid=${uid} owner=${username}"
bash uid=1000 owner=mickem, bash uid=1000 owner=mickem, bash uid=0 owner=root

Without the flag uid is still populated; only username stays empty.

Count the processes owned by root (uid is numeric, so it thresholds directly):

check_process process=* "filter=uid = 0" "warn=count > 1000" "ok-syntax=%(status): %(count) processes owned by root"
OK: 27 processes owned by root|'count'=27;1000;0 ...

Alert on zombie processes:

check_process process=* "crit=proc_state = 'zombie'" "ok-syntax=%(status): no zombie processes (%(count) checked)" "detail-syntax=%(exe) (pid %(pid)) is a zombie"
OK: no zombie processes (49 checked)

Alert on processes blocked in uninterruptible I/O (a wedged disk or a hung NFS mount):

check_process process=* "warn=proc_state = 'disk_sleep'" "ok-syntax=%(status): no processes blocked in uninterruptible I/O"
OK: no processes blocked in uninterruptible I/O

Select by parent process id:

check_process process=* "filter=ppid = 1" "ok-syntax=%(status): %(count) processes reparented to init"
OK: 22 processes reparented to init

Threshold on how long a process has been running (elapsed, in seconds):

check_process process=bash "crit=elapsed > 31536000" "top-syntax=${list}" "detail-syntax=${exe} up ${elapsed}s"
bash up 961756s, bash up 961732s, bash up 6183s, bash up 6s|'bash elapsed'=961756s;0;31536000 ...

rss is an alias for working_set (same value, portable with the Windows check):

check_process process=bash "crit=rss > 2G" "top-syntax=${list}" "detail-syntax=${exe} rss=${rss} ws=${working_set}"
bash rss=8.594MB ws=8.594MB, bash rss=9.219MB ws=9.219MB, bash rss=4.688MB ws=4.688MB|'bash rss'=0.00839GB;0;2 ...

Command-line Arguments

Option Default Value Description
process The service to check, set this to * to check all services
scan-info If all process metrics should be fetched (otherwise only status is fetched)
scan-16bit If 16bit processes should be included
delta false Report CPU usage as a percentage of total CPU instead of cumulative seconds.
scan-unreadable If unreadable processes should be included (will not have information)
total false Include the total of all matching files
resolve-owner false Populate the username/uid keywords with the process owner. Off by default: resolving the owner name can block for seconds on domain / Azure-AD accounts.

delta:

Report CPU usage as a percentage of total CPU instead of cumulative seconds. With delta=true the ‘time’ (and ‘kernel’/’user’) fields report the process CPU usage over a one second window as a whole percentage of total CPU. The reading is taken from the CheckSystem background collector (no per-check sleep), so it requires ‘process cpu = true’ under [/settings/system/windows]; without that the check returns UNKNOWN telling you to enable it.

Default Value: false

total:

Include the total of all matching files

Default Value: false

resolve-owner:

Populate the username/uid keywords with the process owner. Off by default: resolving the owner name can block for seconds on domain / Azure-AD accounts.

Default Value: false

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter state != ‘unreadable’
warning state not in (‘started’)
warn
critical state = ‘stopped’, count = 0
crit
ok
debug false
show-all false
empty-state unknown
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${problem_list}
ok-syntax %(status): all processes are ok.
empty-syntax UNKNOWN: No processes found
detail-syntax ${exe}=${state}
perf-syntax ${exe}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Option Default Value Description
process The process to check, set this to * to check all processes
delta Measure CPU usage as a delta over a one second interval.
total false Include the total of all matching processes
resolve-owner false Populate the username keyword with the process owner’s user name. Off by default: the lookup goes through NSS and can block for seconds when it is backed by a remote directory (LDAP/SSSD). The numeric uid keyword is always populated and needs no flag.

delta:

Measure CPU usage as a delta over a one second interval. The check samples process and system CPU times, sleeps for one second, then samples again. With delta=true the ‘time’ (and ‘kernel’/’user’) fields report the process CPU usage during that second as a whole percentage of total CPU, instead of cumulative CPU seconds.

total:

Include the total of all matching processes

Default Value: false

resolve-owner:

Populate the username keyword with the process owner’s user name. Off by default: the lookup goes through NSS and can block for seconds when it is backed by a remote directory (LDAP/SSSD). The numeric uid keyword is always populated and needs no flag.

Default Value: false

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter state != ‘unreadable’
warning state not in (‘started’)
warn
critical state = ‘stopped’, count = 0
crit
ok
debug false
show-all false
empty-state unknown
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${problem_list}
ok-syntax %(status): all processes are ok.
empty-syntax UNKNOWN: No processes found
detail-syntax ${exe}=${state}
perf-syntax ${exe}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
command_line Command line of process (not always available)
creation Creation time
error Any error messages associated with fetching info
exe The name of the executable
filename Name of process (with path)
gdi_handles Number of handles
handles Number of handles
hung Process is hung
kernel Kernel CPU time: cumulative seconds, or % of total CPU with delta=true
legacy_state Get process status (for legacy use via check_nt only)
new Process is new (can inly be used for real-time filters)
page_fault Page fault count
pagefile Peak page file use in bytes (g,m,k,b)
pagefile_pct Page file usage as a percentage of the system commit limit
peak_pagefile Page file usage in bytes (g,m,k,b)
peak_virtual Peak virtual size in bytes (g,m,k,b)
peak_working_set Peak working set in bytes (g,m,k,b)
pid Process id
rss Resident set size; alias for working_set (g,m,k,b)
started Process is started
state The current state (started, stopped, hung); ‘running’ is accepted as a synonym for started
stopped Process is stopped
thread_count Number of threads
time User+kernel CPU time: cumulative seconds, or % of total CPU with delta=true
uid Process owner SID, the Windows analogue of a Unix uid (empty unless resolve-owner=true)
user User CPU time: cumulative seconds, or % of total CPU with delta=true
user_handles Number of handles
username Process owner as DOMAIN\name (empty unless resolve-owner=true, or when the token cannot be read)
virtual Virtual size in bytes (g,m,k,b)
working_set Working set in bytes (g,m,k,b)
working_set_pct Working set as a percentage of total physical RAM

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

Option Description
command_line Command line of process
creation Creation time
elapsed Wall-clock seconds since the process started (0 when not known)
error Any error messages associated with fetching info
exe The name of the executable
filename Name of process (with path)
kernel Kernel time in seconds
page_fault Page fault count
page_faults Page fault count
peak_virtual Peak virtual size in bytes
peak_working_set Peak working set in bytes
pid Process id
ppid Parent process id
proc_state Raw Linux scheduler state (the letter ps prints in its STAT column): running, sleeping, disk_sleep, zombie, stopped, tracing_stop, dead, idle, parked or unknown
rss Resident set size in bytes; alias for working_set, matching the Windows keyword set (g,m,k,b)
started Process is started
state Cross-platform state verdict: started or stopped (‘running’ is accepted as a synonym for started in expressions; the rendered value stays ‘started’)
stopped Process is stopped
time User-kernel time in seconds
uid Real uid of the process owner from /proc//status; -1 when not known (the synthetic ‘not found’ and total rows)
user User time in seconds
username Process owner user name (empty unless resolve-owner=true)
virtual Virtual size in bytes
working_set Working set (RSS) in bytes

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_process_history

Check the history of processes that have been running since NSClient++ started. Useful for verifying if certain applications have been executed.

About check_process_history

check_process_history reports the processes NSClient++ has seen running since the agent started — including ones that have long since exited. It answers the question a point-in-time check_process cannot: did this ever run?

One record is returned per distinct executable, carrying exe, whether it is running right now, first_seen / last_seen timestamps and times_seen (how many collector ticks observed it).

It must be turned on first

The history is kept by the CheckSystem background collector, which does not track it by default. Enable it once:

[/settings/system/windows]
process history = true

([/settings/system/unix] on Linux.) Until it is enabled the check returns UNKNOWN and names the setting, rather than reporting an empty history that would be easy to mistake for “nothing ran”:

check_process_history
UNKNOWN: Process history is not enabled (set 'process history = true' under /settings/system/windows)

The path in that message is the module’s own settings path, so it reads /settings/system/unix on Linux.

The window is the agent’s uptime

History lives in memory and starts empty when the agent starts. A restarted agent has no history, and there is no persistence across restarts — so first_seen means “first seen since this agent process started”, not “first seen on this machine”. Read the results alongside check_uptime or check_nscp’s uptime when the window matters.

What it is good for

The typical uses are verifying that scheduled work actually ran, and catching things that ran when they should not have:

check_process_history process=backup.exe "crit=times_seen = 0"
check_process_history "crit=exe like 'psexec'" "top-syntax=${status}: ${problem_list}"

process= restricts the check to specific executable names (repeatable, case-insensitive); with no process= every process in the history is reported. There are no default thresholds, and the default empty state is OK.

For the narrower question “what appeared recently”, use check_process_history_new, which takes a time= window and reports only processes first seen inside it.

Check the history of processes seen since NSClient++ started (requires ‘process history = true’).

About check_process_history

check_process_history reports the processes NSClient++ has seen running since the agent started — including ones that have long since exited. It answers the question a point-in-time check_process cannot: did this ever run?

One record is returned per distinct executable, carrying exe, whether it is running right now, first_seen / last_seen timestamps and times_seen (how many collector ticks observed it).

It must be turned on first

The history is kept by the CheckSystem background collector, which does not track it by default. Enable it once:

[/settings/system/windows]
process history = true

([/settings/system/unix] on Linux.) Until it is enabled the check returns UNKNOWN and names the setting, rather than reporting an empty history that would be easy to mistake for “nothing ran”:

check_process_history
UNKNOWN: Process history is not enabled (set 'process history = true' under /settings/system/windows)

The path in that message is the module’s own settings path, so it reads /settings/system/unix on Linux.

The window is the agent’s uptime

History lives in memory and starts empty when the agent starts. A restarted agent has no history, and there is no persistence across restarts — so first_seen means “first seen since this agent process started”, not “first seen on this machine”. Read the results alongside check_uptime or check_nscp’s uptime when the window matters.

What it is good for

The typical uses are verifying that scheduled work actually ran, and catching things that ran when they should not have:

check_process_history process=backup.exe "crit=times_seen = 0"
check_process_history "crit=exe like 'psexec'" "top-syntax=${status}: ${problem_list}"

process= restricts the check to specific executable names (repeatable, case-insensitive); with no process= every process in the history is reported. There are no default thresholds, and the default empty state is OK.

For the narrower question “what appeared recently”, use check_process_history_new, which takes a time= window and reports only processes first seen inside it.

Jump to section:

Sample Commands

Before the history is turned on:

The history is kept by the CheckSystem background collector, which is off by default.

check_process_history
UNKNOWN: Process history is not enabled (set 'process history = true' under /settings/system/unix)

Enable it once ([/settings/system/windows] on Windows):

[/settings/system/unix]
process history = true

Default check (an inventory of everything seen since the agent started):

There are no default thresholds, so a bare call is always OK and reports the count.

check_process_history
OK: 91 processes in history.

Restrict to specific executables (process=, repeatable, case-insensitive):

check_process_history process=nscp process=make
OK: 2 processes in history.

Show the detail for a process:

The default top-syntax renders only the problem list, so with no threshold set you get the OK summary. Ask for the full list to see the per-process detail.

check_process_history process=nscp "top-syntax=${status}: ${list}" "detail-syntax=${exe} running=${running} seen=${times_seen}"
OK: nscp running=true seen=1

first_seen / last_seen are timestamps and support date comparisons:

check_process_history process=nscp "detail-syntax=${exe} running=${running} seen=${times_seen} first=${first_seen}" show-all
OK: nscp running=true seen=1 first=2026-09-04 12:56:43

Count only what is still running:

check_process_history "filter=running = 'true'" "top-syntax=${status}: ${count} still running"
OK: 79 still running

Alert on something that should never have run:

Note that like is a substring match, so a short pattern matches more than you expect — here 'nc' matches a kernel worker thread.

check_process_history "crit=exe like 'nc'" "top-syntax=${status}: ${problem_list}"
CRITICAL: kworker/R-sync_wq (true)

Anchor the pattern or use = for an exact name when you mean one binary.

Verify that a scheduled job actually ran:

check_process_history process=backup.exe "crit=times_seen = 0"
CRITICAL: backup.exe (false)

The window is the agent’s uptime:

History lives in memory and starts empty at agent start, so first_seen means “first seen since this agent process started”, not “first seen on this machine”. A restarted agent reports an empty history:

check_process_history
OK: 0 processes in history.

Over NRPE against a remote host:

check_nrpe --host 192.168.56.103 --command check_process_history --arguments "process=backup.exe" --arguments "crit=times_seen = 0"
OK: 1 processes in history.

Command-line Arguments

Option Default Value Description
process Filter to specific process names. Can be specified multiple times. If not specified, all processes in history are shown.

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning
warn
critical
crit
ok
debug false
show-all false
empty-state ok
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${problem_list}
ok-syntax %(status): ${count} processes in history.
empty-syntax
detail-syntax ${exe} (${running})
perf-syntax ${exe}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
currently_running Whether the process is currently running (1/0)
exe The name of the executable
first_seen Unix timestamp when process was first seen
last_seen Unix timestamp when process was last seen
running Whether the process is currently running: ‘true’ or ‘false’
times_seen Number of times the process has been observed running

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_process_history_new

Check for new processes that appeared within a specified time window. Useful for detecting unexpected or unauthorized applications.

About check_process_history_new

check_process_history_new reports processes that were first seen within a recent time window — i.e. processes that started (or first appeared to the agent) recently. It is useful for spotting unexpected launches, flapping services that keep restarting, or confirming that a scheduled job actually ran.

It relies on the background process-history collector, which must be enabled:

[/settings/system/windows]
process history = true

([/settings/system/unix] on Linux.) Until that is set the check returns UNKNOWN and names the setting, quoting the module’s own settings path — so the message reads /settings/system/windows on Windows and /settings/system/unix on Linux:

check_process_history_new
UNKNOWN: Process history is not enabled (set 'process history = true' under /settings/system/windows)

time= sets how far back “new” reaches — 30s, 5m, 1h — and defaults to 5m.

There are no default thresholds; the empty result is OK: No new processes found. Threshold on count to alert on any new process, or filter by exe to watch for a specific program starting. See also the companion check_process_history (full history rather than just recently-new).

Check for processes first seen within a recent time window (requires ‘process history = true’).

About check_process_history_new

check_process_history_new reports processes that were first seen within a recent time window — i.e. processes that started (or first appeared to the agent) recently. It is useful for spotting unexpected launches, flapping services that keep restarting, or confirming that a scheduled job actually ran.

It relies on the background process-history collector, which must be enabled:

[/settings/system/windows]
process history = true

([/settings/system/unix] on Linux.) Until that is set the check returns UNKNOWN and names the setting, quoting the module’s own settings path — so the message reads /settings/system/windows on Windows and /settings/system/unix on Linux:

check_process_history_new
UNKNOWN: Process history is not enabled (set 'process history = true' under /settings/system/windows)

time= sets how far back “new” reaches — 30s, 5m, 1h — and defaults to 5m.

There are no default thresholds; the empty result is OK: No new processes found. Threshold on count to alert on any new process, or filter by exe to watch for a specific program starting. See also the companion check_process_history (full history rather than just recently-new).

Jump to section:

Sample Commands

List processes first seen in the last few minutes (needs the collector):

check_process_history_new
OK: No new processes found.

When the collector is not enabled it tells you exactly what to set:

The path quoted is the module’s own settings path, so it reads /settings/system/unix on Linux and /settings/system/windows on Windows:

check_process_history_new
UNKNOWN: Process history is not enabled (set 'process history = true' under /settings/system/unix)

Widen the “recently started” window to one hour:

check_process_history_new time=1h
OK: No new processes found.

Alert when any new process appears (e.g. detect unexpected launches):

check_process_history_new time=10m "warn=count > 0"
WARNING: /usr/bin/rogue (first seen: 1720000000)

Watch for a specific executable starting:

check_process_history_new "crit=exe = '/usr/bin/nmap'"
OK: No new processes found.

Command-line Arguments

Option Default Value Description
time 5m Time window to check for new processes (e.g., 5m, 1h, 30s). Processes first seen within this window are considered new.
time:

Time window to check for new processes (e.g., 5m, 1h, 30s). Processes first seen within this window are considered new.

Default Value: 5m

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning
warn
critical
crit
ok
debug false
show-all false
empty-state ok
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax %(status): No new processes found.
empty-syntax
detail-syntax ${exe} (first seen: ${first_seen})
perf-syntax ${exe}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
currently_running Whether the process is currently running (1/0)
exe The name of the executable
first_seen Unix timestamp when process was first seen
last_seen Unix timestamp when process was last seen
running Whether the process is currently running: ‘true’ or ‘false’
times_seen Number of times the process has been observed running

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_registry_key

Available on Windows only.

Check existence, last-write time, and child counts of one or more Windows registry keys.

About check_registry_key

check_registry_key inspects registry keys — whether they exist, when they were last written, and how many values and sub-keys they hold. Use check_registry_value when you care about the contents of a specific value instead.

At least one key= is required (repeatable), given as a full path including the hive, e.g. HKLM\Software\MyApp. The default critical threshold is not exists, so a bare call is an existence probe: name a key and the check goes critical if it is missing.

Existence as a policy check

The exists keyword is the reason this check earns its place: a great deal of Windows configuration is “this key is present” or “this key is absent”. Both directions are one expression:

check_registry_key key=HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate
check_registry_key key=HKLM\SOFTWARE\SomeVendor "crit=exists = 1"

Note that empty-state is unknown, so a check that matches nothing at all reports UNKNOWN rather than a misleading OK.

Change detection

written is the key’s last-write timestamp (epoch seconds, comparable as a date) and age the seconds since. Together they turn the check into a tamper/drift probe for keys that are supposed to be stable:

check_registry_key key=HKLM\SYSTEM\CurrentControlSet\Services\MyService "crit=age < 1d"

Be aware that Windows updates a key’s last-write time for changes to its values as well as its sub-keys, and that the timestamp is not maintained for every hive with the same fidelity — treat it as a strong hint rather than an audit record.

Enumeration, views and remote hosts

recursive=true walks the sub-keys below each starting key, bounded by max-depth= (-1, the default under recursive, means unlimited). Without recursive only the named key itself is examined. exclude= drops sub-keys by name during enumeration.

view= selects the registry view on 64-bit Windows: default, 32 (KEY_WOW64_32KEY) or 64 (KEY_WOW64_64KEY). This matters more often than it looks — a 32-bit installer writes under Wow6432Node, and a check that does not pin the view can report “missing” for a key that is plainly there in regedit.

computer= connects to a remote machine’s registry, which requires the Remote Registry service to be running there and appropriate rights; running the check locally on the monitored host is both faster and easier to secure.

Jump to section:

Sample Commands

Default check (single key, just verifies it exists):

check_registry_key "key=HKLM\Software\Microsoft\Windows NT\CurrentVersion"
OK: All 1 registry key(s) are ok.

Key that does not exist (default crit=not exists):

check_registry_key "key=HKLM\Software\DoesNotExist"
CRITICAL: HKLM\Software\DoesNotExist: exists=false, subkeys=0, values=0

Check several keys in one call:

check_registry_key "key=HKLM\Software\Microsoft\Windows NT\CurrentVersion" "key=HKLM\Software\NSClient"
OK: All 2 registry key(s) are ok.

Wildcard / recursive enumeration of immediate sub-keys:

check_registry_key "key=HKLM\Software\Microsoft\Windows NT\CurrentVersion" recursive max-depth=1 "top-syntax=%(status): %(list)" "detail-syntax=%(name) (subkeys=%(subkey_count), values=%(value_count))"
OK: AeDebug (subkeys=1, values=2), Compatibility32 (subkeys=0, values=0), Console (subkeys=4, values=18), ...

Force a 32-bit or 64-bit registry view (WoW64):

check_registry_key "key=HKLM\Software\NSClient" view=64
OK: All 1 registry key(s) are ok.

check_registry_key "key=HKLM\Software\NSClient" view=32
CRITICAL: HKLM\Software\NSClient: exists=false, subkeys=0, values=0

Exclude noisy sub-keys when recursing:

check_registry_key "key=HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall" recursive max-depth=1 exclude=KB5005463 exclude=KB5005539
OK: All 248 registry key(s) are ok.

Alert when a key is unexpectedly empty:

check_registry_key "key=HKLM\Software\NSClient" "warn=value_count < 5" "crit=value_count = 0 or not exists"
OK: HKLM\Software\NSClient: exists=true, subkeys=2, values=12

Alert when a key has not been written for over 30 days (configuration drift watchdog):

check_registry_key "key=HKLM\Software\NSClient" "warn=age > 7d" "crit=age > 30d or not exists"
OK: HKLM\Software\NSClient: exists=true, subkeys=2, values=12

Custom output text:

check_registry_key "key=HKLM\Software\NSClient" "top-syntax=%(status): %(list)" "detail-syntax=%(path) last-written %(written_s)"
OK: HKLM\Software\NSClient last-written 2026-04-15 09:12:33

Remote computer / 32-bit view via NRPE:

check_nscp_client --host 192.168.56.103 --command check_registry_key --argument "key=HKLM\Software\NSClient" --argument "view=64"
OK: All 1 registry key(s) are ok.

Command-line Arguments

Option Default Value Description
key One or more registry key paths to check (e.g. HKLM\Software\MyApp).
exclude Registry key names to exclude from enumeration
computer Remote computer to connect to (empty = local)
view default Registry view: ‘default’, ‘32’ (KEY_WOW64_32KEY), or ‘64’ (KEY_WOW64_64KEY)
recursive false Recursively enumerate all sub-keys below each starting key
max-depth Maximum recursion depth (requires –recursive; -1 = unlimited)
view:

Registry view: ‘default’, ‘32’ (KEY_WOW64_32KEY), or ‘64’ (KEY_WOW64_64KEY)

Default Value: default

recursive:

Recursively enumerate all sub-keys below each starting key

Default Value: false

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning
warn
critical not exists
crit
ok
debug false
show-all false
empty-state unknown
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${problem_list}
ok-syntax ${status}: All %(count) registry key(s) are ok.
empty-syntax ${status}: No registry keys found
detail-syntax ${path}: exists=${exists}, subkeys=${subkey_count}, values=${value_count}
perf-syntax ${path}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
age Seconds since the key was last written
class Key class string (rarely set)
depth Depth below the starting key (0 = the key itself)
exists Whether the key exists (true/false)
hive Hive abbreviation (HKLM, HKCU, HKCR, HKU, HKCC)
name Leaf key name
parent Parent key path (full, including hive)
path Full registry key path including hive (e.g. HKLM\Software\MyApp)
subkey_count Number of immediate sub-keys
value_count Number of values in this key
written Last-write time (epoch seconds; supports date comparisons)
written_s Last-write time as a human-readable string

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_registry_value

Available on Windows only.

Check the type, content, and size of one or more Windows registry values.

About check_registry_value

check_registry_value inspects registry values — their type, contents and size. Use check_registry_key when you care about the key itself rather than what is in it.

At least one key= is required (repeatable). value= restricts the check to specific value names; omit it, or pass value=*, to enumerate every value in the key. The unnamed default value is reported as (default). The default critical threshold is not exists, so naming a value and running the check bare is an existence probe.

Reading the value

Two keywords carry the contents, and picking the right one matters:

  • string_value is the rendered form and works for every type. Use it for REG_SZ, REG_EXPAND_SZ and REG_MULTI_SZ, and for matching with like.
  • int_value is the numeric value of a REG_DWORD or REG_QWORD, and is 0 for every other type. That zero is a trap: a threshold like crit=int_value = 0 fires on any string value too, so pair it with a type= guard when the key might hold something unexpected.

type compares against the registry type names (REG_SZ, REG_DWORD, …), and size is the raw byte size of the data.

This is the check for verifying that a policy or product setting actually holds the value it is supposed to:

check_registry_value key=HKLM\SYSTEM\CurrentControlSet\Control\Lsa value=RunAsPPL "crit=int_value != 1"
check_registry_value key=HKLM\SOFTWARE\MyApp value=LogLevel "crit=string_value != 'INFO'"
Enumeration, views and remote hosts

recursive=true walks values in sub-keys as well, bounded by max-depth= (unlimited by default under recursive); exclude= drops value names during enumeration. view= selects the 32-bit or 64-bit registry view — the usual cause of a value that is “missing” from the check but visible in regedit — and computer= reads a remote machine’s registry, which needs the Remote Registry service and rights on the target.

empty-state is unknown, so an enumeration that matches nothing reports UNKNOWN rather than OK.

Jump to section:

Sample Commands

Read a single value (default: enumerates all values in the key):

check_registry_value "key=HKLM\Software\Microsoft\Windows NT\CurrentVersion" value=ProductName
OK: HKLM\Software\Microsoft\Windows NT\CurrentVersion\ProductName: Windows 10 Pro (type=REG_SZ)

Read multiple specific values from the same key:

check_registry_value "key=HKLM\Software\Microsoft\Windows NT\CurrentVersion" value=ProductName value=CurrentBuild value=ReleaseId
OK: All 3 registry value(s) are ok.

Enumerate every value in a key:

check_registry_value "key=HKLM\Software\NSClient" "top-syntax=%(status): %(list)" "detail-syntax=%(name)=%(string_value)"
OK: ConfigFile=C:\Program Files\NSClient++\nsclient.ini, InstallVersion=0.6.0, ...

Value that does not exist (default crit=not exists):

check_registry_value "key=HKLM\Software\NSClient" value=NoSuchValue
CRITICAL: HKLM\Software\NSClient\NoSuchValue: (type=REG_NONE)

Type assertion (alert if a value isn’t the expected type):

check_registry_value "key=HKLM\Software\NSClient" value=InstallVersion "crit=type != 'REG_SZ' or not exists"
OK: HKLM\Software\NSClient\InstallVersion: 0.6.0 (type=REG_SZ)

Numeric DWORD / QWORD comparison:

check_registry_value "key=HKLM\System\CurrentControlSet\Services\W32Time\Config" value=MaxPollInterval "warn=int_value > 14" "crit=int_value > 17"
OK: HKLM\System\CurrentControlSet\Services\W32Time\Config\MaxPollInterval: 10 (type=REG_DWORD)

String / content match:

check_registry_value "key=HKLM\Software\NSClient" value=ConfigFile "crit=string_value not like 'C:\\Program Files\\NSClient++\\nsclient.ini'"
OK: HKLM\Software\NSClient\ConfigFile: C:\Program Files\NSClient++\nsclient.ini (type=REG_SZ)

Size watchdog (alert if a binary blob grows unexpectedly):

check_registry_value "key=HKLM\Software\NSClient" value=Cache "warn=size > 4096" "crit=size > 16384"
OK: HKLM\Software\NSClient\Cache: 0xDEADBEEF... (type=REG_BINARY)

Force the 32-bit registry view (WoW64):

check_registry_value "key=HKLM\Software\NSClient" value=InstallDir view=32
OK: HKLM\Software\NSClient\InstallDir: C:\Program Files (x86)\NSClient++\ (type=REG_SZ)

Recursive enumeration of values across an entire sub-tree:

check_registry_value "key=HKLM\Software\NSClient" recursive max-depth=2 "top-syntax=%(status): %(list)" "detail-syntax=%(path)=%(string_value)"
OK: HKLM\Software\NSClient\ConfigFile=..., HKLM\Software\NSClient\modules\enabled=1, ...

Exclude noisy values during enumeration:

check_registry_value "key=HKCU\Software\NSClient" exclude=LastRun exclude=Cache
OK: All 5 registry value(s) are ok.

Custom output text including type / size:

check_registry_value "key=HKLM\Software\NSClient" value=InstallVersion "top-syntax=%(status): %(list)" "detail-syntax=%(name) [%(type)] = %(string_value) (%(size)B)"
OK: InstallVersion [REG_SZ] = 0.6.0 (12B)

Default check via NRPE:

check_nscp_client --host 192.168.56.103 --command check_registry_value --argument "key=HKLM\Software\NSClient" --argument "value=InstallVersion"
OK: HKLM\Software\NSClient\InstallVersion: 0.6.0 (type=REG_SZ)

Command-line Arguments

Option Default Value Description
key One or more registry key paths whose values to check (e.g. HKLM\Software\MyApp)
value Restrict to specific value names (default: all values). Supports ‘*’ to enumerate all.
exclude Value names to exclude from enumeration
computer Remote computer to connect to (empty = local)
view default Registry view: ‘default’, ‘32’ (KEY_WOW64_32KEY), or ‘64’ (KEY_WOW64_64KEY)
recursive false Recursively enumerate values in all sub-keys
max-depth Maximum recursion depth for –recursive (-1 = unlimited)
view:

Registry view: ‘default’, ‘32’ (KEY_WOW64_32KEY), or ‘64’ (KEY_WOW64_64KEY)

Default Value: default

recursive:

Recursively enumerate values in all sub-keys

Default Value: false

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning
warn
critical not exists
crit
ok
debug false
show-all false
empty-state unknown
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${problem_list}
ok-syntax ${status}: %(list).
empty-syntax ${status}: No registry values found
detail-syntax ${path}: ${string_value} (type=${type})
perf-syntax ${path}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
age Seconds since parent key was last written
exists Whether the value exists (true/false)
hive Hive abbreviation (HKLM, HKCU, HKCR, HKU, HKCC)
int_value Numeric value (REG_DWORD / REG_QWORD); 0 for non-numeric types
key Parent key path (full, including hive)
name Value name (‘(default)’ for the unnamed default value)
path Full path: key\name
size Raw byte size of the value data
string_value Value rendered as a string (REG_SZ expanded, REG_DWORD as decimal, REG_BINARY as hex, etc.)
type Value type (REG_SZ, REG_DWORD, etc.)
written Parent key last-write time (epoch seconds; supports date comparisons)
written_s Parent key last-write time as a human-readable string

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_service

Check the state of one or more of the computer services.

About check_service

check_service reports the state of the machine’s services. state is normalised across platforms so the same warning= / critical= expressions read the same way on Windows and Linux; the platform-native fields are exposed alongside it.

Windows

Enumerates the Service Control Manager. Two helper functions make the “is this service actually fine” question expressible in a filter:

state_is_ok

Helper function that checks if the state of a service is “OK”. It returns True if the state is “OK” and False otherwise. This can be used in filter expressions to warn about services that are not running properly.

Configured State exit_code Result of state_is_ok
auto-start running any ✅ ok
delayed auto-start stopped any ✅ ok
auto-start + triggers stopped any ✅ ok
auto-start stopped 0 ✅ ok
auto-start stopped non zero ❌ not ok
demand-start any state any ✅ ok
state_is_perfect

Helper function that checks if the state of a service is “perfect”. It returns True if the state is “perfect” and False otherwise. This can be used in filter expressions to warn about services that are not running perfectly.

Configured State Result of state_is_perfect
auto-start running ✅ perfect
auto-start stopped ❌ not perfect
auto-start + triggers stopped ✅ perfect
demand-start any state ✅ perfect
disabled stopped ✅ perfect
Linux

check_service inspects systemd units (via systemctl show). It maps each unit’s raw systemd state to a normalised state keyword so thresholds read the same way as on Windows, and also exposes the raw systemd fields and the main process’s resource usage.

By default it looks at units that are not inactive (filter = active != 'inactive') and treats a unit as critical when it is not in a healthy state and is not deliberately disabled:

critical = ( state not in ('running', 'oneshot', 'static') or active = 'failed' ) and preset != 'disabled'

An enabled unit that has failed is therefore CRITICAL.

A unit that is merely stopped, however, never reaches that threshold: the default filter active != 'inactive' excludes it before the critical expression is evaluated. With nothing left to match, the check falls to its empty state, which is unknown:

check_service service=nginx
UNKNOWN: No services found

service=<name> (repeatable) narrows which units are enumerated; it does not bypass the filter. To alert on a unit being stopped rather than failed, widen the filter so inactive units are considered:

check_service service=nginx filter=none "crit=state != 'running'"

exclude= drops units by name, and state= (all, active, inactive, failed) restricts the enumeration before filtering.

Jump to section:

Sample Commands

Windows

Default check:

check_service
OK all services are ok.

Excluding services using exclude::

check_service "exclude=clr_optimization_v4.0.30319_32"  "exclude=clr_optimization_v4.0.30319_64"
WARNING: gupdate=stopped (auto), Net Driver HPZ12=stopped (auto), NSClientpp=stopped (auto), nscp=stopped (auto), Pml Driver HPZ12=stopped (auto), SkypeUpdate=stopped (auto), sppsvc=stopped (auto)

Show all service by changing the syntax::

check_service "top-syntax=${list}" "detail-syntax=${name}:${state}"
AdobeActiveFileMonitor10.0:running, AdobeARMservice:running, AdobeFlashPlayerUpdateSvc:stopped, ..., WwanSvc:stopped

Excluding services using the filter::

check_service "filter=start_type = 'auto' and name not in ('Bonjour Service', 'Net Driver HPZ12')"
AdobeActiveFileMonitor10.0: running, AdobeARMservice: running, AMD External Events Utility: running,  ... wuauserv: running

Exclude versus filter::

You can use both exclude and filter to exclude services the befnefit of exclude is that it is faster with the obvious drawback that it only works on the service name. The upside to filters are that they are richer in terms of functionality i.e. substring matching (as below).

Regular check

check_service
CRITICAL: CRITICAL: nfoo=stopped (auto), nscp=stopped (auto), nscp2=stopped (auto), ...

Excluding nfoo service with exclude:

check_service exclude=nfoo
CRITICAL: CRITICAL: nscp=stopped (auto), nscp2=stopped (auto), ...

Excluding nscp2 with substring like matching filter:

check_service exclude=nfoo "filter=name not like 'nscp'"
CRITICAL: CRITICAL: ...

Default check via NRPE::

check_nrpe --host 192.168.56.103 --command check_service
WARNING: DPS=stopped (auto), MSDTC=stopped (auto), sppsvc=stopped (auto), UALSVC=stopped (auto)

Check that a service is not started::

check_service service=nscp "crit=state = 'started'" warn=none

Dashboard rollup with summary (aggregate state-count perfdata)::

Adding summary emits per-state counts across all enumerated services as performance data, so a dashboard gets running/stopped/paused/pending/total rollups without a custom top-syntax:

check_service summary "filter=none"
OK: All 214 service(s) are ok.
'running_services'=118 'stopped_services'=94 'paused_services'=0 'pending_services'=2 'service_count'=214

The counts cover every matched service regardless of the warning/critical filter, so the rollup is stable even when the check itself is OK.

Linux

Check all services (the default watches enabled units for failures):

check_service
OK: All 42 service(s) are ok.

Check one service by name:

check_service service=cron
OK: All 1 service(s) are ok.

Show the mapped state, raw systemd state and vendor preset:

check_service service=cron "top-syntax=${list}" "detail-syntax=${name}=${state} active=${active} preset=${preset}"
cron=running active=active preset=enabled

A failed enabled service is CRITICAL:

check_service service=nginx
CRITICAL: nginx=failed

A merely stopped service is filtered out, not reported:

The default filter is active != 'inactive', so a cleanly stopped unit never reaches the critical expression and the check falls to its empty state:

check_service service=nginx
UNKNOWN: No services found

service= narrows which units are enumerated; it does not bypass the filter.

Alert on a specific service not running (stopped included):

Widen the filter so inactive units are considered:

check_service service=ssh filter=none "crit=state != 'running'"
OK: All 1 service(s) are ok.

Alert on a service using too much memory (process metrics):

check_service service=mysql "warn=rss > 1G" "crit=rss > 2G" "detail-syntax=${name} rss=${rss} cpu=${cpu}%"
OK: All 1 service(s) are ok.

Check via NRPE:

check_nrpe --host 192.168.56.103 --command check_service --arguments "service=docker"
OK: All 1 service(s) are ok.

Command-line Arguments

Option Default Value Description
computer The name of the remote computer to check
service The service to check, set this to * to check all services
exclude A list of services to ignore (mainly useful in combination with service=*)
type service The types of services to enumerate available types are driver, file-system-driver, kernel-driver, service, service-own-process, service-share-process
state all The types of services to enumerate available states are active, inactive or all
only-essential false Set filter to classification = ‘essential’
only-ignored false Set filter to classification = ‘ignored’
only-role false Set filter to classification = ‘role’
only-supporting false Set filter to classification = ‘supporting’
only-system false Set filter to classification = ‘system’
only-user false Set filter to classification = ‘user’
summary false Emit aggregate state-count performance data (running_services/stopped_services/paused_services/pending_services/service_count) across all enumerated services, for dashboard rollups.

type:

The types of services to enumerate available types are driver, file-system-driver, kernel-driver, service, service-own-process, service-share-process

Default Value: service

state:

The types of services to enumerate available states are active, inactive or all

Default Value: all

only-essential:

Set filter to classification = ‘essential’

Default Value: false

only-ignored:

Set filter to classification = ‘ignored’

Default Value: false

only-role:

Set filter to classification = ‘role’

Default Value: false

only-supporting:

Set filter to classification = ‘supporting’

Default Value: false

only-system:

Set filter to classification = ‘system’

Default Value: false

only-user:

Set filter to classification = ‘user’

Default Value: false

summary:

Emit aggregate state-count performance data (running_services/stopped_services/paused_services/pending_services/service_count) across all enumerated services, for dashboard rollups.

Default Value: false

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning not state_is_perfect()
warn
critical not state_is_ok()
crit
ok
debug false
show-all false
empty-state unknown
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${crit_list}, delayed (${warn_list})
ok-syntax %(status): All %(count) service(s) are ok.
empty-syntax %(status): No services found
detail-syntax ${name}=${state}, exit=%(exit_code), type=%(start_type)
perf-syntax ${name}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Option Default Value Description
service The service to check, set this to * to check all services
exclude A list of services to ignore (mainly useful in combination with service=*)
state all The state of services to enumerate: active, inactive, failed, or all

state:

The state of services to enumerate: active, inactive, failed, or all

Default Value: all

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter active != ‘inactive’
warning
warn
critical ( state not in (‘running’, ‘oneshot’, ‘static’) or active = ‘failed’ ) and preset != ‘disabled’
crit
ok
debug false
show-all false
empty-state unknown
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${crit_list}
ok-syntax %(status): All %(count) service(s) are ok.
empty-syntax %(status): No services found
detail-syntax ${name}=${state}
perf-syntax ${name}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
classification Get classification
delayed If the service is delayed
desc Service description
exit_code The Win32 exit code of the service
is_trigger If the service is has associated triggers
legacy_state Get legacy state (deprecated and only used by check_nt)
name Service name
pid Process id
start_type The configured start type ()
state The current state ()
state_is_ok() Check if the state is ok, i.e. all running services are running (delayed services are allowed to be stopped)
state_is_perfect() Check if the state is ok, i.e. all running services are running
triggers The number of associated triggers for this service

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

Option Description
active Raw systemd ActiveState (active, inactive, failed)
age Seconds since the main process started
cpu CPU usage of the main process in percent (lifetime average)
created Unix timestamp when the main process started
desc Unit description
name Unit (service) name
pid Main process id
preset Vendor preset (enabled, disabled)
rss Resident memory of the main process in bytes
service Alias for name
start_type The configured start type (enabled, disabled, static, masked)
started Service is started/active
state The mapped service state (stopped, starting, oneshot, running, static, unknown)
state_is_ok() Check if the state is ok (enabled services running or starting, disabled services can be any state)
state_is_perfect() Check if the state is perfect (enabled services running, disabled services stopped)
stopped Service is stopped/inactive
sub_state Raw systemd SubState (running, dead, exited, …)
tasks Number of tasks (cgroup) for this service
vms Virtual memory of the main process in bytes

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_swap_io

Check system paging (swap) I/O rates: pages/bytes paged in and out per second.

About check_swap_io

check_swap_io measures how fast the system is paging to and from swap. It samples the underlying counters over a ~1 second window and reports the rate. Sustained non-zero swap I/O is a strong signal of memory pressure — often more actionable than swap usage, since a box can sit with swap full but idle, or with little swap used yet thrashing hard.

The keyword vocabulary is identical on both platforms, so warning/critical expressions and detail-syntax port between them. There are no default thresholds: sustained paging is workload dependent, and a default would warn on legitimately busy hosts. Set a threshold on swap_in / swap_out (pages/s) or swap_in_bytes / swap_out_bytes (bytes/s) for the host in question.

Windows

Sourced from the memory performance counters \Memory\Pages Input/sec and \Memory\Pages Output/sec. Windows has no per-pagefile I/O counter, so this is a single system-wide aggregate row.

Note: on Windows these are system-wide paging rates (pages moved between disk and physical memory) — the correct analogue of Linux swap-in/out — not literal per-pagefile read/write bytes.

Linux

Reads pswpin / pswpout from /proc/vmstat. On a host with no swap configured the rates are simply 0.

Check the swap in/out paging rate.

About check_swap_io

check_swap_io measures how fast the system is paging to and from swap. It samples the underlying counters over a ~1 second window and reports the rate. Sustained non-zero swap I/O is a strong signal of memory pressure — often more actionable than swap usage, since a box can sit with swap full but idle, or with little swap used yet thrashing hard.

The keyword vocabulary is identical on both platforms, so warning/critical expressions and detail-syntax port between them. There are no default thresholds: sustained paging is workload dependent, and a default would warn on legitimately busy hosts. Set a threshold on swap_in / swap_out (pages/s) or swap_in_bytes / swap_out_bytes (bytes/s) for the host in question.

Windows

Sourced from the memory performance counters \Memory\Pages Input/sec and \Memory\Pages Output/sec. Windows has no per-pagefile I/O counter, so this is a single system-wide aggregate row.

Note: on Windows these are system-wide paging rates (pages moved between disk and physical memory) — the correct analogue of Linux swap-in/out — not literal per-pagefile read/write bytes.

Linux

Reads pswpin / pswpout from /proc/vmstat. On a host with no swap configured the rates are simply 0.

Jump to section:

Sample Commands

Default check (current paging rate):

check_swap_io
OK: 1 page file(s), in 0 pages/s, out 0 pages/s|'io_swap_in'=0;;; 'io_swap_out'=0;;; 'io_swap_in_bytes'=0B;;; 'io_swap_out_bytes'=0B;;;

On Linux the same call names swap devices rather than page files:

check_swap_io
OK: 1 swap device(s) in 0 pages/s, out 0 pages/s|'io_swap_in'=0;0;0 'io_swap_out'=0;0;0 'io_swap_in_bytes'=0;0;0 'io_swap_out_bytes'=0;0;0

Alert on sustained paging (pages/s):

check_swap_io "warn=swap_in > 1000" "crit=swap_in > 5000"
OK: 1 page file(s), in 42 pages/s, out 7 pages/s|'io_swap_in'=42;1000;5000; 'io_swap_out'=7;;; 'io_swap_in_bytes'=172032B;;; 'io_swap_out_bytes'=28672B;;;

Alert in either direction:

check_swap_io "warn=swap_in > 100 or swap_out > 100" "crit=swap_in > 1000 or swap_out > 1000"
OK: 1 swap device(s) in 0 pages/s, out 0 pages/s

Threshold on throughput (bytes/s) with a custom output line:

check_swap_io "crit=swap_out_bytes > 10485760" "detail-syntax=in ${swap_in_bytes}B/s, out ${swap_out_bytes}B/s"
OK: in 172032B/s, out 28672B/s|'io_swap_in_bytes'=172032B;;; 'io_swap_out_bytes'=28672B;;10485760;

Command-line Arguments

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning
warn
critical
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax ${swap_count} page file(s), in ${swap_in} pages/s, out ${swap_out} pages/s
perf-syntax io
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning
warn
critical
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax ${swap_count} swap device(s) in ${swap_in} pages/s, out ${swap_out} pages/s
perf-syntax io
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
name Always ‘swap’ (single aggregate row)
swap_count Number of page files on the system
swap_in Pages paged in from disk per second (perfdata io_swap_in)
swap_in_bytes Bytes paged in per second — swap_in multiplied by the system page size (perfdata io_swap_in_bytes)
swap_out Pages paged out to disk per second (perfdata io_swap_out)
swap_out_bytes Bytes paged out per second (perfdata io_swap_out_bytes)

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

Option Description
name Always ‘swap’ (single aggregate row)
swap_count Number of active swap devices
swap_in Pages swapped in per second
swap_in_bytes Bytes swapped in per second (pages x page size)
swap_out Pages swapped out per second
swap_out_bytes Bytes swapped out per second (pages x page size)

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_temperature

Check ACPI thermal zone temperatures.

About check_temperature

check_temperature reports thermal sensor readings, one record per zone or sensor, in degrees Celsius. The defaults are temperature > 70 (warning) and temperature > 90 (critical).

Sensor availability is the main caveat

Thermal sensors are hardware- and driver-dependent, and a great deal of the infrastructure this agent runs on does not expose any:

  • Virtual machines almost never present thermal zones — the hypervisor owns the hardware.
  • Cloud instances likewise.
  • On Linux, readings come from the kernel’s thermal zones and hwmon sensors (/sys/class/thermal, /sys/class/hwmon), so a sensor needs a loaded driver to appear. sensors-detect from lm-sensors is the usual way to find out what a given box can report.
  • On Windows, ACPI thermal zones are read through WMI, and many vendors expose either nothing or a single coarse zone rather than per-component sensors.

A host with no readable sensors does not fall through to the filter’s empty state at all: the check returns UNKNOWN: No temperature sensors found before filtering. So on a VM this check is permanently UNKNOWN rather than quietly OK — which is honest, but means it should only be enabled where the hardware actually reports something.

Naming is not portable

name is whatever the platform calls the zone — thermal_zone0, coretemp Package id 0, TZ00 — and it differs between machines, vendors and kernel versions. Do not hard-code a sensor name in a fleet-wide check; threshold across all of them and use detail-syntax to identify the offender in the message.

A sensible fleet-wide shape is a generous threshold on everything, since the absolute numbers vary a lot between a CPU package sensor and a chassis sensor:

check_temperature "warn=temperature > 75" "crit=temperature > 90" "detail-syntax=${name}=${temperature}C"

active reports whether the zone is currently active; on Windows throttle_reasons carries the ACPI throttle bitmask, which is a more direct signal that thermal limits are actually biting than the temperature alone.

Check temperature sensors (thermal zones / hwmon).

About check_temperature

check_temperature reports thermal sensor readings, one record per zone or sensor, in degrees Celsius. The defaults are temperature > 70 (warning) and temperature > 90 (critical).

Sensor availability is the main caveat

Thermal sensors are hardware- and driver-dependent, and a great deal of the infrastructure this agent runs on does not expose any:

  • Virtual machines almost never present thermal zones — the hypervisor owns the hardware.
  • Cloud instances likewise.
  • On Linux, readings come from the kernel’s thermal zones and hwmon sensors (/sys/class/thermal, /sys/class/hwmon), so a sensor needs a loaded driver to appear. sensors-detect from lm-sensors is the usual way to find out what a given box can report.
  • On Windows, ACPI thermal zones are read through WMI, and many vendors expose either nothing or a single coarse zone rather than per-component sensors.

A host with no readable sensors does not fall through to the filter’s empty state at all: the check returns UNKNOWN: No temperature sensors found before filtering. So on a VM this check is permanently UNKNOWN rather than quietly OK — which is honest, but means it should only be enabled where the hardware actually reports something.

Naming is not portable

name is whatever the platform calls the zone — thermal_zone0, coretemp Package id 0, TZ00 — and it differs between machines, vendors and kernel versions. Do not hard-code a sensor name in a fleet-wide check; threshold across all of them and use detail-syntax to identify the offender in the message.

A sensible fleet-wide shape is a generous threshold on everything, since the absolute numbers vary a lot between a CPU package sensor and a chassis sensor:

check_temperature "warn=temperature > 75" "crit=temperature > 90" "detail-syntax=${name}=${temperature}C"

active reports whether the zone is currently active; on Windows throttle_reasons carries the ACPI throttle bitmask, which is a more direct signal that thermal limits are actually biting than the temperature alone.

Jump to section:

Sample Commands

A host with no readable sensors:

Most VMs and cloud instances expose no thermal zones at all. The check returns UNKNOWN before the filter runs, rather than a misleading OK.

check_temperature
UNKNOWN: No temperature sensors found

Default check on hardware that does report (> 70 warns, > 90 is critical):

check_temperature
OK: thermal_zone0: 42 C, thermal_zone1: 38 C|'thermal_zone0'=42;70;90 'thermal_zone1'=38;70;90

Fleet-wide thresholds:

Sensor names differ between machines, vendors and kernel versions, so threshold across all of them and let detail-syntax name the offender rather than hard-coding a zone.

check_temperature "warn=temperature > 75" "crit=temperature > 90" "detail-syntax=${name}=${temperature}C"
CRITICAL: coretemp Package id 0=94C

Watch one specific sensor:

check_temperature "filter=name like 'Package'" "crit=temperature > 85"
OK: coretemp Package id 0: 61 C

Only the zones that are currently active:

check_temperature "filter=active = 1" "detail-syntax=${name}=${temperature}C"
OK: thermal_zone0=42C

Over NRPE against a remote host:

check_nrpe --host 192.168.56.103 --command check_temperature --arguments "crit=temperature > 90"
OK: thermal_zone0: 42 C, thermal_zone1: 38 C

Command-line Arguments

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning temperature > 70
warn
critical temperature > 90
crit
ok
debug false
show-all false
empty-state critical
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax %(status): All thermal zones seem ok.
empty-syntax
detail-syntax ${name}: ${temperature} C
perf-syntax ${name}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning temperature > 70
warn
critical temperature > 90
crit
ok
debug false
show-all false
empty-state critical
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax %(status): Temperature is ok.
empty-syntax
detail-syntax ${name}: ${temperature}C
perf-syntax ${name}
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
active True if the thermal zone is active
name Thermal zone name
temperature Temperature in degrees Celsius
throttle_reasons Throttle reasons bitmask

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

Option Description
active Whether the sensor is active
name Thermal zone / sensor name
temperature Temperature in degrees Celsius

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_uptime

Check time since last server re-boot.

About check_uptime

check_uptime reports how long the machine has been running since its last boot, as a single aggregate row.

The defaults invert the usual reading of “uptime”: the check warns when uptime is less than 2 days and goes critical below 1 day. That is deliberate — a low uptime means the machine has just rebooted, which is the event worth alerting on. A high uptime is only a problem if your patching policy makes it one, in which case invert the comparison:

check_uptime "warn=uptime > 90d" "crit=uptime > 180d"

uptime accepts units, so thresholds are written the way you think about them (2d, 12h, 90d) rather than in raw seconds.

Rendering the duration

max-unit= controls the largest unit ${uptime} is rendered in — s, m, h, d or w, defaulting to w. For a six-week uptime, w renders 6w 0d 00:00, d renders 42d 00:00 and h renders 1008:00. Pick whichever reads best for the audience; it affects only the rendered string, never the comparisons.

Boot time and timezone

boot is the wall-clock time the machine came up, derived as now minus uptime, and ${tz} renders the timezone label it is expressed in. Both follow the module’s configured timezone (default local), so the boot time in the message matches the clock an operator is reading it against.

The same duration formatting and unit handling is shared with check_nscp’s uptime and crash_age keywords, so thresholds written for one read the same way in the other.

Jump to section:

Sample Commands

Default check:

check_uptime
uptime: -9:02, boot: 2013-aug-18 08:29:13 (local)
'uptime uptime'=1376814553s;1376760683;1376803883

Adding warning and critical thresholds::

check_uptime "warn=uptime < -2d" "crit=uptime < -1d"
...

Default check via NRPE::

check_nrpe --host 192.168.56.103 --command check_uptime
uptime: -0:3, boot: 2013-sep-08 18:41:06 (local)|'uptime'=1378665666;1378579481;1378622681

Configuring the timezone (added in 0.6.x). The default syntax renders the boot timestamp in the configured zone and surfaces a short label via the ${tz} placeholder. The value is cached by each plugin in its loadModuleEx and is read from the global /settings/default/timezone setting. Accepted values: local (default), utc, or any POSIX TZ string parseable by Boost.Date_time (for example MST-07 or EST-05EDT,M3.2.0,M11.1.0).

Choosing the display granularity for ${uptime} (issue #590). The max-unit argument selects the largest unit allowed when rendering ${uptime}. Accepted values: s|m|h|d|w (default w). For example, on a host that has been up six weeks, max-unit=w renders 6w 0d 00:00, max-unit=d renders 42d 00:00, and max-unit=h renders 1008:00:

check_uptime max-unit=d "detail-syntax=uptime: ${uptime}, boot: ${boot} (${tz})"

Command-line Arguments

Option Default Value Description
max-unit w Largest time unit used to render ${uptime}: s
max-unit:

Largest time unit used to render ${uptime}: s|m|h|d|w (default: w). For a 6-week uptime, w=>‘6w 0d 00:00’, d=>‘42d 00:00’, h=>‘1008:00’.

Default Value: w

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning uptime < 2d
warn
critical uptime < 1d
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax uptime: ${uptime}h, boot: ${boot} (${tz})
perf-syntax uptime
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
boot System boot time
uptime Time since last boot

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

check_w32time

Available on Windows only.

Check the Windows Time service: whether the machine is following a time source at all, which one, the computed clock offset and the configured peers.

About check_w32time

check_w32time reports what the Windows Time service (W32Time) itself thinks: whether the machine is following a time source at all, which source that is, how far the clock was last computed to be off and which peers are configured. This is the inside-out counterpart to CheckNet’s check_ntp_offset, which probes an NTP server from the outside: a domain member whose time hierarchy has broken keeps answering with a plausible clock for hours while Kerberos ticket validation is already on its way to failing, and only the service’s own view shows it.

The data is assembled from four places:

Source What it gives
Service control manager Whether W32Time exists, is running, and how it starts.
HKLM\SYSTEM\CurrentControlSet\Services\W32Time\Parameters Type (the synchronization mode) and NtpServer (the configured peers).
HKLM\SYSTEM\CurrentControlSet\Services\W32Time\Config\LastKnownGoodTime When the service last recorded the clock as good.
W32TimeQuerySource (w32time.dll) The source the running service is actually following. Like w32tm /query /source, this needs privilege: the agent has it running as a service, an unprivileged caller gets access denied and the check falls back to the configured peers.
“Windows Time Service” PDH counters Computed time offset, NTP round trip delay, clock frequency adjustment and the number of time sources in use.

The counter-backed keywords — offset, delay, frequency_adjustment, time_sources and last_sync_age — come from counters the service only maintains while it runs. When there is no measurement they render as unknown, compare false against every number (so a threshold like offset > 1000 cannot fire on a missing value) and emit no perfdata. Test for the absence explicitly with offset = 'unknown'.

synchronized ranks its evidence rather than guessing. The service not running or Type=NoSync settles it on its own. Otherwise, when the service could be asked what it follows, that answer decides — the local clock means unsynchronized, anything else means synchronized. When it could not be asked, time_sources = 0 (no time source in use) decides instead. With neither piece of evidence the check reports the configured intent and does not raise an alarm, so a host where the counters are unavailable does not alert forever.

Default thresholds: critical when synchronized = 0 or offset > 30000 and warning when offset > 1000. The critical is the important one — it fires when the machine follows no time source at all, whether because the service is not running, because Type is NoSync, or because it has fallen back to its own clock. Kerberos rejects tickets once the clock is five minutes out, so the 30-second critical leaves room to act.

On a workgroup machine Windows trigger-starts W32Time and stops it again between synchronizations, so running is 0 most of the time and the default critical fires by design. Check the configuration and the age of the last good synchronization there instead, e.g. check_w32time "critical=sync_type = 'NoSync'" "warning=last_sync_age > 604800". On a server or domain member the service is expected to run continuously and the defaults apply as they are. Windows only.

Jump to section:

Sample Commands

Check that the machine is following a time source (Windows)

The default is critical when the machine is not synchronizing at all and warning once the computed offset passes one second.

check_w32time
L        cli OK: synchronizing with dc01.corp.example.com (offset 3ms)|'w32time_offset'=3ms;1000;30000
check_w32time
L        cli CRITICAL: the Windows Time service is stopped (start type demand)
check_w32time
L        cli CRITICAL: not synchronizing: falling back to Local CMOS Clock
check_w32time
L        cli CRITICAL: not synchronizing: no time source in use (configured: time.windows.com)|'w32time_offset'=0ms;1000;30000

Show the service state, configuration and source

check_w32time warning=none critical=none "top-syntax=${status}: ${list}" "detail-syntax=svc=${service_state}/${start_type} type=${sync_type} src=${source} (${source_from}) peers=${peers}"
L        cli OK: svc=stopped/demand type=NTP src=time.windows.com (configuration) peers=time.windows.com

source_from says where the source came from: service when the running service was asked what it is actually following, configuration when it could not be asked and the configured peers are shown instead. The verdict is worded to match — “synchronizing with X” only when the service confirmed it, and “configured to synchronize with X” when that is all we know.

check_w32time warning=none critical=none "top-syntax=${list}" "detail-syntax=src=[${source}] from=${source_from} local=${local_clock} sync=${synchronized} srcs=${time_sources} off=${offset} delay=${delay}"
L        cli src=[time.windows.com] from=configuration local=0 sync=0 srcs=0 off=0 delay=31

Watch a domain member’s time hierarchy

local_clock is the signal that a domain member has lost its hierarchy and is free-running: it keeps answering, but its clock is no longer anchored to anything, which breaks Kerberos once it drifts past five minutes.

check_w32time "critical=local_clock = 1 or sync_type = 'NoSync' or running = 0"
L        cli OK: synchronizing with dc01.corp.example.com (offset 12ms)

Alert on drift only

check_w32time "warning=offset > 500" "critical=offset > 5000"
L        cli WARNING: synchronizing with time.windows.com (offset 812ms)|'w32time_offset'=812ms;500;5000

Report how long ago the clock was last validated

check_w32time "warning=last_sync_age > 86400" "critical=none" "top-syntax=${status}: ${list}" "detail-syntax=last sync ${last_sync} (${last_sync_age}s ago)"
L        cli OK: last sync 2026-08-15 21:28:41 (49654s ago)|'w32time_last_sync'=49654s;86400;0

Values the service has not measured read as unknown

The “Windows Time Service” counters only carry data while the service is running; until then offset, delay, frequency_adjustment and time_sources render as unknown, compare false against every number and emit no perfdata.

check_w32time "warning=none" "critical=none" "top-syntax=${list}" "detail-syntax=off=${offset} delay=${delay} freq=${frequency_adjustment} srcs=${time_sources}"
L        cli off=unknown delay=unknown freq=unknown srcs=unknown
check_w32time "critical=offset = 'unknown'"
L        cli CRITICAL: the Windows Time service is stopped (start type demand)

A workgroup client, where W32Time is trigger-started

Windows starts the time service on demand on a machine that is not domain joined, so it is stopped most of the time. Check the configuration and the age of the last good synchronization there instead of the service state.

check_w32time "critical=sync_type = 'NoSync'" "warning=last_sync_age > 604800"
L        cli OK: the Windows Time service is stopped (start type demand)|'w32time_last_sync'=50036s;604800;0

Command-line Arguments

Common options:

These options are shared by all filter based commands and are described on the common options page; the default values below are specific to this command.

Option Default Value
filter
warning offset > 1000
warn
critical synchronized = 0 or offset > 30000
crit
ok
debug false
show-all false
empty-state ignored
perf-config
escape-html false
list-separator ,
top-syntax ${status}: ${list}
ok-syntax
empty-syntax
detail-syntax ${state}
perf-syntax w32time
byte-unit
decimal-separator
decimals -1
thousands-separator

This command also accepts the standard help options: help, help-pb, show-default, help-short.

Filter keywords

Option Description
delay NTP round trip delay to the time source in milliseconds
frequency_adjustment Correction the service applies to the clock frequency, in parts per billion (negative slows the clock down)
installed True when the W32Time service exists on this host
last_sync Time of the last known good synchronization, in UTC, or ‘unknown’
last_sync_age Seconds since the last synchronization W32Time recorded as good; threshold with durations, e.g. last_sync_age > 24h
local_clock True when the source is the machine’s own clock (Local CMOS Clock / free-running)
offset Absolute clock offset against the time source in milliseconds, as last computed by the service; ‘unknown’ until it has measured one (offset = 'unknown' tests for it)
peer_count Number of configured NTP peers
peers Configured NTP peers, comma separated (empty on a domain member, which discovers its source)
running True when the W32Time service is running
service_state State of the W32Time service: running, stopped, starting, … or ‘not installed’
source The time source in use; the configured peers when the service could not be asked (see source_from)
source_from Where source came from: ‘service’ (live), ‘configuration’ or ‘unknown’
start_type Start type of the W32Time service: auto, delayed, demand, disabled, …
state One line verdict: not installed, not running, NoSync, falling back to the local clock or synchronizing with a source
sync_type Configured synchronization type: NT5DS (domain hierarchy), NTP, AllSync or NoSync
synchronized True when the machine is following a time source: the service runs, synchronization is not turned off, the source is not the local clock and - when the source could not be read - at least one time source is in use
time_sources Number of NTP time sources the client is currently using

This command also supports the common filter keywords: count, total, ok_count, warn_count, crit_count, problem_count, list, ok_list, warn_list, crit_list, problem_list, detail_list, sep, status.

Configuration

Path / Section Description
/settings/default Default values
/settings/system/unix Unix system
/settings/system/unix/real-time/cpu Realtime cpu filters
/settings/system/unix/real-time/memory Realtime memory filters
/settings/system/unix/real-time/process Realtime process filters
/settings/system/unix/service-tags Service tags
/settings/system/windows Windows system
/settings/system/windows/counters PDH Counters
/settings/system/windows/real-time/checks Legacy generic filters
/settings/system/windows/real-time/cpu Realtime cpu filters
/settings/system/windows/real-time/memory Realtime memory filters
/settings/system/windows/real-time/process Realtime process filters
/settings/system/windows/service-tags Service tags

Default values

Default values used in other config sections.

Key Default Value Description
allowed hosts 127.0.0.1 Allowed hosts
bind to BIND TO ADDRESS
cache allowed hosts true Cache list of allowed hosts
encoding NRPE PAYLOAD ENCODING
inbox inbox INBOX
password Password
socket queue size 0 LISTEN QUEUE
thread pool 10 THREAD POOL
timeout 30 TIMEOUT
timezone local Timezone
# Default values used in other config sections.
[/settings/default]
allowed hosts=127.0.0.1
cache allowed hosts=true
inbox=inbox
socket queue size=0
thread pool=10
timeout=30
timezone=local

Allowed hosts

A comma separated list of allowed hosts. You can use netmasks (/ syntax) or * to create ranges.

Key Description
Path: /settings/default
Key: allowed hosts
Default value: 127.0.0.1

Sample:

[/settings/default]
# Allowed hosts
allowed hosts=127.0.0.1

BIND TO ADDRESS

Allows you to bind server to a specific local address. This has to be a dotted ip address not a host name. Leaving this blank will bind to all available IP addresses.

Key Description
Path: /settings/default
Key: bind to
Default value: N/A

Sample:

[/settings/default]
# BIND TO ADDRESS
bind to=

Cache list of allowed hosts

If host names (DNS entries) should be cached, improves speed and security somewhat but won’t allow you to have dynamic IPs for your Nagios server.

Key Description
Path: /settings/default
Key: cache allowed hosts
Default value: true

Sample:

[/settings/default]
# Cache list of allowed hosts
cache allowed hosts=true

NRPE PAYLOAD ENCODING

Key Description
Path: /settings/default
Key: encoding
Advanced: Yes (means it is not commonly used)
Default value: N/A

Sample:

[/settings/default]
# NRPE PAYLOAD ENCODING
encoding=

INBOX

The default channel to post incoming messages on

Key Description
Path: /settings/default
Key: inbox
Default value: inbox

Sample:

[/settings/default]
# INBOX
inbox=inbox

Password

Password used to authenticate against server

Key Description
Path: /settings/default
Key: password
Default value: N/A

Sample:

[/settings/default]
# Password
password=

LISTEN QUEUE

Number of sockets to queue before starting to refuse new incoming connections. This can be used to tweak the amount of simultaneous sockets that the server accepts.

Key Description
Path: /settings/default
Key: socket queue size
Advanced: Yes (means it is not commonly used)
Default value: 0

Sample:

[/settings/default]
# LISTEN QUEUE
socket queue size=0

THREAD POOL

Key Description
Path: /settings/default
Key: thread pool
Advanced: Yes (means it is not commonly used)
Default value: 10

Sample:

[/settings/default]
# THREAD POOL
thread pool=10

TIMEOUT

Timeout (in seconds) when reading packets on incoming sockets. If the data has not arrived within this time we will bail out.

Key Description
Path: /settings/default
Key: timeout
Default value: 30

Sample:

[/settings/default]
# TIMEOUT
timeout=30

Timezone

Timezone used to render dates such as boot time. Accepts ‘local’ (default), ‘utc’, or any POSIX TZ string parseable by Boost.Date_time (e.g. ‘MST-07’ or ‘EST-05EDT,M3.2.0,M11.1.0’).

Key Description
Path: /settings/default
Key: timezone
Advanced: Yes (means it is not commonly used)
Default value: local

Sample:

[/settings/default]
# Timezone
timezone=local

Unix system

Available on Linux only.

Section for system checks and system settings

Key Default Value Description
default buffer length 1h Default buffer time
process history false Track process history
timezone local Timezone
# Section for system checks and system settings
[/settings/system/unix]
default buffer length=1h
process history=false
timezone=local

Default buffer time

Used to define the default size of range buffer checks (ie. CPU).

Key Description
Path: /settings/system/unix
Key: default buffer length
Default value: 1h

Sample:

[/settings/system/unix]
# Default buffer time
default buffer length=1h

Track process history

Enable tracking of process history for use with the check_process_history and check_process_history_new commands.

Key Description
Path: /settings/system/unix
Key: process history
Default value: false

Sample:

[/settings/system/unix]
# Track process history
process history=false

Timezone

Timezone used to render dates such as boot time. Accepts ‘local’ (default), ‘utc’, or any POSIX TZ string parseable by Boost.Date_time (e.g. ‘MST-07’ or ‘EST-05EDT,M3.2.0,M11.1.0’).

Key Description
Path: /settings/system/unix
Key: timezone
Advanced: Yes (means it is not commonly used)
Default value: local

Sample:

[/settings/system/unix]
# Timezone
timezone=local

Realtime cpu filters

Available on Linux only.

A set of filters to use in real-time mode

This is a section of objects. This means that you will create objects below this point by adding sections which all look the same.

Keys:

Key Default Value Description
byte unit BYTE UNIT
command COMMAND NAME
critical CRITICAL FILTER
debug DEBUG
decimal separator DECIMAL SEPARATOR
decimals -1 DECIMALS
destination DESTINATION
detail syntax SYNTAX
empty message eventlog found no records EMPTY MESSAGE
escape html ESCAPE HTML
filter FILTER
list separator LIST SEPARATOR
maximum age 5m MAXIMUM AGE
ok OK FILTER
ok syntax SYNTAX
perf config PERF CONFIG
run on startup RUN ON STARTUP
severity SEVERITY
silent period false Silent period
source id SOURCE ID
target DESTINATION
target id TARGET ID
thousands separator THOUSANDS SEPARATOR
time TIME
times TIMES
top syntax SYNTAX
warning WARNING FILTER

Sample:

# An example of a Realtime cpu filters section
[/settings/system/unix/real-time/cpu/sample]
#byte unit=...
#command=...
#critical=...
#debug=...
#decimal separator=...
decimals=-1
#destination=...
#detail syntax=...
empty message=eventlog found no records
#escape html=...
#filter=...
#list separator=...
maximum age=5m
#ok=...
#ok syntax=...
#perf config=...
#run on startup=...
#severity=...
silent period=false
#source id=...
#target=...
#target id=...
#thousands separator=...
#time=...
#times=...
#top syntax=...
#warning=...

Realtime memory filters

Available on Linux only.

A set of filters to use in real-time mode

This is a section of objects. This means that you will create objects below this point by adding sections which all look the same.

Keys:

Key Default Value Description
byte unit BYTE UNIT
command COMMAND NAME
critical CRITICAL FILTER
debug DEBUG
decimal separator DECIMAL SEPARATOR
decimals -1 DECIMALS
destination DESTINATION
detail syntax SYNTAX
empty message eventlog found no records EMPTY MESSAGE
escape html ESCAPE HTML
filter FILTER
list separator LIST SEPARATOR
maximum age 5m MAXIMUM AGE
ok OK FILTER
ok syntax SYNTAX
perf config PERF CONFIG
run on startup RUN ON STARTUP
severity SEVERITY
silent period false Silent period
source id SOURCE ID
target DESTINATION
target id TARGET ID
thousands separator THOUSANDS SEPARATOR
top syntax SYNTAX
type MEMORY TYPE
types MEMORY TYPES
warning WARNING FILTER

Sample:

# An example of a Realtime memory filters section
[/settings/system/unix/real-time/memory/sample]
#byte unit=...
#command=...
#critical=...
#debug=...
#decimal separator=...
decimals=-1
#destination=...
#detail syntax=...
empty message=eventlog found no records
#escape html=...
#filter=...
#list separator=...
maximum age=5m
#ok=...
#ok syntax=...
#perf config=...
#run on startup=...
#severity=...
silent period=false
#source id=...
#target=...
#target id=...
#thousands separator=...
#top syntax=...
#type=...
#types=...
#warning=...

Realtime process filters

Available on Linux only.

A set of filters to use in real-time mode

This is a section of objects. This means that you will create objects below this point by adding sections which all look the same.

Keys:

Key Default Value Description
byte unit BYTE UNIT
command COMMAND NAME
critical CRITICAL FILTER
debug DEBUG
decimal separator DECIMAL SEPARATOR
decimals -1 DECIMALS
destination DESTINATION
detail syntax SYNTAX
empty message eventlog found no records EMPTY MESSAGE
escape html ESCAPE HTML
filter FILTER
list separator LIST SEPARATOR
maximum age 5m MAXIMUM AGE
ok OK FILTER
ok syntax SYNTAX
perf config PERF CONFIG
process PROCESS
processes PROCESSES
run on startup RUN ON STARTUP
severity SEVERITY
silent period false Silent period
source id SOURCE ID
target DESTINATION
target id TARGET ID
thousands separator THOUSANDS SEPARATOR
top syntax SYNTAX
warning WARNING FILTER

Sample:

# An example of a Realtime process filters section
[/settings/system/unix/real-time/process/sample]
#byte unit=...
#command=...
#critical=...
#debug=...
#decimal separator=...
decimals=-1
#destination=...
#detail syntax=...
empty message=eventlog found no records
#escape html=...
#filter=...
#list separator=...
maximum age=5m
#ok=...
#ok syntax=...
#perf config=...
#process=...
#processes=...
#run on startup=...
#severity=...
silent period=false
#source id=...
#target=...
#target id=...
#thousands separator=...
#top syntax=...
#warning=...

Service tags

Available on Linux only.

Systemd units to surface as host tags: each key is a unit name and each value the tag to publish. When the unit exists and is active the tag is published as =enabled (removed otherwise). Example: postgresql=postgres

This is a section of objects. This means that you will create objects below this point by adding sections which all look the same.

Windows system

Available on Windows only.

Section for system checks and system settings

Key Default Value Description
default buffer length 1h Default buffer time
disable Disable automatic checks
fetch core loads true Fetch core load
process cpu false Sample per-process CPU
process history false Track process history
subsystem default PDH subsystem
timezone local Timezone
use pdh for cpu false Use PDH to fetch CPU load
# Section for system checks and system settings
[/settings/system/windows]
default buffer length=1h
fetch core loads=true
process cpu=false
process history=false
subsystem=default
timezone=local
use pdh for cpu=false

Default buffer time

Used to define the default size of range buffer checks (ie. CPU).

Key Description
Path: /settings/system/windows
Key: default buffer length
Default value: 1h

Sample:

[/settings/system/windows]
# Default buffer time
default buffer length=1h

Disable automatic checks

A comma separated list of checks to disable in the collector: battery,cpu,handles,load,network,temperature,cpu_frequency,os_updates,metrics,pdh. Please note disabling these will mean part of NSClient++ will no longer function as expected.

Key Description
Path: /settings/system/windows
Key: disable
Advanced: Yes (means it is not commonly used)
Default value: N/A

Sample:

[/settings/system/windows]
# Disable automatic checks
disable=

Fetch core load

Set to false to use a different API for fetching CPU load (will not provide core load, and will not show exact same values as task manager).

Key Description
Path: /settings/system/windows
Key: fetch core loads
Advanced: Yes (means it is not commonly used)
Default value: true

Sample:

[/settings/system/windows]
# Fetch core load
fetch core loads=true

Sample per-process CPU

Sample per-process CPU usage once a second in the background so that ‘check_process delta=true’ can report CPU% without stalling the check for a second. Off by default (adds one system-process-table query per second); required for the delta=true CPU fields.

Key Description
Path: /settings/system/windows
Key: process cpu
Default value: false

Sample:

[/settings/system/windows]
# Sample per-process CPU
process cpu=false

Track process history

Enable tracking of process history for use with check_process_history and check_process_history_new commands.

Key Description
Path: /settings/system/windows
Key: process history
Default value: false

Sample:

[/settings/system/windows]
# Track process history
process history=false

PDH subsystem

Set which pdh subsystem to use. Currently default and thread-safe are supported where thread-safe is slower but required if you have some problematic counters.

Key Description
Path: /settings/system/windows
Key: subsystem
Advanced: Yes (means it is not commonly used)
Default value: default

Sample:

[/settings/system/windows]
# PDH subsystem
subsystem=default

Timezone

Timezone used to render dates such as boot time. Accepts ‘local’ (default), ‘utc’, or any POSIX TZ string parseable by Boost.Date_time (e.g. ‘MST-07’ or ‘EST-05EDT,M3.2.0,M11.1.0’).

Key Description
Path: /settings/system/windows
Key: timezone
Advanced: Yes (means it is not commonly used)
Default value: local

Sample:

[/settings/system/windows]
# Timezone
timezone=local

Use PDH to fetch CPU load

When using PDH you might get better accuracy and hel alleviate invalid CPU values on multi core systems. The drawback is that PDH counters are sometimes missing and have invalid indexes so your milage may vary

Key Description
Path: /settings/system/windows
Key: use pdh for cpu
Advanced: Yes (means it is not commonly used)
Default value: false

Sample:

[/settings/system/windows]
# Use PDH to fetch CPU load
use pdh for cpu=false

PDH Counters

Available on Windows only.

Add counters to check

This is a section of objects. This means that you will create objects below this point by adding sections which all look the same.

Keys:

Key Default Value Description
alias ALIAS
buffer size BUFFER SIZE
collection strategy COLLECTION STRATEGY
counter COUNTER
flags FLAGS
instances Interpret instances
is template false IS TEMPLATE
parent default PARENT
resolution COUNTER RESOLUTION
type COUNTER TYPE

Sample:

# An example of a PDH Counters section
[/settings/system/windows/counters/sample]
#alias=...
#buffer size=...
#collection strategy=...
#counter=...
#flags=...
#instances=...
is template=false
parent=default
#resolution=...
#type=...

Known instances:

  • disk_queue_length
  • memory_pages_sec

Legacy generic filters

Available on Windows only.

A set of filters to use in real-time mode

This is a section of objects. This means that you will create objects below this point by adding sections which all look the same.

Keys:

Key Default Value Description
byte unit BYTE UNIT
check cpu TYPE OF CHECK
command COMMAND NAME
critical CRITICAL FILTER
debug DEBUG
decimal separator DECIMAL SEPARATOR
decimals -1 DECIMALS
destination DESTINATION
detail syntax SYNTAX
empty message eventlog found no records EMPTY MESSAGE
escape html ESCAPE HTML
filter FILTER
list separator LIST SEPARATOR
maximum age 5m MAXIMUM AGE
ok OK FILTER
ok syntax SYNTAX
perf config PERF CONFIG
run on startup RUN ON STARTUP
severity SEVERITY
silent period false Silent period
source id SOURCE ID
target DESTINATION
target id TARGET ID
thousands separator THOUSANDS SEPARATOR
time TIME
times FILES
top syntax SYNTAX
warning WARNING FILTER

Sample:

# An example of a Legacy generic filters section
[/settings/system/windows/real-time/checks/sample]
#byte unit=...
check=cpu
#command=...
#critical=...
#debug=...
#decimal separator=...
decimals=-1
#destination=...
#detail syntax=...
empty message=eventlog found no records
#escape html=...
#filter=...
#list separator=...
maximum age=5m
#ok=...
#ok syntax=...
#perf config=...
#run on startup=...
#severity=...
silent period=false
#source id=...
#target=...
#target id=...
#thousands separator=...
#time=...
#times=...
#top syntax=...
#warning=...

Realtime cpu filters

Available on Windows only.

A set of filters to use in real-time mode

This is a section of objects. This means that you will create objects below this point by adding sections which all look the same.

Keys:

Key Default Value Description
byte unit BYTE UNIT
command COMMAND NAME
critical CRITICAL FILTER
debug DEBUG
decimal separator DECIMAL SEPARATOR
decimals -1 DECIMALS
destination DESTINATION
detail syntax SYNTAX
empty message eventlog found no records EMPTY MESSAGE
escape html ESCAPE HTML
filter FILTER
list separator LIST SEPARATOR
maximum age 5m MAXIMUM AGE
ok OK FILTER
ok syntax SYNTAX
perf config PERF CONFIG
run on startup RUN ON STARTUP
severity SEVERITY
silent period false Silent period
source id SOURCE ID
target DESTINATION
target id TARGET ID
thousands separator THOUSANDS SEPARATOR
time TIME
top syntax SYNTAX
warning WARNING FILTER

Sample:

# An example of a Realtime cpu filters section
[/settings/system/windows/real-time/cpu/sample]
#byte unit=...
#command=...
#critical=...
#debug=...
#decimal separator=...
decimals=-1
#destination=...
#detail syntax=...
empty message=eventlog found no records
#escape html=...
#filter=...
#list separator=...
maximum age=5m
#ok=...
#ok syntax=...
#perf config=...
#run on startup=...
#severity=...
silent period=false
#source id=...
#target=...
#target id=...
#thousands separator=...
#time=...
#top syntax=...
#warning=...

Realtime memory filters

Available on Windows only.

A set of filters to use in real-time mode

This is a section of objects. This means that you will create objects below this point by adding sections which all look the same.

Keys:

Key Default Value Description
byte unit BYTE UNIT
command COMMAND NAME
critical CRITICAL FILTER
debug DEBUG
decimal separator DECIMAL SEPARATOR
decimals -1 DECIMALS
destination DESTINATION
detail syntax SYNTAX
empty message eventlog found no records EMPTY MESSAGE
escape html ESCAPE HTML
filter FILTER
list separator LIST SEPARATOR
maximum age 5m MAXIMUM AGE
ok OK FILTER
ok syntax SYNTAX
perf config PERF CONFIG
run on startup RUN ON STARTUP
severity SEVERITY
silent period false Silent period
source id SOURCE ID
target DESTINATION
target id TARGET ID
thousands separator THOUSANDS SEPARATOR
top syntax SYNTAX
type MEMORY TYPE
warning WARNING FILTER

Sample:

# An example of a Realtime memory filters section
[/settings/system/windows/real-time/memory/sample]
#byte unit=...
#command=...
#critical=...
#debug=...
#decimal separator=...
decimals=-1
#destination=...
#detail syntax=...
empty message=eventlog found no records
#escape html=...
#filter=...
#list separator=...
maximum age=5m
#ok=...
#ok syntax=...
#perf config=...
#run on startup=...
#severity=...
silent period=false
#source id=...
#target=...
#target id=...
#thousands separator=...
#top syntax=...
#type=...
#warning=...

Realtime process filters

Available on Windows only.

A set of filters to use in real-time mode

This is a section of objects. This means that you will create objects below this point by adding sections which all look the same.

Keys:

Key Default Value Description
byte unit BYTE UNIT
command COMMAND NAME
critical CRITICAL FILTER
debug DEBUG
decimal separator DECIMAL SEPARATOR
decimals -1 DECIMALS
destination DESTINATION
detail syntax SYNTAX
empty message eventlog found no records EMPTY MESSAGE
escape html ESCAPE HTML
filter FILTER
list separator LIST SEPARATOR
maximum age 5m MAXIMUM AGE
ok OK FILTER
ok syntax SYNTAX
perf config PERF CONFIG
process PROCESS
run on startup RUN ON STARTUP
severity SEVERITY
silent period false Silent period
source id SOURCE ID
target DESTINATION
target id TARGET ID
thousands separator THOUSANDS SEPARATOR
top syntax SYNTAX
warning WARNING FILTER

Sample:

# An example of a Realtime process filters section
[/settings/system/windows/real-time/process/sample]
#byte unit=...
#command=...
#critical=...
#debug=...
#decimal separator=...
decimals=-1
#destination=...
#detail syntax=...
empty message=eventlog found no records
#escape html=...
#filter=...
#list separator=...
maximum age=5m
#ok=...
#ok syntax=...
#perf config=...
#process=...
#run on startup=...
#severity=...
silent period=false
#source id=...
#target=...
#target id=...
#thousands separator=...
#top syntax=...
#warning=...

Service tags

Available on Windows only.

Windows services to surface as host tags: each key is a service name and each value the tag to publish. When the service exists and is running the tag is published as =enabled (removed otherwise). Example: MSSQLSERVER=sql-server

This is a section of objects. This means that you will create objects below this point by adding sections which all look the same.