Skip to content

Commit 462e6a0

Browse files
committed
feat(sensors-temperatures): add --ignore parameter to filter sensors by regex (#965)
1 parent 0373a4d commit 462e6a0

5 files changed

Lines changed: 87 additions & 19 deletions

File tree

.pylintrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ disable=
33
# Plugin file names use dashes (e.g. "cpu-usage", "ipmi-sel") which is correct
44
# for CLI tools but violates Python's snake_case module naming convention.
55
C0103,
6+
# Some plugins need warnings.filterwarnings() before imports (e.g. psutil
7+
# deprecation warnings). This is intentional and cannot be avoided.
8+
C0413,
69
# Every plugin uses "except Exception: lib.base.cu()" as a top-level safety net.
710
# This is intentional and consistent across all plugins.
811
W0718,

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Monitoring Plugins:
4040
* infomaniak-swiss-backup-devices: add `--ignore-customer`, `--ignore-name`, `--ignore-tag`, `--ignore-user` parameters to skip devices by regex
4141
* infomaniak-swiss-backup-products: add `--ignore-customer`, `--ignore-tag` parameters to skip products by regex
4242
* ipmi-sel: add `--ignore` parameter to filter out SEL entries by regex, e.g. auto-generated "Log area reset/cleared" entries after `ipmitool sel clear` ([#982](https://github.com/Linuxfabrik/monitoring-plugins/issues/982))
43+
* sensors-temperatures: add `--ignore` parameter to filter out sensors by regex ([#965](https://github.com/Linuxfabrik/monitoring-plugins/issues/965))
4344
* librenms-alerts: add device-type `management`
4445
* librenms-health: add device-type `management`
4546
* nextcloud-enterprise: provides information about an installed Nextcloud Enterprise subscription

check-plugins/sensors-temperatures/README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,20 @@ Hints:
2323
## Help
2424

2525
```text
26-
usage: sensors-temperatures [-h] [-V] [--always-ok]
26+
usage: sensors-temperatures [-h] [-V] [--always-ok] [--ignore IGNORE]
2727
2828
Return certain hardware temperature sensors (it may be a CPU, an hard disk or
2929
something else, depending on the OS and its configuration). All temperatures
3030
are expressed in celsius. Check is done automatically against hardware
3131
thresholds. If sensors are not supported by the OS OK is returned.
3232
3333
options:
34-
-h, --help show this help message and exit
35-
-V, --version show program's version number and exit
36-
--always-ok Always returns OK.
34+
-h, --help show this help message and exit
35+
-V, --version show program's version number and exit
36+
--always-ok Always returns OK.
37+
--ignore IGNORE Ignore sensors matching this Python regular expression on
38+
the sensor name or label (repeating). Example:
39+
`--ignore="iwlwifi_1"` or `--ignore="^acpitz"`
3740
```
3841

3942

check-plugins/sensors-temperatures/icingaweb2-module-director/sensors-temperatures.json

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
"arguments": {
55
"--always-ok": {
66
"set_if": "$sensors_temperatures_always_ok$"
7+
},
8+
"--ignore": {
9+
"value": "$sensors_temperatures_ignore$",
10+
"repeat_key": true
711
}
812
},
913
"command": "/usr/lib64/nagios/plugins/sensors-temperatures",
@@ -13,6 +17,11 @@
1317
"datafield_id": 1,
1418
"is_required": "n",
1519
"var_filter": null
20+
},
21+
{
22+
"datafield_id": 2,
23+
"is_required": "n",
24+
"var_filter": null
1625
}
1726
],
1827
"imports": [],
@@ -67,7 +76,8 @@
6776
"use_var_overrides": null,
6877
"vars": {
6978
"criticality": "A",
70-
"sensors_temperatures_always_ok": false
79+
"sensors_temperatures_always_ok": false,
80+
"sensors_temperatures_ignore": []
7181
},
7282
"volatile": null,
7383
"zone": null,
@@ -83,6 +93,17 @@
8393
"format": null,
8494
"settings": {},
8595
"uuid": "7170c8a1-70a8-4052-b98f-253d25ca28b5"
96+
},
97+
"2": {
98+
"varname": "sensors_temperatures_ignore",
99+
"caption": "Sensors Temperatures: Ignore",
100+
"description": "Ignore sensors matching this Python regular expression on the sensor name or label (repeating). Example: `--ignore=\"iwlwifi_1\"` or `--ignore=\"^acpitz\"`",
101+
"datatype": "Icinga\\Module\\Director\\DataType\\DataTypeArray",
102+
"format": null,
103+
"settings": {
104+
"visibility": "visible"
105+
},
106+
"uuid": "3148036c-198e-47c1-bec8-cc4800683402"
86107
}
87108
}
88109
}

check-plugins/sensors-temperatures/sensors-temperatures

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,22 @@
1414
import warnings
1515

