Module: check_mk
Branch: master
Commit: ab5aaa7dde6e53b614f7e02128dfc9dda24f6216
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=ab5aaa7dde6e53…
Author: Mathias Kettner <mk(a)mathias-kettner.de>
Date: Fri Oct 16 15:38:00 2015 +0200
#2664 FIX ps: Speedup in situation with many matching processes
In one situation with about 7500 matching processes out of 8000 the check now saves
about 15% of the CPU ressources.
---
.werks/2664 | 10 ++++++++++
ChangeLog | 1 +
modules/check_mk_base.py | 27 +++++++++++++++++++--------
3 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/.werks/2664 b/.werks/2664
new file mode 100644
index 0000000..6891d01
--- /dev/null
+++ b/.werks/2664
@@ -0,0 +1,10 @@
+Title: ps: Speedup in situation with many matching processes
+Level: 1
+Component: checks
+Compatible: compat
+Version: 1.2.7i4
+Date: 1445002617
+Class: fix
+
+In one situation with about 7500 matching processes out of 8000 the check now saves
+about 15% of the CPU ressources.
diff --git a/ChangeLog b/ChangeLog
index 2e68c85..4c61766 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,7 @@
* 2663 knuerr_rms_temp: switch to new generic temperature logic, allow e.g. lower
levels...
NOTE: Please refer to the migration notes!
* 2660 FIX: fixed windows agent using the wrong working directory...
+ * 2664 FIX: ps: Speedup in situation with many matching processes...
Multisite:
* 2680 FIX: LDAP: Fixed exception when syncing groups using configurations from
previous versions...
diff --git a/modules/check_mk_base.py b/modules/check_mk_base.py
index 32073af..0c1cc0a 100644
--- a/modules/check_mk_base.py
+++ b/modules/check_mk_base.py
@@ -1093,17 +1093,28 @@ def last_counter_wrap():
-# Deletes counters from g_item_state matching the given pattern and are older_than x
seconds.
-# This is a neccessary cleanup just used by ps.include. Not nice.
-def clear_counters(check_type_prefix, older_than):
+# Makes sure, that no counter with a give prefix is kept longer
+# than min_keep_seconds * 2. Counter is kept at least min_keep_seconds.
+def clear_counters(counter_name_prefix, min_keep_seconds):
global g_item_state
+
+ cleared_key = "last.cleared." + counter_name_prefix
+ if cleared_key in g_item_state:
+ last_cleared, none = g_item_state[cleared_key]
+ if last_cleared + min_keep_seconds > time.time():
+ return # recent enough
+ g_item_state[cleared_key] = (time.time(), None)
+
counters_to_delete = []
- now = time.time()
+ remove_if_min_keep_seconds = time.time() - min_keep_seconds
- for name, (timestamp, value) in g_item_state.items():
- joined_name = type(name) == tuple and name[0] or name
- if joined_name.startswith(check_type_prefix):
- if now > timestamp + older_than:
+ for name, (timestamp, value) in g_item_state.iteritems():
+ if type(name) == tuple:
+ counter_name = name[0] # never needed, since only called by ps currently
+ else:
+ counter_name = name
+ if counter_name.startswith(counter_name_prefix):
+ if timestamp < remove_if_min_keep_seconds:
counters_to_delete.append(name)
for name in counters_to_delete: