diff --git a/VERSION.txt b/VERSION.txt index a2540d2..83b0350 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -15.2.7 +15.2.8 diff --git a/miniprobe/sensors/apt.py b/miniprobe/sensors/apt.py index 004bd8e..90f927b 100644 --- a/miniprobe/sensors/apt.py +++ b/miniprobe/sensors/apt.py @@ -55,7 +55,7 @@ def check(self): upgrade = 0 install = 0 remove = 0 - ret = os.popen("apt-get -s dist-upgrade | grep 'newly inst'") + ret = os.popen("LC_ALL=C apt-get -s dist-upgrade | grep 'newly inst'") updatedata = ret.readlines() ret.close() for line in updatedata: diff --git a/miniprobe/sensors/mdadm.py b/miniprobe/sensors/mdadm.py new file mode 100644 index 0000000..2945a2d --- /dev/null +++ b/miniprobe/sensors/mdadm.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python +# With nice greetings from Dynam-IT GbR +# Suggestion for a mdadm-raid sensor +# Thanks to Paessler for providing the free PRTG Python Probe and the API + +import os +# import re for use of re.split; explained below +import re +import gc +import logging + + +class MDADM(object): + def __init__(self): + gc.enable() + + @staticmethod + def get_kind(): + """ + return sensor kind + """ + return "mpmdadm" + + @staticmethod + def get_sensordef(): + """ + Definition of the sensor and data to be shown in the PRTG WebGUI + """ + sensordefinition = { + "kind": MDADM.get_kind(), + "name": "MDADM RAID Status", + "description": "Monitors status of RAID arrays provided by MDADM", + "help": "Count total number of Arrays, count arrays with missing drives,count arrays resyncing, recovering and checking", + "tag": "mpmdadmsensor", + "fields": [], + "groups": [] + + } + return sensordefinition + + def check(self): + + # Get the standard information output of mdadm and count + numberOfArrays = os.popen("grep ^md -c /proc/mdstat").read() + arraysMissingDrives = 0 + arraysRecovering = 0 + arraysResyncing = 0 + arraysChecking = 0 + + ret = os.popen("cat /proc/mdstat").readlines() + mdstat = ' '.join([line.strip() for line in ret]) + # Using re.split to split output instead of split to prevent cutting the leading "md" + raidArrayList = re.split(' (?=md)', mdstat) + + for index in range(len(raidArrayList)): + # Searching for list entries beginning with "md" + if re.match('^md', raidArrayList[index]): + print raidArrayList[index] + if '_' in raidArrayList[index]: + # adrive missing can also be a defect drive. Defect or missing drives are marked with an "_" instead of an "U" in the drive list + arraysMissingDrives += 1 + if 'recovering' in raidArrayList[index]: + arraysRecovering += 1 + if 'resync' in raidArrayList[index]: + arraysResyncing += 1 + if 'check' in raidArrayList[index]: + arraysChecking += 1 + + channel_list = [ + { + "name": "Total count of RAID arrays", + "mode": "integer", + "unit": "count", + "limitmaxwarning": 0, + "limitmode": 0, + "value": numberOfArrays + }, + { + "name": "RAID arrays with missing drives", + "mode": "integer", + "unit": "count", + # setting this channel to error if arraysMissingDrives is > 0 + "limitmaxerror": 0, + "limitmode": 1, + "value": arraysMissingDrives + }, + { + "name": "RAID arrays recovering", + "mode": "integer", + "unit": "count", + "limitmaxwarning": 0, + "limitmode": 1, + "value": arraysRecovering + }, + { + "name": "RAID arrays resyncing", + "mode": "integer", + "unit": "count", + "limitmaxwarning": 0, + "limitmode": 1, + "value": arraysResyncing + }, + { + "name": "RAID arrays in automatic checking task", + "mode": "integer", + "unit": "count", + # In many linux distributions an array check is performed automatically once a day or week. So we should not warn about this + "limitmaxwarning": 0, + "limitmode": 0, + "value": arraysChecking + }, + ] + return channel_list + + @staticmethod + def get_data(data, out_queue): + mdadm = MDADM() + try: + mdadmdata = mdadm.check() + data_r = { + "sensorid": int(data['sensorid']), + "message": "OK", + "channel": mdadmdata + } + logging.debug("Running sensor: %s" % mdadm.get_kind()) + except Exception as e: + logging.error("Ooops Something went wrong with '%s' sensor %s. Error: %s" % (mdadm.get_kind(), + data['sensorid'], e)) + data_r = { + "sensorid": int(data['sensorid']), + "error": "Exception", + "code": 1, + "message": "MDADM Sensor failed. %s" % e + } + out_queue.put(data_r) + return 1 + del mdadm + gc.collect() + out_queue.put(data_r) + return 0 diff --git a/setup.py b/setup.py index 251ece8..2b575ed 100644 --- a/setup.py +++ b/setup.py @@ -138,7 +138,7 @@ def init_script(self, script_path, user): return init_script_tpl.read() % (script_path, user) def write_load_list(self, ds18b20_sensors, other_sensors): - default_sensors = "Ping,HTTP,Port,SNMPCustom,CPULoad,Memory,Diskspace,SNMPTraffic,CPUTemp,Probehealth,ExternalIP,ADNS,APT,NMAP" + default_sensors = "Ping,HTTP,Port,SNMPCustom,CPULoad,Memory,Diskspace,SNMPTraffic,CPUTemp,Probehealth,ExternalIP,ADNS,APT,NMAP,MDADM" if not (other_sensors == ""): default_sensors = default_sensors + "," + other_sensors f=open("./miniprobe/sensors/__init__.py","a")