Skip to content

Commit 6b11151

Browse files
committed
fix(plugins): wrong identifier / swapped fields (#1070)
Eight plugins referenced the wrong variable or dict key in a message or perfdata call. The message text was often correct in each case, but the emitted numeric value or state label did not match. - hin-status: `cnt_incidents = 1` was hardcoded whenever the parser found any incident, instead of `len(incidents)`. The perfdata counter now tracks the real count. - mysql-table-locks: the "X immediate / Y locks" denominator used `Table_locks_immediate` twice. Use the actual total (`Table_locks_immediate + Table_locks_waited`) as Y. - ntp-w32tm: when "Time since Last Good Sync Time" ticks into CRIT, the appended state label hardcoded STATE_WARN. Use the actual `local_state` instead. - openstack-swift-stat: the "bytes used" block gated on the quota header `x-account-meta-quota-bytes` when it should have gated on `x-account-bytes-used`. The "used" line now shows up for any account with non-zero bytes, regardless of whether a quota is set. - php-status: the "missing config" builder appended `'{key} = {value}, '` as a plain string, so the output contained literal `{key}` / `{value}` placeholders. Make it an f-string. - qts-temperatures: the `systemp` and `cputemp` perfdata entries had their `warn` / `crit` thresholds swapped - the sys perfdata used `CPUTempWarnT`/`CPUTempErrT` and the cpu perfdata used `SysTempWarnT`/`SysTempErrT`. The message text was already correct. - redis-status, valkey-status: the `key_count` perfdata value used the loop variable `keys` (the last database's per-DB key count) instead of the accumulated `key_count` total. The "with X keys" message text was already using `key_count` correctly. php-fpm-ping was also flagged but turned out to be intentional: the plugin has no response-time metric (it only compares strings), so emitting the state integer as the perfdata value is a conscious design choice rather than a bug.
1 parent b40de0e commit 6b11151

9 files changed

Lines changed: 27 additions & 19 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
* axenita-stats: fix the version-number extraction slice `[8 : 8 + find('-') - 1]` that only worked for exactly 6-character versions like `14.0.8` and silently truncated any longer patch number. Use `split('-')[1]` instead, which handles `14.0.12`, `1.2.3`, and 2-digit majors correctly ([#1070](https://github.com/Linuxfabrik/monitoring-plugins/issues/1070))
1515
* deb-updates: add missing `lib.txt` import so the "N update(s) available" summary no longer crashes with `AttributeError` at runtime
1616
* Fix `--require-hashes` pip install in pre-commit autoupdate workflow by using pinned version instead
17+
* hin-status: when incidents are found, set `cnt_incidents = len(incidents)` instead of the hardcoded `1`, so the perfdata counter matches the actual number of incidents listed in the message ([#1070](https://github.com/Linuxfabrik/monitoring-plugins/issues/1070))
1718
* keycloak-version: replace the fragile regex `r'n (.*)'` (which relied on the "n " in the word "Version" of `/opt/keycloak/version.txt`) with an explicit `r'[Vv]ersion\s+(\d+(?:\.\d+)*)'` pattern. Also fall through to the API fallback when the file is present but the regex does not match, instead of aborting with "Keycloak not found" ([#1070](https://github.com/Linuxfabrik/monitoring-plugins/issues/1070))
1819
* mysql-memory: fix `get_other_process_memory()` fallback path for psutil older than 5.3.0 (referenced an undefined `cmdline` variable and the wrong attribute on the process dict) and drop an unreachable `break` after `return` in `get_pfs_memory()`
1920
* mysql-storage-engines: drop a dead `SELECT ... FROM information_schema.engines` query whose result was never used
21+
* mysql-table-locks: the "X immediate / Y locks" message denominator used `Table_locks_immediate` twice instead of `Table_locks_immediate + Table_locks_waited` as the total, so the output lied about the total lock count. The ratio displayed as a percentage was already correct ([#1070](https://github.com/Linuxfabrik/monitoring-plugins/issues/1070))
2022
* network-connections: the final `lib.base.oao()` call passed a hardcoded `STATE_OK` instead of the accumulated `state`, discarding all WARN/CRIT decisions from the loop. The plugin now exits with the correct accumulated state ([#1070](https://github.com/Linuxfabrik/monitoring-plugins/issues/1070))
2123
* ntp-ntpd: collapse four sequential `if`-then-`oao()` early-exit guards into a single `if/elif` chain so the intent (try each failure mode in turn and exit on the first one that matches) is explicit ([#1070](https://github.com/Linuxfabrik/monitoring-plugins/issues/1070))
24+
* ntp-w32tm: when the "Time since Last Good Sync Time" check yields a non-OK state, the appended state label is now the actual `local_state` (WARN or CRIT) instead of a hardcoded `STATE_WARN`, so a CRIT state no longer shows up as "WARNING" in the message ([#1070](https://github.com/Linuxfabrik/monitoring-plugins/issues/1070))
25+
* openstack-swift-stat: the "bytes used" block gated on `'x-account-meta-quota-bytes' in headers` (a quota header) when it should have gated on `'x-account-bytes-used' in headers`. The "used" line now shows up for any account with non-zero bytes, regardless of whether a quota is set ([#1070](https://github.com/Linuxfabrik/monitoring-plugins/issues/1070))
2226
* openvpn-version: replace the fragile regex `r'N (\d+\.\d+\.\d+)'` (which relied on the "N" at the end of "OpenVPN") with an explicit `r'OpenVPN\s+(\d+\.\d+\.\d+)'` pattern anchored on the command name ([#1070](https://github.com/Linuxfabrik/monitoring-plugins/issues/1070))
27+
* php-status: the "missing config" builder appended `'{key} = {value}, '` as a plain string instead of an f-string, so the output contained literal `{key}` / `{value}` placeholders. Mark it as an f-string so the real key/value is rendered ([#1070](https://github.com/Linuxfabrik/monitoring-plugins/issues/1070))
2328
* ping: drop dead initialization of `rtt_min / rtt_avg / rtt_max / rtt_mdev` that was never read
29+
* qts-temperatures: the `systemp` and `cputemp` perfdata entries had their `warn` / `crit` thresholds swapped (system perfdata used the CPU threshold fields and vice versa). The message text was already correct ([#1070](https://github.com/Linuxfabrik/monitoring-plugins/issues/1070))
30+
* redis-status, valkey-status: the `key_count` perfdata value used the loop variable `keys` (the last database's per-DB key count) instead of the accumulated `key_count` (total across all databases). The "with X keys" message text was already using `key_count` ([#1070](https://github.com/Linuxfabrik/monitoring-plugins/issues/1070))
2431
* rocketchat-stats: add missing `lib.txt` import so the user-count pluralization no longer crashes with `AttributeError` at runtime
2532
* starface-java-memory-usage: the heap and non-heap state checks used `state += lib.base.get_worst(used_state, state)` which adds state integers together and corrupts the accumulated state (e.g. WARN+WARN=2 reads as CRIT, WARN+CRIT=3 is outside the valid range). Replaced with `state = lib.base.get_worst(state, used_state)` so the accumulated state remains a valid STATE_OK / STATE_WARN / STATE_CRIT value ([#1070](https://github.com/Linuxfabrik/monitoring-plugins/issues/1070))
2633
* tools/run-unit-tests: skip the `example` plugin in default runs. Its unit test is a template meant to be copy-pasted into new plugins and does not correspond to a real check. Explicit `python tools/run-unit-tests example` still runs it

check-plugins/hin-status/hin-status

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ except ImportError:
2727

2828

2929
__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
30-
__version__ = '2025100601'
30+
__version__ = '2026041201'
3131

3232
DESCRIPTION = """Monitors the HIN (Health Info Net) status page for service disruptions. Parses the
3333
support website for outage announcements since no machine-readable API is available.
@@ -146,7 +146,7 @@ def main():
146146
'div', class_='hin-status-block-content'
147147
).find_all('li'):
148148
incidents.append(incident.get_text(strip=True))
149-
cnt_incidents = 1
149+
cnt_incidents = len(incidents)
150150
state = STATE_WARN
151151
msg += f'Incidents: {", ".join(incidents)}. See {args.URL} for details.'
152152
except AttributeError:

check-plugins/mysql-table-locks/mysql-table-locks

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import lib.human
2020
from lib.globals import STATE_OK, STATE_UNKNOWN, STATE_WARN
2121

2222
__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
23-
__version__ = '2026040801'
23+
__version__ = '2026041201'
2424

2525
DESCRIPTION = """Checks the rate of table locks that had to wait in MySQL/MariaDB. A high wait rate
2626
indicates contention between concurrent queries.
@@ -137,12 +137,13 @@ def main():
137137
mycalc['pct_table_locks_immediate'] = 0
138138

139139
# Table locks
140+
total_locks = int(mystat['Table_locks_immediate']) + int(mystat['Table_locks_waited'])
140141
msg = (
141142
f'{mycalc["pct_table_locks_immediate"]}% table locks'
142143
f' acquired immediately'
143144
f' ({lib.human.number2human(mystat["Table_locks_immediate"])}'
144145
f' immediate /'
145-
f' {lib.human.number2human(mystat["Table_locks_immediate"])}'
146+
f' {lib.human.number2human(total_locks)}'
146147
f' locks)'
147148
)
148149
if mycalc['pct_table_locks_immediate'] < 95:

check-plugins/ntp-w32tm/ntp-w32tm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import lib.txt
2222
from lib.globals import STATE_OK, STATE_UNKNOWN, STATE_WARN
2323

2424
__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
25-
__version__ = '2025120201'
25+
__version__ = '2026041201'
2626

2727
DESCRIPTION = """Checks the Windows Time Service (w32tm) status, including clock offset, stratum,
2828
and time source. Useful for diagnosing time synchronization issues on Windows
@@ -170,7 +170,7 @@ def main():
170170
time_since_last_good_sync_time, args.WARN, args.CRIT
171171
)
172172
if local_state != STATE_OK:
173-
msg.append(f'{line} {lib.base.state2str(STATE_WARN)}')
173+
msg.append(f'{line} {lib.base.state2str(local_state)}')
174174
state = lib.base.get_worst(local_state, state)
175175

176176
# build the message

check-plugins/openstack-swift-stat/openstack-swift-stat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ except ImportError:
3131

3232

3333
__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
34-
__version__ = '2026040801'
34+
__version__ = '2026041201'
3535

3636
DESCRIPTION = """Checks OpenStack Swift object storage account statistics, including total container
3737
count, object count, and bytes used. Alerts when storage usage exceeds the configured
@@ -253,7 +253,7 @@ def main():
253253
f'{lib.human.number2human(obj_cnt)}'
254254
f' {lib.txt.pluralize("object", int(obj_cnt))}, '
255255
)
256-
if 'x-account-meta-quota-bytes' in stat_account['headers'] and int(
256+
if 'x-account-bytes-used' in stat_account['headers'] and int(
257257
stat_account['headers']['x-account-bytes-used']
258258
):
259259
bytes_used = int(stat_account['headers']['x-account-bytes-used'])

check-plugins/php-status/php-status

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ from lib.globals import STATE_OK, STATE_UNKNOWN, STATE_WARN
2222

2323

2424
__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
25-
__version__ = '2026033101'
25+
__version__ = '2026041201'
2626

2727
DESCRIPTION = """Checks PHP configuration and health, including startup errors, missing modules, and
2828
misconfigured php.ini directives. Optionally reads extended PHP information from a
@@ -193,7 +193,7 @@ def get_config_errors(args):
193193
except Exception:
194194
continue
195195
if f'{key.lower()} => {value.lower()}' not in php_config:
196-
result += '{key} = {value}, '
196+
result += f'{key} = {value}, '
197197
if result:
198198
result = result[:-2] + ' (did you run the check with sudo?), '
199199
return result

check-plugins/qts-temperatures/qts-temperatures

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ except ImportError:
2828

2929

3030
__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
31-
__version__ = '2026040801'
31+
__version__ = '2026041201'
3232

3333
DESCRIPTION = """Checks system and disk temperatures on QNAP appliances running QTS via the API.
3434
Alerts when temperatures exceed the configured thresholds."""
@@ -162,15 +162,15 @@ def main():
162162
perfdata = lib.base.get_perfdata(
163163
'systemp',
164164
int(data['func']['ownContent']['root']['sys_tempc']),
165-
warn=int(data['func']['ownContent']['root']['CPUTempWarnT']),
166-
crit=int(data['func']['ownContent']['root']['CPUTempErrT']),
165+
warn=int(data['func']['ownContent']['root']['SysTempWarnT']),
166+
crit=int(data['func']['ownContent']['root']['SysTempErrT']),
167167
_min=0,
168168
)
169169
perfdata += lib.base.get_perfdata(
170170
'cputemp',
171171
int(data['func']['ownContent']['root']['cpu_tempc']),
172-
warn=int(data['func']['ownContent']['root']['SysTempWarnT']),
173-
crit=int(data['func']['ownContent']['root']['SysTempErrT']),
172+
warn=int(data['func']['ownContent']['root']['CPUTempWarnT']),
173+
crit=int(data['func']['ownContent']['root']['CPUTempErrT']),
174174
_min=0,
175175
)
176176

check-plugins/redis-status/redis-status

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ from lib.globals import STATE_OK, STATE_UNKNOWN, STATE_WARN
2525
__author__ = """
2626
Linuxfabrik GmbH, Zurich/Switzerland;
2727
"""
28-
__version__ = '2025103001'
28+
__version__ = '2026041201'
2929

3030
DESCRIPTION = """Monitors a Redis server via the INFO command. Reports memory usage, fragmentation ratio,
3131
keyspace hit rate, connected clients, replication status, and persistence state. Alerts
@@ -379,7 +379,7 @@ def main():
379379
)
380380
perfdata += lib.base.get_perfdata(
381381
'key_count',
382-
keys,
382+
key_count,
383383
uom=None,
384384
warn=None,
385385
crit=None,

check-plugins/valkey-status/valkey-status

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ __author__ = """
2525
Linuxfabrik GmbH, Zurich/Switzerland;
2626
enhanced by Claudio Kuenzler
2727
"""
28-
__version__ = '2025103001'
28+
__version__ = '2026041201'
2929

3030
DESCRIPTION = """Monitors a Valkey server via the INFO command. Reports memory usage, fragmentation
3131
ratio, keyspace hit rate, connected clients, replication status, and persistence state.
@@ -374,7 +374,7 @@ def main():
374374
)
375375
perfdata += lib.base.get_perfdata(
376376
'key_count',
377-
keys,
377+
key_count,
378378
uom=None,
379379
warn=None,
380380
crit=None,

0 commit comments

Comments
 (0)