1616
warnings.filterwarnings("ignore")
17-
import argparse # pylint: disable=C0413
18-
import sys # pylint: disable=C0413
17+
import argparse
18+
import re
19+
import sys
1920

20-
import lib.base # pylint: disable=C0413
21-
from lib.globals import (STATE_CRIT, STATE_OK, # pylint: disable=C0413
22-
STATE_UNKNOWN, STATE_WARN)
21+
import lib.base
22+
from lib.globals import (STATE_OK, STATE_UNKNOWN)
2323

2424
try:
25-
import psutil # pylint: disable=C0413
25+
import psutil
2626
except ImportError:
2727
print('Python module "psutil" is not installed.')
2828
sys.exit(STATE_UNKNOWN)
2929

3030

3131
__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
32-
__version__ = '2025100601'
32+
__version__ = '2026040801'
3333

3434
DESCRIPTION = """Return certain hardware temperature sensors (it may be a CPU, an hard disk or
3535
something else, depending on the OS and its configuration). All temperatures are
@@ -45,7 +45,7 @@ def parse_args():
4545
parser.add_argument(
4646
'-V', '--version',
4747
action='version',
48-
version='%(prog)s: v{} by {}'.format(__version__, __author__)
48+
version=f'%(prog)s: v{__version__} by {__author__}'
4949
)
5050

5151
parser.add_argument(
@@ -56,6 +56,16 @@ def parse_args():
5656
default=False,
5757
)
5858

59+
parser.add_argument(
60+
'--ignore',
61+
help='Ignore sensors matching this Python regular expression on the sensor '
62+
'name or label (repeating). '
63+
'Example: `--ignore="iwlwifi_1"` or `--ignore="^acpitz"`',
64+
dest='IGNORE',
65+
action='append',
66+
default=None,
67+
)
68+
5969
args, _ = parser.parse_known_args()
6070
return args
6171

@@ -70,35 +80,65 @@ def main():
7080
except SystemExit:
7181
sys.exit(STATE_UNKNOWN)
7282

83+
if args.IGNORE is None:
84+
args.IGNORE = []
85+
86+
# compile ignore patterns
87+
try:
88+
ignore_patterns = [re.compile(p) for p in args.IGNORE]
89+
except re.error as e:
90+
lib.base.cu(f'Invalid regular expression: {e}')
91+
7392
if not hasattr(psutil, 'sensors_temperatures'):
7493
lib.base.cu('Platform not supported.')
7594

7695
# fetch data
7796
temps = psutil.sensors_temperatures()
7897
if not temps:
79-
lib.base.oao('Can\'t read any temperature.', STATE_OK, always_ok=args.ALWAYS_OK)
98+
lib.base.oao("Can't read any temperature.", STATE_OK, always_ok=args.ALWAYS_OK)
8099

81100
msg = ''
82101
state = STATE_OK
83102
perfdata = ''
84103

85104
for name, entries in temps.items():
86-
msg += '* {}: '.format(name)
105+
filtered_entries = []
87106
for entry in entries:
88-
perfdata += lib.base.get_perfdata('{}_{}'.format(name, entry.label).replace(' ', '_').lower(), entry.current, None, entry.high, entry.critical, 0, None)
107+
sensor_id = f'{name}_{entry.label}' if entry.label else name
108+
if any(pattern.search(sensor_id) for pattern in ignore_patterns):
109+
continue
110+
filtered_entries.append(entry)
111+
112+
if not filtered_entries:
113+
continue
114+
115+
msg += f'* {name}: '
116+
for entry in filtered_entries:
117+
perfdata_label = f'{name}_{entry.label}'.replace(' ', '_').lower() \
118+
if entry.label else name.replace(' ', '_').lower()
119+
perfdata += lib.base.get_perfdata(
120+
perfdata_label,
121+
entry.current,
122+
warn=entry.high,
123+
crit=entry.critical,
124+
_min=0,
125+
)
89126
sensor_state = lib.base.get_state(entry.current, entry.high, entry.critical, 'ge')
90-
msg += '{} = {}°C '.format(entry.label or name, entry.current)
127+
msg += f'{entry.label or name} = {entry.current}°C '
91128
msg += lib.base.state2str(sensor_state)
92129
msg = msg.strip() + ', '
93130
state = lib.base.get_worst(state, sensor_state)
94131
msg = msg[:-2] + '\n'
95132

133+
if not msg:
134+
lib.base.oao('Everything is ok (all sensors ignored).', STATE_OK, always_ok=args.ALWAYS_OK)
135+
96136
# over and out
97-
lib.base.oao(msg[:-2], state, perfdata, always_ok=args.ALWAYS_OK)
137+
lib.base.oao(msg[:-1], state, perfdata, always_ok=args.ALWAYS_OK)
98138

99139

100140
if __name__ == '__main__':
101141
try:
102142
main()
103-
except Exception: # pylint: disable=W0703
143+
except Exception:
104144
lib.base.cu()

0 commit comments

Comments
 (0)