Skip to content

Commit dfaaf89

Browse files
committed
17776 systemd_units: Add option to include disabled failed units in critical failed count for systemd summary
The summary check for systemd units now respects the parameter `Treat failed units that are disabled as critical`. If set, failed disabled units are included in the critical count for failed services. Previously, disabled units were always excluded from the failed counts. SUP-24357 Change-Id: I20563aa4a230f784e748240d9df73e7558aa49e8
1 parent 835c273 commit dfaaf89

5 files changed

Lines changed: 97 additions & 13 deletions

File tree

.werks/17776.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[//]: # (werk v2)
2+
# systemd_units: Add option to include disabled failed units in critical failed count for systemd summary
3+
4+
key | value
5+
---------- | ---
6+
date | 2025-07-20T19:20:17+00:00
7+
version | 2.4.0p9
8+
class | feature
9+
edition | cre
10+
component | checks
11+
level | 1
12+
compatible | yes
13+
14+
The summary check for systemd units now respects the parameter `Treat failed units that are disabled as critical`.
15+
If set, failed disabled units are included in the critical count for failed services. Previously, disabled units were always excluded from the failed counts.

cmk/gui/plugins/wato/check_parameters/systemd_services_summary.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,15 @@
1212
RulespecGroupCheckParametersApplications,
1313
)
1414
from cmk.gui.plugins.wato.utils.simple_levels import SimpleLevels
15-
from cmk.gui.valuespec import Age, Dictionary, ListOf, Migrate, MonitoringState, RegExp
15+
from cmk.gui.valuespec import (
16+
Age,
17+
Checkbox,
18+
Dictionary,
19+
ListOf,
20+
Migrate,
21+
MonitoringState,
22+
RegExp,
23+
)
1624

1725
REQUIRED_STATE_KEYS_AND_STATES = {"active": 0, "inactive": 0, "failed": 2}
1826

@@ -31,6 +39,18 @@ def _parameter_valuespec_systemd_units_summary() -> Migrate:
3139
return Migrate(
3240
valuespec=Dictionary(
3341
elements=[
42+
(
43+
"disabled_critical",
44+
Checkbox(
45+
default_value=True,
46+
label="Failed units that are disabled will be considered critical",
47+
title=_("Treat failed units that are disabled as critical"),
48+
help=_(
49+
"Failed service that are disabled are also considered for the status of the service. "
50+
"Activating this option will cause the service to be CRIT if a failed service is disabled."
51+
),
52+
),
53+
),
3454
(
3555
"states",
3656
Dictionary(

cmk/plugins/collection/agent_based/systemd_units.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,8 @@ def check_systemd_units_summary(
768768
sum_failed = sum(
769769
s.active_status == "failed"
770770
for s in units
771-
if s not in services_organised["excluded"] and s not in services_organised["disabled"]
771+
if s not in services_organised["excluded"]
772+
and (params["disabled_critical"] is True or s not in services_organised["disabled"])
772773
)
773774

774775
yield Result(
@@ -797,6 +798,7 @@ def check_systemd_units_summary(
797798

798799

799800
CHECK_DEFAULT_PARAMETERS_SUMMARY = {
801+
"disabled_critical": False,
800802
"states": {
801803
"active": 0,
802804
"inactive": 0,

cmk/plugins/collection/checkman/systemd_units_services_summary

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@ agents: linux
33
catalog: os/ps
44
license: GPLv2
55
distribution: check_mk
6-
description:
7-
This check gives a summary of the linux services provided by
8-
the command 'systemctl --all'.
9-
The check reports the number of all services and for each service
10-
type, i.e. 'active', 'inactive', 'failed' and other ones.
11-
The state mapping is configurable, by default active and inactive
12-
states are OK, failed and all others are CRIT.
6+
description: This check gives a summary of the linux services provided by
7+
the command 'systemctl --all'.
8+
The check reports the number of all services and for each service
9+
type, i.e. 'active', 'inactive', 'failed' and other ones.
10+
The state mapping is configurable, by default active and inactive
11+
states are OK, failed and all others are CRIT.
12+
Note that by default, failed systemd services that are disabled do not result in CRIT.
13+
This is configurable so that such services do trigger a CRIT.
1314

14-
item:
15-
The fixed statement {{Summary}}
15+
item: The fixed statement {{Summary}}
1616

17-
discovery:
18-
One summary service is created.
17+
discovery: One summary service is created.

tests/unit/cmk/plugins/collection/agent_based/test_systemd_units.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,7 @@ def test_discover_systemd_units_services_summary(
10081008
"else": 2,
10091009
"states": {"active": 0, "failed": 2, "inactive": 0},
10101010
"states_default": 2,
1011+
"disabled_critical": False,
10111012
},
10121013
SECTION,
10131014
[
@@ -1029,6 +1030,7 @@ def test_discover_systemd_units_services_summary(
10291030
"else": 2,
10301031
"states": {"active": 0, "failed": 2, "inactive": 0},
10311032
"states_default": 2,
1033+
"disabled_critical": False,
10321034
},
10331035
SECTION,
10341036
[
@@ -1044,6 +1046,7 @@ def test_discover_systemd_units_services_summary(
10441046
"else": 2,
10451047
"states": {"active": 0, "failed": 2, "inactive": 0},
10461048
"states_default": 2,
1049+
"disabled_critical": False,
10471050
},
10481051
SECTION,
10491052
[
@@ -1060,6 +1063,7 @@ def test_discover_systemd_units_services_summary(
10601063
"else": 2,
10611064
"states": {"active": 0, "failed": 2, "inactive": 0},
10621065
"states_default": 2,
1066+
"disabled_critical": False,
10631067
},
10641068
SECTION,
10651069
[
@@ -1076,6 +1080,7 @@ def test_discover_systemd_units_services_summary(
10761080
"else": 2,
10771081
"states": {"active": 0, "failed": 2, "inactive": 0},
10781082
"states_default": 2,
1083+
"disabled_critical": False,
10791084
},
10801085
Section(services={}, sockets={}),
10811086
[
@@ -1103,6 +1108,7 @@ def test_check_systemd_units_services(
11031108
"else": 2,
11041109
"states": {"active": 2, "failed": 1, "inactive": 0},
11051110
"states_default": 2,
1111+
"disabled_critical": False,
11061112
},
11071113
Section(
11081114
sockets={
@@ -1139,6 +1145,7 @@ def test_check_systemd_units_sockets(
11391145
"else": 2,
11401146
"states": {"active": 0, "failed": 2, "inactive": 0},
11411147
"states_default": 2,
1148+
"disabled_critical": False,
11421149
"ignored": [],
11431150
"activating_levels": (30, 60),
11441151
"deactivating_levels": (30, 60),
@@ -1158,6 +1165,7 @@ def test_check_systemd_units_sockets(
11581165
"else": 2,
11591166
"states": {"active": 0, "failed": 1, "inactive": 0},
11601167
"states_default": 2,
1168+
"disabled_critical": False,
11611169
"ignored": [],
11621170
"activating_levels": (30, 60),
11631171
"deactivating_levels": (30, 60),
@@ -1206,6 +1214,7 @@ def test_check_systemd_units_sockets(
12061214
"activating_levels": (30, 60),
12071215
"deactivating_levels": (30, 60),
12081216
"reloading_levels": (30, 60),
1217+
"disabled_critical": False,
12091218
},
12101219
Section(
12111220
sockets={},
@@ -1245,6 +1254,7 @@ def test_check_systemd_units_sockets(
12451254
"activating_levels": (30, 60),
12461255
"deactivating_levels": (30, 60),
12471256
"reloading_levels": (30, 60),
1257+
"disabled_critical": False,
12481258
},
12491259
Section(
12501260
sockets={},
@@ -1274,6 +1284,7 @@ def test_check_systemd_units_sockets(
12741284
"activating_levels": (30, 60),
12751285
"deactivating_levels": (30, 60),
12761286
"reloading_levels": (30, 60),
1287+
"disabled_critical": False,
12771288
},
12781289
Section(
12791290
sockets={},
@@ -1303,6 +1314,7 @@ def test_check_systemd_units_sockets(
13031314
"activating_levels": (30, 60),
13041315
"deactivating_levels": (30, 60),
13051316
"reloading_levels": (30, 60),
1317+
"disabled_critical": False,
13061318
},
13071319
Section(
13081320
sockets={},
@@ -1329,6 +1341,7 @@ def test_check_systemd_units_sockets(
13291341
"else": 2,
13301342
"states": {"active": 0, "failed": 2, "inactive": 0},
13311343
"states_default": 2,
1344+
"disabled_critical": False,
13321345
"ignored": [],
13331346
"activating_levels": (30, 60),
13341347
"deactivating_levels": (30, 60),
@@ -1360,6 +1373,7 @@ def test_check_systemd_units_sockets(
13601373
"else": 2,
13611374
"states": {"active": 0, "failed": 2, "inactive": 0},
13621375
"states_default": 2,
1376+
"disabled_critical": False,
13631377
"ignored": [
13641378
"systemd-timesyncd.service",
13651379
"systemd-ask-password-console",
@@ -1395,6 +1409,7 @@ def test_check_systemd_units_sockets(
13951409
"else": 2,
13961410
"states": {"active": 0, "failed": 2, "inactive": 0},
13971411
"states_default": 2,
1412+
"disabled_critical": False,
13981413
"ignored": [
13991414
"systemd.",
14001415
],
@@ -1440,6 +1455,7 @@ def test_check_systemd_units_sockets(
14401455
"else": 2,
14411456
"states": {"active": 0, "failed": 2, "inactive": 0},
14421457
"states_default": 2,
1458+
"disabled_critical": False,
14431459
"ignored": [],
14441460
"activating_levels": (30, 60),
14451461
"deactivating_levels": (30, 60),
@@ -1465,11 +1481,43 @@ def test_check_systemd_units_sockets(
14651481
],
14661482
id="One failed, but disabled",
14671483
),
1484+
pytest.param(
1485+
{
1486+
"disabled_critical": True,
1487+
"else": 2,
1488+
"states": {"active": 0, "failed": 2, "inactive": 0},
1489+
"states_default": 2,
1490+
"ignored": [],
1491+
"activating_levels": (30, 60),
1492+
"deactivating_levels": (30, 60),
1493+
"reloading_levels": (30, 60),
1494+
},
1495+
Section(
1496+
sockets={},
1497+
services={
1498+
"systemd-timesyncd.service": UnitEntry(
1499+
name="systemd-timesyncd.service",
1500+
loaded_status="loaded",
1501+
active_status="failed",
1502+
current_state="failed",
1503+
description="Import ZFS pool fgprs\\x2dpbs02\\x2dpool1\\x2d100",
1504+
enabled_status="disabled",
1505+
),
1506+
},
1507+
),
1508+
[
1509+
Result(state=State.OK, summary="Total: 1"),
1510+
Result(state=State.OK, summary="Disabled: 1"),
1511+
Result(state=State.CRIT, summary="Failed: 1"),
1512+
],
1513+
id="One disabled, but critical state configured in params -> CRIT",
1514+
),
14681515
pytest.param(
14691516
{
14701517
"else": 2,
14711518
"states": {"active": 0, "failed": 0, "inactive": 0},
14721519
"states_default": 2,
1520+
"disabled_critical": False,
14731521
"ignored": [],
14741522
"activating_levels": (30, 60),
14751523
"deactivating_levels": (30, 60),

0 commit comments

Comments
 (0)