Module: check_mk
Branch: master
Commit: 48a17f5ed4a696d3c490a3aabb656d878e292534
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=48a17f5ed4a696…
Author: Mathias Kettner <mk(a)mathias-kettner.de>
Date: Fri Aug 19 22:34:56 2011 +0200
support non-Ascii characters in SNMP strings
---
.bugs/13 | 15 ++++++++++++---
ChangeLog | 2 ++
checks/printer_supply | 13 ++++++++-----
modules/check_mk.py | 12 +++++++++++-
modules/snmp.py | 11 +++++++++++
5 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/.bugs/13 b/.bugs/13
index 69b2283..0c30b25 100644
--- a/.bugs/13
+++ b/.bugs/13
@@ -1,10 +1,11 @@
Title: Umlaute in SNMP-Daten und Servicedescription
Component: checks
+State: done
+Class: bug
+Date: 2010-12-21 12:12:02
Benefit: 1
-State: open
Cost: 4
-Date: 2010-12-21 12:12:02
-Class: bug
+Fun: 0
Ein Drucker sendet per SNMP Latin1
kodierte Wert, z.B. Resttonerbehälter. Daraus baut Check_MK eine
@@ -18,3 +19,11 @@ im Falle vom Datentyp String, automatisch konvertiert. Oder
man macht das explizit im Check, der weiß, dass die Daten
evtl. kodiert daher kommen.
+
+2011-08-19 22:34:40: changed state open -> done
+snmp_character_encodings muss definiert werden. Aktuell wird
+das nur in printer_supply verwendet. Ob andere Checks aktuell
+betroffen sind, ist nicht klar.
+Evtl. kann man einst auch Windows-Eventlogs auf diese
+Art machen. Obwohl ich eher finde, dass man das auf dem Agent
+lösen sollte.
diff --git a/ChangeLog b/ChangeLog
index 545d4d2..68196b7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -18,6 +18,8 @@
* Windows Agent: Now supports direct execution of powershell scripts
* local: PNP template now supports multiple performance values
* lnx_if: make lnx_if the default interface check for Linux
+ * printer_supply: support non-Ascii characters in items like
+ "Resttonerbehälter". You need to define snmp_character_encodings in
main.mk
MK Livestatus:
* WaitObject: allow to separate host name and service with a semicolon.
diff --git a/checks/printer_supply b/checks/printer_supply
index fe64faf..81cf105 100644
--- a/checks/printer_supply
+++ b/checks/printer_supply
@@ -61,16 +61,19 @@ printer_supply_some_remaining_status = 1
# Add the color description to that item
def printer_supply_fix_infos(info):
colors = []
- for index, line in enumerate(info):
- if line[0].startswith('Toner Cartridge') \
- or line[0].startswith('Image Drum Unit'):
+ new_info = []
+ for line in info:
+ line_0 = snmp_decode_string(line[0]) # give chance for latin1->utf8 decoding
+ if line_0.startswith('Toner Cartridge') \
+ or line_0.startswith('Image Drum Unit'):
if line[3]:
colors += [ line[3] ]
color = line[3]
elif line[3] == '':
color = colors[index - len(colors)]
- info[index][0] = '%s %s' % (color.title(), line[0])
- return info
+ line_0 = '%s %s' % (color.title(), line_0)
+ new_info.append([line_0] + line[1:])
+ return new_info
def inventory_printer_supply(info):
# Ignore devices which show -2 for current value and -2 for max value -> useless
diff --git a/modules/check_mk.py b/modules/check_mk.py
index 0991fba..f7d6d3d 100755
--- a/modules/check_mk.py
+++ b/modules/check_mk.py
@@ -225,9 +225,10 @@ debug_log = None
monitoring_host = "localhost" # your Nagios host
max_num_processes = 50
-# SNMP communities
+# SNMP communities and encoding
snmp_default_community = 'public'
snmp_communities = []
+snmp_character_encodings = []
# Inventory and inventory checks
inventory_check_interval = None # Nagios intervals (4h = 240)
@@ -604,6 +605,11 @@ def snmp_credentials_of(hostname):
# nothing configured for this host -> use default
return snmp_default_community
+def get_snmp_character_encoding(hostname):
+ entries = host_extra_conf(hostname, snmp_character_encodings)
+ if len(entries) > 0:
+ return entries[0]
+
def check_uses_snmp(check_type):
check_name = check_type.split(".")[0]
return snmp_info.has_key(check_name) or snmp_info_single.has_key(check_name)
@@ -2320,6 +2326,10 @@ no_inventory_possible = None
output.write("def agent_port_of(hostname):\n return %d\n\n" %
agent_port_of(hostname))
output.write("def snmp_port_spec(hostname):\n return %r\n\n" %
snmp_port_spec(hostname))
+ # SNMP character encoding
+ output.write("def get_snmp_character_encoding(hostname):\n return
%r\n\n"
+ % get_snmp_character_encoding(hostname))
+
# Parameters for checks: Default values are defined in checks/*. The
# variables might be overridden by the user in main.mk. We need
# to set the actual values of those variables here. Otherwise the users'
diff --git a/modules/snmp.py b/modules/snmp.py
index 198f143..4d5450e 100644
--- a/modules/snmp.py
+++ b/modules/snmp.py
@@ -66,6 +66,7 @@ def convert_from_hex(value):
r += chr(int(hx, 16))
return r
+
def oid_to_bin(oid):
return u"".join([ unichr(int(p)) for p in
oid.strip(".").split(".") ])
@@ -484,3 +485,13 @@ def get_stored_snmpwalk(hostname, oid):
break
# import pprint ; pprint.pprint(rowinfo)
return rowinfo
+
+# Helper function to be used in checks. It applies a user-specified
+# character encoding in order to tranlate e.g. latin1 to utf8
+def snmp_decode_string(text):
+ encoding = get_snmp_character_encoding(g_hostname)
+ if encoding:
+ return text.decode(encoding).encode("utf-8")
+ else:
+ return text
+