Module: check_mk
Branch: master
Commit: 2cd0a937ab582b1bc85c5637701524fda5a82276
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=2cd0a937ab582b…
Author: Mathias Kettner <mk(a)mathias-kettner.de>
Date: Thu May 5 16:02:16 2011 +0200
Impressive speed up of stored snmp walks
---
checks/if | 1 +
modules/snmp.py | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 80 insertions(+), 2 deletions(-)
diff --git a/checks/if b/checks/if
index 1e9ffc3..c37db49 100644
--- a/checks/if
+++ b/checks/if
@@ -25,6 +25,7 @@
# Boston, MA 02110-1301 USA.
def inventory_if(checkname, info):
+ # import pprint; pprint.pprint(info)
return inventory_if_common(if_convert_to_if64(info))
def check_if(item, params, info):
diff --git a/modules/snmp.py b/modules/snmp.py
index bec9d6b..b76a132 100644
--- a/modules/snmp.py
+++ b/modules/snmp.py
@@ -349,6 +349,7 @@ def check_snmp_fixed(item, targetvalue, info):
return (0, "OK - %s" % (value,))
return (3, "Missing item %s in SNMP data" % item)
+g_walk_cache = {}
def get_stored_snmpwalk(hostname, oid):
if oid.startswith("."):
oid = oid[1:]
@@ -361,12 +362,87 @@ def get_stored_snmpwalk(hostname, oid):
dot_star = False
path = snmpwalks_dir + "/" + hostname
+
if opt_debug:
sys.stderr.write("Getting %s from %s\n" % (oid, path))
if not os.path.exists(path):
raise MKGeneralException("No snmpwalk file %s\n" % path)
rowinfo = []
+
+ use_new = True
+ if use_new:
+ # New implementation: use binary search
+ def to_bin_string(oid):
+ return tuple(map(int, oid.strip(".").split(".")))
+
+ def compare_oids(a, b):
+ aa = to_bin_string(a)
+ bb = to_bin_string(b)
+ if len(aa) <= len(bb) and bb[:len(aa)] == aa:
+ result = 0
+ else:
+ result = cmp(aa, bb)
+ return result
+
+ if hostname in g_walk_cache:
+ lines = g_walk_cache[hostname]
+ else:
+ lines = file(path).readlines()
+ g_walk_cache[hostname] = lines
+
+ begin = 0
+ end = len(lines)
+ hit = None
+ while end - begin > 0:
+ current = (begin + end) / 2
+ parts = lines[current].split(None, 1)
+ comp = parts[0]
+ hit = compare_oids(oid_prefix, comp)
+ if hit == 0:
+ break
+ elif hit == 1: # we are too low
+ begin = current + 1
+ else:
+ end = current
+
+ if hit != 0:
+ return [] # not found
+
+
+ def collect_until(index, direction):
+ rows = []
+ while True:
+ line = lines[index]
+ parts = line.split(None, 1)
+ o = parts[0]
+ if o.startswith('.'):
+ o = o[1:]
+ if o == oid or o.startswith(oid_prefix + "."):
+ if len(parts) > 1:
+ value = parts[1]
+ if agent_simulator:
+ value = agent_simulator_process(value)
+ else:
+ value = ""
+ rows.append((o, strip_snmp_value(value)))
+ index += direction
+ if index < 0 or index >= len(lines):
+ break
+ else:
+ break
+ return rows
+
+
+ rowinfo = collect_until(current, -1)
+ rowinfo.reverse()
+ rowinfo += collect_until(current + 1, 1)
+ # import pprint ; pprint.pprint(rowinfo)
+ return rowinfo
+
+
+
+ # Old implementation
hot = False
for line in file(path):
parts = line.split(None, 1)
@@ -383,7 +459,8 @@ def get_stored_snmpwalk(hostname, oid):
value = ""
rowinfo.append((o, strip_snmp_value(value))) # return pair of OID and value
if dot_star:
- return rowinfo # only return first (used by get_single_oid)
+ break
elif hot: # end of interesting part, no point in further search
- return rowinfo
+ break
+ # import pprint ; pprint.pprint(rowinfo)
return rowinfo