Skip to content

Commit 7799ea2

Browse files
Simon HarmsSimon0Harms
authored andcommitted
mk_sap: Add exclude_paths option to skip monitoring objects
The monitor_paths option of the mk_sap agent plugin is a pure allow list. When using wildcard patterns there is no way to skip single unwanted monitoring objects below a matched subtree, e.g. the alert container of a client which only holds purely technical number range objects (like ALAUTOUID) that roll over by design and produce permanent noise once they pass their warning threshold. The only workarounds are to enumerate all wanted sibling nodes explicitly (losing auto-discovery of new nodes) or to disable the alert in the SAP system itself. Introduce an exclude_paths option which uses the same unix shell pattern syntax as monitor_paths. A path matching any exclude pattern is skipped, even if it matches one of the monitor_paths patterns. Exclude rules are always matched against the full path and are intentionally not shortened to the first two segments during toplevel matching: shortening a rule which targets a single subtree node would exclude the whole monitor. A rule matching the toplevel path itself still skips the whole monitor and saves the RFC calls for its tree. Since path segments are built from the 40 character SAP field MTNAMESHRT, long node names arrive truncated and patterns have to match the truncated name. This is documented in the sample config. The option defaults to an empty list, existing configurations are not affected.
1 parent 7e7faef commit 7799ea2

3 files changed

Lines changed: 88 additions & 0 deletions

File tree

agents/sap/sap.cfg

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,22 @@ monitor_paths += [
4949
#'SAP CCMS Monitor Templates/Operating System/OperatingSystem/CPU/CPU_Utilization',
5050
#'*',
5151
]
52+
53+
# A list of strings using the same unix shell pattern syntax as
54+
# monitor_paths (see above). All monitoring objects whose path matches at
55+
# least one of these patterns are excluded from monitoring, even if the
56+
# path is matched by one of the monitor_paths patterns. This can be used
57+
# to skip single objects below a monitor_paths wildcard, e.g. the alert
58+
# container of a client which only holds purely technical number range
59+
# objects rolling over by design.
60+
# Anchoring the pattern to the affected subtree is recommended to avoid
61+
# accidentally excluding objects in other monitors.
62+
# Note: The path segments are built from the SAP field MTNAMESHRT, which
63+
# is limited to 40 characters. Long node names are therefore truncated
64+
# (e.g. "Client 000 Alert Messages for Number Ran") and patterns have to
65+
# match the truncated name. To verify the exact paths, temporarily enable
66+
# the debug output line in the plugin (search for 'node["PATH"]').
67+
exclude_paths += [
68+
#'SAP CCMS Technical Expert Monitors/All Monitoring Contexts/Critical Number Ranges/Critical Number Ranges All Clients/Client 000 Alert Messages for Number Ran*',
69+
#'SAP CCMS Technical Expert Monitors/All Monitoring Contexts/Critical Number Ranges/*/Client 066*',
70+
]

cmk/plugins/sap/agents/mk_sap.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,13 @@
136136
"SAP CCMS Monitor Templates/Dialog Overview/*",
137137
]
138138
monitor_types = [] # type: list[str]
139+
140+
# A list of strings using the same unix shell pattern syntax as
141+
# monitor_paths (see above). All monitoring objects whose path matches at
142+
# least one of these patterns are excluded from monitoring, even if the
143+
# path is matched by one of the monitor_paths patterns. This can be used
144+
# to skip single objects below a monitor_paths wildcard.
145+
exclude_paths = [] # type: list[str]
139146
config_file = MK_CONFDIR + "/sap.cfg"
140147

141148
cfg = {} # type: list[dict[Any, Any]] | dict[Any, Any]
@@ -208,6 +215,15 @@ class SapError(Exception):
208215

209216

210217
def to_be_monitored(path, toplevel_match=False):
218+
# Exclude rules are always matched against the full path. They are
219+
# intentionally not shortened during toplevel matching: Shortening a
220+
# rule which targets a single subtree node would exclude the whole
221+
# monitor instead. A rule matching the toplevel path itself still
222+
# skips the whole monitor and saves the RFC calls for its tree.
223+
for rule in exclude_paths:
224+
if fnmatch.fnmatch(path, rule):
225+
return False
226+
211227
for rule in monitor_paths:
212228
if toplevel_match and rule.count("/") > 1:
213229
rule = "/".join(rule.split("/")[:2])

