commit 8c64fb6b3b07d28f1f3415a33ea6fb5e43ea9fed Author: Markus Birth Date: Tue Nov 14 17:12:50 2017 +0100 Initial commit. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fbc4e80 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +ALL_FOLDERS := ${shell find ./src/ -mindepth 1 -maxdepth 1 -type d -print0 | xargs -0} +#ALL_FOLDERS := $(dir $(wildcard ./src/*/.)) + +#ALL_TARGETS = $(ALL_FOLDERS:./src/%=build/%.mkp) +ALL_TARGETS := ${shell bin/findtargets.py build/ $(ALL_FOLDERS)} + +all: $(ALL_TARGETS) + + +$(ALL_TARGETS): $(ALL_FOLDERS) + @echo "Building $@ from $<" + bin/makemkp.py $< ./build/ + + +# cleanup + +.PHONY: clean show_targets +clean: + -rm ./build/*.mkp + +show_targets: + @echo $(ALL_TARGETS) diff --git a/README.md b/README.md new file mode 100644 index 0000000..29fb775 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +Check_MK Plugins +================ + diff --git a/bin/findtargets.py b/bin/findtargets.py new file mode 100644 index 0000000..bb0cc12 --- /dev/null +++ b/bin/findtargets.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import configparser +import os +import sys + +if len(sys.argv) < 3: + print("Syntax: {} BUILD_DIR FILE_LIST".format(sys.argv[0])) + sys.exit(1) + +source_dirs = sys.argv[2:] +dst_dir = sys.argv[1] + +for src_dir in source_dirs: + pkg_name = os.path.basename(src_dir) + + info = { + "name": pkg_name, + "version": 1.0 + } + + if os.path.isfile(src_dir + "/baseinfo.ini"): + cfg = configparser.ConfigParser() + cfg.read(src_dir + "/baseinfo.ini") + for key in cfg["info"]: + info[key] = cfg["info"][key] + + dst_file = os.path.normpath(dst_dir + "/" + "{}-{}.mkp".format(info["name"], info["version"])) + print(dst_file) diff --git a/bin/makemkp.py b/bin/makemkp.py new file mode 100644 index 0000000..fdcb117 --- /dev/null +++ b/bin/makemkp.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import configparser +import json +import os +import sys +import pprint +import subprocess +import tarfile +import time +from io import BytesIO + +if len(sys.argv) < 3: + print("Syntax: {} SRCDIR DESTDIR".format(sys.argv[0])) + sys.exit(1) + +src_dir = sys.argv[1] +dst_dir = sys.argv[2] + +if not os.path.isdir(src_dir): + print("{} is not a directory!".format(src_dir)) + sys.exit(2) + +if not os.path.isdir(dst_dir): + print("{} is not a directory!".format(dst_dir)) + sys.exit(3) + +pkg_name = os.path.basename(src_dir) + +info = { + "title" : "Title of {}".format(pkg_name), + "name" : pkg_name, + "description" : "Please add a description here", + "version" : "1.0", + "version.packaged" : "1.4.0", + "version.min_required" : "1.4.0", + "packaged_by" : "makemkp.py", + "author" : "Add your name here", + "download_url" : "http://example.com/{}/".format(pkg_name), + "files" : {} +} + +cfg = configparser.ConfigParser() +cfg.read(src_dir + "/baseinfo.ini") + +for key in cfg["info"]: + info[key] = cfg["info"][key].encode("utf-8") + +dst_file = os.path.normpath(dst_dir + "/" + "{}-{}.mkp".format(info["name"], info["version"])) + +print("Packaging {} v{} into {}...".format(info["name"], info["version"], dst_file)) + +tar = tarfile.open(name=dst_file, mode="w:gz") + + +# COLLECT FILES + +package_parts = [ (part, title, perm) for part, title, perm in [ + ( "checks", "Checks", 0644 ), + ( "notifications", "Notification scripts", 0755 ), + ( "inventory", "Inventory plugins", 0644 ), + ( "checkman", "Checks' man pages", 0644 ), + ( "agents", "Agents", 0755 ), + ( "web", "Multisite extensions", 0644 ), + ( "pnp-templates", "PNP4Nagios templates", 0644 ), + ( "doc", "Documentation files", 0644 ), + ( "bin", "Binaries", 0755 ), + ( "lib", "Libraries", 0644 ), + ( "mibs", "SNMP MIBs", 0644 ), +]] + +def files_in_dir(dir, prefix = ""): + if dir == None or not os.path.exists(dir): + return [] + + result = [] + files = os.listdir(dir) + for f in files: + if f in [ '.', '..' ] or f.startswith('.') or f.endswith('~'): + continue + + path = dir + "/" + f + if os.path.isdir(path): + result += files_in_dir(path, prefix + f + "/") + else: + result.append(prefix + f) + result.sort() + return result + +def create_tar_info(filename, size): + info = tarfile.TarInfo() + info.mtime = time.time() + info.uid = 0 + info.gid = 0 + info.size = size + info.mode = 0644 + info.type = tarfile.REGTYPE + info.name = filename + return info + +def tar_from_string(tar, filename, payload): + data_stream = BytesIO(payload) + tarinfo = create_tar_info(filename, len(data_stream.getvalue())) + tar.addfile(tarinfo, data_stream) + +files = {} +num_files = 0 +for part, title, perm in package_parts: + files_list = files_in_dir(src_dir + "/" + part) + files[part] = files_list + num_files += len(files_list) + +info["files"] = files +info["num_files"] = num_files + +info_file = pprint.pformat(info) +info_json = json.dumps(info) +tar_from_string(tar, "info", info_file) +tar_from_string(tar, "info.json", info_json) + + +for part in info["files"]: + filenames = info["files"][part] + if len(filenames) > 0: + subtarname = part + ".tar" + subdata = subprocess.check_output(["tar", "cf", "-", "--dereference", "--force-local", + "-C", src_dir + "/" + part] + filenames) + tar_from_string(tar, subtarname, subdata) + +tar.close() diff --git a/build/.gitignore b/build/.gitignore new file mode 100644 index 0000000..779296e --- /dev/null +++ b/build/.gitignore @@ -0,0 +1 @@ +*.mkp diff --git a/src/envivio/baseinfo.ini b/src/envivio/baseinfo.ini new file mode 100644 index 0000000..679a99c --- /dev/null +++ b/src/envivio/baseinfo.ini @@ -0,0 +1,7 @@ +[info] +title = Ericsson Envivio 4Caster +author = Markus Birth +description = SNMP based checks for the Ericsson Envivio 4Caster encoder. +version = 2017.06.20.1 +version.min_required = 1.2.8p2 +download_url = https://github.com/mbirth/check_mk-plugins diff --git a/src/envivio/checkman/envivio_alarms b/src/envivio/checkman/envivio_alarms new file mode 100644 index 0000000..ae35d32 --- /dev/null +++ b/src/envivio/checkman/envivio_alarms @@ -0,0 +1,17 @@ +title: Envivio 4Caster: Alarms +catalog: hw/other +agents: snmp +license: GPL +distribution: check_mk +description: + This check monitors the list of alarms of Envivio 4Caster encoders. + + Active alarms are displayed with their messages. Errors and Minor problems + make the check turn to {WARN}, Critical alarms cause a {CRIT} status. + + Once the alarms are cleared from the device, the status of the check will + turn back to {OK} again. + +inventory: + If the SNMP data contains info about the alarms, it will be detected automatically. + diff --git a/src/envivio/checkman/envivio_cpu b/src/envivio/checkman/envivio_cpu new file mode 100644 index 0000000..cd8ad49 --- /dev/null +++ b/src/envivio/checkman/envivio_cpu @@ -0,0 +1,22 @@ +title: Envivio 4Caster: CPU +catalog: hw/other +agents: snmp +license: GPL +distribution: check_mk +description: + This check monitors the CPU usages of Envivio 4Caster encoders. + + It shows the average CPU usage over all installed CPUs. If that goes + over 95%, the check turns to {WARN}, 98% and more make it turn into + {CRIT}. + + Performance data for all CPUs and the average value are also collected. + + This check also includes a perfometer. + +perfdata: + CPU usage of every single CPU and the average value are collected. + +inventory: + If the SNMP data contains info about the CPUs, it will be detected automatically. + diff --git a/src/envivio/checkman/envivio_memory b/src/envivio/checkman/envivio_memory new file mode 100644 index 0000000..580b8d3 --- /dev/null +++ b/src/envivio/checkman/envivio_memory @@ -0,0 +1,22 @@ +title: Envivio 4Caster: Memory +catalog: hw/other +agents: snmp +license: GPL +distribution: check_mk +description: + This check monitors the memory usage of Envivio 4Caster encoders. + + It shows the physical, paged and virtual memory usage. If one value + goes above 90%, a {WARN} marker will appear. If it goes above 95%, that + will turn into a {CRIT} marker. However, no "problem" will be triggered. + + Performance data is also being collected. + + This check also includes a perfometer. + +perfdata: + Memory usage for physical, paged and virtual memory. + +inventory: + If the SNMP data contains info about the memory, it will be detected automatically. + diff --git a/src/envivio/checks/envivio_alarms b/src/envivio/checks/envivio_alarms new file mode 100644 index 0000000..b8dde32 --- /dev/null +++ b/src/envivio/checks/envivio_alarms @@ -0,0 +1,63 @@ +#!/usr/bin/python +# -*- coding: utf-8; py-indent-offset: 4 -*- +# _______ __ _ ____ __ +# | | \ | |___ \ / / +# | | \| | __) | / /-,_ +# | | |\ |/ __/ /__ _| +# |_______|_| \__|_____| |_| +# +# @author Markus Birth +# MIBs: http:///Snmp/Mibs/ + +def inventory_envivio_alarms(info): + inventory = [] + inventory.append( ("Alarms", None) ) + return inventory + +def check_envivio_alarms(item, _no_params, info): + severities = [ "Info", "Critical", "Error", "Minor" ] + sev2omd = [ 0, 2, 1, 1 ] + + status = 0 + message = "" + longmsg = "" + maxsev = 1 + + for aid, stamp, severity, details, obj, label in info: + # replace Pipes by Slashes to not confuse Check_MK + details = details.replace("|", "/") + severity = saveint(severity) + omdsev = sev2omd[severity] + if omdsev > status: + status = omdsev + if omdsev == maxsev: + message += " %s." % (details) + elif omdsev > maxsev: + # Clear message to only show alarms of the highest priority + message = " %s." % (details) + maxsev = omdsev + longmsg += "\\n%s [%s] %s (%s)" % (stamp, severities[severity], details, label) + + if status == 0: + message += "No alarms." + + message += longmsg + + return status, message + +check_info["envivio_alarms"] = { + "check_function" : check_envivio_alarms, + "inventory_function" : inventory_envivio_alarms, + "service_description" : "%s", + "snmp_info" : (".1.3.6.1.4.1.10613.1.3.1", [ + 1, # Alarm ID + 2, # Timestamp + 3, # Severity (2 = Error) + 4, # Detail info + 5, # Device / Service + 6, # Message + ]), + "snmp_scan_function" : lambda oid: oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.4.1.10613"), + "has_perfdata" : False, + "handle_empty_info" : True +} diff --git a/src/envivio/checks/envivio_cpu b/src/envivio/checks/envivio_cpu new file mode 100644 index 0000000..5197f56 --- /dev/null +++ b/src/envivio/checks/envivio_cpu @@ -0,0 +1,52 @@ +#!/usr/bin/python +# -*- coding: utf-8; py-indent-offset: 4 -*- +# _______ __ _ ____ __ +# | | \ | |___ \ / / +# | | \| | __) | / /-,_ +# | | |\ |/ __/ /__ _| +# |_______|_| \__|_____| |_| +# +# @author Markus Birth +# MIBs: http:///Snmp/Mibs/ + +def inventory_envivio_cpu(info): + inventory = [] + for cpuavg, cpuall in info: + inventory.append( ("CPU Usage", None) ) + return inventory + +def check_envivio_cpu(item, _no_params, info): + status = 0 + + for cpuavg, cpuall in info: + cpuavg = float(cpuavg) + coreinfo = cpuall.split(",") + corecount = len(coreinfo) + message = "%i Cores, Average: %.2f%%" % (corecount, cpuavg) + + if cpuavg > 98: + status = 2 + elif cpuavg > 95: + status =1 + + perfdata = [ ("CPU_Avg_Usage", cpuavg, 95, 98, 0, 100) ] + + for i in range(0, len(coreinfo)): + coreinfo[i] = float(coreinfo[i]) + perfdata.append( ("CPU%02i_Usage" % i, coreinfo[i], None, None, 0, 100) ) + + return status, message, perfdata + + return 3, "%s not found in SNMP data." % item + +check_info["envivio_cpu"] = { + "check_function" : check_envivio_cpu, + "inventory_function" : inventory_envivio_cpu, + "service_description" : "%s", + "snmp_info" : (".1.3.6.1.4.1.10613.10.1", [ + 1, # Average CPU Usage (%) + 2, # CPU Usage by Core (%, comma separated) + ]), + "snmp_scan_function" : lambda oid: oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.4.1.10613"), + "has_perfdata" : True +} diff --git a/src/envivio/checks/envivio_memory b/src/envivio/checks/envivio_memory new file mode 100644 index 0000000..57a624a --- /dev/null +++ b/src/envivio/checks/envivio_memory @@ -0,0 +1,97 @@ +#!/usr/bin/python +# -*- coding: utf-8; py-indent-offset: 4 -*- +# _______ __ _ ____ __ +# | | \ | |___ \ / / +# | | \| | __) | / /-,_ +# | | |\ |/ __/ /__ _| +# |_______|_| \__|_____| |_| +# +# @author Markus Birth +# MIBs: http:///Snmp/Mibs/ + +def inventory_envivio_memory(info): + inventory = [] + for totalPhys, usedPhys, totalPaged, usedPaged, totalVirt, usedVirt in info: + inventory.append( ("Memory Usage", None) ) + return inventory + +def envivio_memory_unit_to_string(memkb): + units = ["kB", "MB", "GB", "TB"] + unitidx = 0 + + while memkb > 9999: + memkb /= 1000.0 + unitidx += 1 + + return "%.1f %s" % (memkb, units[unitidx]) + +def check_envivio_memory(item, _no_params, info): + # convert to int + for i in range(0, len(info[0])): + info[0][i] = int(info[0][i]) + + status = 0 + + for totalPhys, usedPhys, totalPaged, usedPaged, totalVirt, usedVirt in info: + freePhys = totalPhys - usedPhys + freePaged = totalPaged - usedPaged + freeVirt = totalVirt - usedVirt + + percPhys = usedPhys*100.0/totalPhys if totalPhys > 0 else 0.0 + percPaged = usedPaged*100.0/totalPaged if totalPaged > 0 else 0.0 + percVirt = usedVirt*100.0/totalVirt if totalVirt > 0 else 0.0 + + message = "Physical (%iGB): %.1f%% used" % ((totalPhys/1024/1024), percPhys) + if percPhys > 95: + message += " (!!)" + elif percPhys >= 90: + message += " (!)" + message += " / Paged (%iGB): %.1f%% used" % ((totalPaged/1024/1024), percPaged) + if percPaged > 95: + message += " (!!)" + elif percPaged >= 90: + message += " (!)" + message += " / Virtual (%iGB): %.1f%% used" % ((totalVirt/1024/1024), percVirt) + if percVirt > 95: + message += " (!!)" + elif percVirt >= 90: + message += " (!)" + + longmsg = "" + longmsg += "\\nPhysical: Used %s of %s (%.1f%%), %s free" % (envivio_memory_unit_to_string(usedPhys), envivio_memory_unit_to_string(totalPhys), percPhys, envivio_memory_unit_to_string(freePhys)) + longmsg += "\\nPaged: Used %s of %s kB (%.1f%%), %s kB free" % (envivio_memory_unit_to_string(usedPaged), envivio_memory_unit_to_string(totalPaged), percPaged, envivio_memory_unit_to_string(freePaged)) + longmsg += "\\nVirtual: Used %s of %s kB (%.1f%%), %s kB free" % (envivio_memory_unit_to_string(usedVirt), envivio_memory_unit_to_string(totalVirt), percVirt, envivio_memory_unit_to_string(freeVirt)) + + perfdata = [ + ("Physical_Used_KB", usedPhys, None, None), + ("Physical_Total_KB", totalPhys, None, None), + ("Physical_Percent", percPhys, None, None, 0, 100), + ("Paged_Used_KB", usedPaged, None, None), + ("Paged_Total_KB", totalPaged, None, None), + ("Paged_Percent", percPaged, None, None, 0, 100), + ("Virtual_Used_KB", usedVirt, None, None), + ("Virtual_Total_KB", totalVirt, None, None), + ("Virtual_Percent", percVirt, None, None, 0, 100), + ] + + message += longmsg + + return status, message, perfdata + + return 3, "%s not found in SNMP data." % item + +check_info["envivio_memory"] = { + "check_function" : check_envivio_memory, + "inventory_function" : inventory_envivio_memory, + "service_description" : "%s", + "snmp_info" : (".1.3.6.1.4.1.10613.10.2", [ + 1, # total physical mem (kB) + 2, # used physical mem (kB) + 3, # total paged mem (kB) + 4, # used paged mem (kB) + 5, # total virtual mem (kB) + 6, # used virtual mem (kB) + ]), + "snmp_scan_function" : lambda oid: oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.4.1.10613"), + "has_perfdata" : True +} diff --git a/src/envivio/web/plugins/perfometer/envivio_cpu.py b/src/envivio/web/plugins/perfometer/envivio_cpu.py new file mode 100644 index 0000000..ab6aaba --- /dev/null +++ b/src/envivio/web/plugins/perfometer/envivio_cpu.py @@ -0,0 +1,31 @@ +#!/usr/bin/python +# -*- coding: utf-8; py-indent-offset: 4 -*- +# _______ __ _ ____ __ +# | | \ | |___ \ / / +# | | \| | __) | / /-,_ +# | | |\ |/ __/ /__ _| +# |_______|_| \__|_____| |_| +# +# @author Markus Birth + +def perfometer_envivio_cpu(row, check_command, perfdata): + if len(perfdata) < 1: + return "", "" + + ccur = float(perfdata[0][1]) + #cwarn = float(perfdata[0][3]) + #ccrit = float(perfdata[0][4]) + + cwarn = 95 + ccrit = 98 + + if ccur > ccrit: + color = "#f88" + elif ccur > cwarn: + color = "#ff6" + else: + color = "#8f8" + + return "%.2f%%" % ccur, perfometer_linear(ccur, color) + +perfometers["check_mk-envivio_cpu"] = perfometer_envivio_cpu diff --git a/src/envivio/web/plugins/perfometer/envivio_memory.py b/src/envivio/web/plugins/perfometer/envivio_memory.py new file mode 100644 index 0000000..24209ab --- /dev/null +++ b/src/envivio/web/plugins/perfometer/envivio_memory.py @@ -0,0 +1,42 @@ +#!/usr/bin/python +# -*- coding: utf-8; py-indent-offset: 4 -*- +# _______ __ _ ____ __ +# | | \ | |___ \ / / +# | | \| | __) | / /-,_ +# | | |\ |/ __/ /__ _| +# |_______|_| \__|_____| |_| +# +# @author Markus Birth + +def perfometer_envivio_memory(row, check_command, perfdata): + if len(perfdata) < 1: + return "", "" + + phys_used = int(perfdata[0][1]) + phys_total = int(perfdata[1][1]) + page_used = int(perfdata[3][1]) + page_total = int(perfdata[4][1]) + virt_used = int(perfdata[6][1]) + virt_total = int(perfdata[7][1]) + + phys_free = phys_total - phys_used + page_free = page_total - page_used + virt_free = virt_total - virt_used + + mem_used = phys_used + page_used + virt_used + mem_total = phys_total + page_total + virt_total + + # paint used ram and swap + bar = '' + bar += perfometer_td(100 * phys_used / mem_total, "#097054") + bar += perfometer_td(100 * page_used / mem_total, "#6599ff") + bar += perfometer_td(100 * virt_used / mem_total, "#ffde00") + + bar += perfometer_td(100 * phys_free / mem_total, "#ccfff1") + bar += perfometer_td(100 * page_free / mem_total, "#e6eeff") + bar += perfometer_td(100 * virt_free / mem_total, "#fff8cc") + + bar += "
" + return "%.1f%%" % (100.0 * (float(mem_used) / float(mem_total))), bar + +perfometers["check_mk-envivio_memory"] = perfometer_envivio_memory