diff --git a/.werks/15873 b/.werks/15873 new file mode 100644 index 00000000000..a6ee2a4a406 --- /dev/null +++ b/.werks/15873 @@ -0,0 +1,13 @@ +Title: ucd_cpu_load: Consider the number of CPUs +Class: fix +Compatible: compat +Component: checks +Date: 1697635673 +Edition: cre +Level: 1 +Version: 2.2.0p18 + +The number of CPUs in UCD SNMP Daemon: CPU Utilization was hardcoded to 1, which is mostly wrong today. + +With this Werk we count the number of CPUs by fetching {HOST-RESOURCES-V2-MIB::hrProcessorFrwID}. +If this is not available the check falls back to 1 CPU. diff --git a/cmk/base/plugins/agent_based/ucd_cpu_load.py b/cmk/base/plugins/agent_based/ucd_cpu_load.py index a889d57bf5d..2a9b9e39436 100644 --- a/cmk/base/plugins/agent_based/ucd_cpu_load.py +++ b/cmk/base/plugins/agent_based/ucd_cpu_load.py @@ -3,7 +3,7 @@ # This file is part of Checkmk (https://checkmk.com). It is subject to the terms and # conditions defined in the file COPYING, which is part of this source code package. -from typing import Optional +from typing import List from .agent_based_api.v1 import register, SNMPTree from .agent_based_api.v1.type_defs import StringTable @@ -11,8 +11,9 @@ from .utils.ucd_hr_detection import UCD -def parse_ucd_cpu_load(string_table: StringTable) -> Optional[Section]: - if len(string_table) != 3: +def parse_ucd_cpu_load(string_table: List[StringTable]) -> Section | None: + cpu_loads, cpu_count = string_table + if len(cpu_loads) != 3: return None return Section( load=Load( @@ -22,10 +23,12 @@ def parse_ucd_cpu_load(string_table: StringTable) -> Optional[Section]: else float(int_cpu_load_str) / 100.0 if int_cpu_load_str else 0 - for int_cpu_load_str, float_cpu_load_str in string_table + for int_cpu_load_str, float_cpu_load_str in cpu_loads ) ), - num_cpus=1, + num_cpus=len(cpu_count) + if cpu_count + else 1, # fallback to 1 if we don't get the number of cpu's from SNMP ) @@ -33,12 +36,20 @@ def parse_ucd_cpu_load(string_table: StringTable) -> Optional[Section]: name="ucd_cpu_load", parsed_section_name="cpu", parse_function=parse_ucd_cpu_load, - fetch=SNMPTree( - base=".1.3.6.1.4.1.2021.10.1", - oids=[ - "5", # UCD-SNMP-MIB::laLoadInt Int table - "6", # UCD-SNMP-MIB::laLoadFloat Float table - ], - ), + fetch=[ + SNMPTree( + base=".1.3.6.1.4.1.2021.10.1", + oids=[ + "5", # UCD-SNMP-MIB::laLoadInt Int table + "6", # UCD-SNMP-MIB::laLoadFloat Float table + ], + ), + SNMPTree( + base=".1.3.6.1.2.1.25.3.3.1", + oids=[ + "1", # HOST-RESOURCES-V2-MIB::hrProcessorFrwID + ], + ), + ], detect=UCD, ) diff --git a/tests/unit/cmk/base/plugins/agent_based/test_ucd_cpu_load.py b/tests/unit/cmk/base/plugins/agent_based/test_ucd_cpu_load.py index 45547a14303..09c841a18f0 100644 --- a/tests/unit/cmk/base/plugins/agent_based/test_ucd_cpu_load.py +++ b/tests/unit/cmk/base/plugins/agent_based/test_ucd_cpu_load.py @@ -3,6 +3,8 @@ # This file is part of Checkmk (https://checkmk.com). It is subject to the terms and # conditions defined in the file COPYING, which is part of this source code package. +from typing import List + import pytest from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import StringTable @@ -14,15 +16,18 @@ ["string_table", "expected_section"], [ pytest.param( - [["312", "3.123213"], ["280", "2.78897"], ["145", "1.34563546"]], + [ + [["312", "3.123213"], ["280", "2.78897"], ["145", "1.34563546"]], + [[".0.0"], [".0.0"], [".0.0"], [".0.0"]], + ], Section( load=Load(load1=3.123213, load5=2.78897, load15=1.34563546), - num_cpus=1, + num_cpus=4, ), id="complete dataset", ), pytest.param( - [["", "5,234"], ["234", ""], ["", ""]], + [[["", "5,234"], ["234", ""], ["", ""]], []], Section( load=Load(load1=5.234, load5=2.34, load15=0), num_cpus=1, @@ -31,5 +36,5 @@ ), ], ) -def test_parse_ucd_cpu_load(string_table: StringTable, expected_section: Section) -> None: +def test_parse_ucd_cpu_load(string_table: List[StringTable], expected_section: Section) -> None: assert parse_ucd_cpu_load(string_table) == expected_section