tests/unit/cmk/plugins/sap/agents/test_mk_sap.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,59 @@ def test_recursion(monkeypatch):
112112
}
113113

114114

115+
@pytest.mark.parametrize(
116+
"monitor, exclude, path, toplevel_match, expected",
117+
[
118+
# default behaviour without exclude_paths stays untouched
119+
(["SAP CCMS Monitor Templates/Dialog Overview/*"], [], "SAP CCMS Monitor Templates/Dialog Overview/ResponseTime", False, True),
120+
(["SAP CCMS Monitor Templates/Dialog Overview/*"], [], "SAP CCMS Monitor Templates/Other Monitor/Foo", False, False),
121+
# toplevel matching shortens monitor rules to the first two segments
122+
(["SAP CCMS Monitor Templates/Dialog Overview/ResponseTime"], [], "SAP CCMS Monitor Templates/Dialog Overview", True, True),
123+
# a matching exclude rule wins over a matching monitor rule.
124+
# Note the truncated last path segment: segments come from the
125+
# 40 character SAP field MTNAMESHRT, patterns must match the
126+
# truncated name (pattern anchored to the subtree as recommended
127+
# in sap.cfg)
128+
(
129+
["SAP CCMS Technical Expert Monitors/All Monitoring Contexts/Critical Number Ranges/*"],
130+
["SAP CCMS Technical Expert Monitors/All Monitoring Contexts/Critical Number Ranges/Critical Number Ranges All Clients/Client 000 Alert Messages for Number Ran*"],
131+
"SAP CCMS Technical Expert Monitors/All Monitoring Contexts/Critical Number Ranges/Critical Number Ranges All Clients/Client 000 Alert Messages for Number Ran",
132+
False,
133+
False,
134+
),
135+
# sibling nodes not matching the exclude rule are still monitored
136+
(
137+
["SAP CCMS Technical Expert Monitors/All Monitoring Contexts/Critical Number Ranges/*"],
138+
["SAP CCMS Technical Expert Monitors/All Monitoring Contexts/Critical Number Ranges/Critical Number Ranges All Clients/Client 000 Alert Messages for Number Ran*"],
139+
"SAP CCMS Technical Expert Monitors/All Monitoring Contexts/Critical Number Ranges/Critical Number Ranges All Clients/Client 100 Alert Messages for Number Ran",
140+
False,
141+
True,
142+
),
143+
# an exclude rule targeting a subtree node must not skip the whole
144+
# monitor during toplevel matching (exclude rules are not shortened)
145+
(
146+
["SAP CCMS Technical Expert Monitors/All Monitoring Contexts/Critical Number Ranges/*"],
147+
["SAP CCMS Technical Expert Monitors/All Monitoring Contexts/Critical Number Ranges/Critical Number Ranges All Clients/Client 000 Alert Messages for Number Ran*"],
148+
"SAP CCMS Technical Expert Monitors/All Monitoring Contexts",
149+
True,
150+
True,
151+
),
152+
# an exclude rule matching the toplevel path skips the whole monitor
153+
(
154+
["*"],
155+
["SAP CCMS Monitor Templates/Dialog Overview*"],
156+
"SAP CCMS Monitor Templates/Dialog Overview",
157+
True,
158+
False,
159+
),
160+
],
161+
)
162+
def test_to_be_monitored(monkeypatch, monitor, exclude, path, toplevel_match, expected):
163+
monkeypatch.setattr(mk_sap, "monitor_paths", monitor)
164+
monkeypatch.setattr(mk_sap, "exclude_paths", exclude)
165+
assert mk_sap.to_be_monitored(path, toplevel_match) is expected
166+
167+
115168
def test_state_file_round_trip(monkeypatch, tmp_path):
116169
state_file = tmp_path / "sap.state"
117170
state_file.write_text(mk_sap.serialize_states(STATES))

0 commit comments

Comments
 (0)