From a6381efa53d15e033268c35d115543a70ab86f6b Mon Sep 17 00:00:00 2001 From: Konstantin Wolff Date: Tue, 2 Jun 2015 20:21:03 +0200 Subject: [PATCH 1/2] done some code cleanup -> PEP8, fixed some logical stuff like not used variables in all sensors --- miniprobe/miniprobe.py | 21 ++++--- miniprobe/probe.py | 41 +++++++------- miniprobe/sensors/adns.py | 32 ++++++----- miniprobe/sensors/apt.py | 17 +++--- miniprobe/sensors/cpuload.py | 51 +++++++++-------- miniprobe/sensors/cputemp.py | 11 ++-- miniprobe/sensors/diskspace.py | 22 +++----- miniprobe/sensors/ds18b20.py | 9 ++- .../sensors/{external_ip.py => externalip.py} | 42 +++++++------- miniprobe/sensors/http.py | 17 +++--- miniprobe/sensors/memory.py | 55 +++++++++++-------- miniprobe/sensors/ping.py | 22 ++++---- miniprobe/sensors/port.py | 15 +++-- miniprobe/sensors/probehealth.py | 15 ++--- miniprobe/sensors/snmpcustom.py | 8 +-- miniprobe/sensors/snmptraffic.py | 6 +- miniprobe/tests/__init__.py | 0 miniprobe/tests/test_sensors.py | 10 ++-- 18 files changed, 202 insertions(+), 192 deletions(-) rename miniprobe/sensors/{external_ip.py => externalip.py} (76%) create mode 100644 miniprobe/tests/__init__.py diff --git a/miniprobe/miniprobe.py b/miniprobe/miniprobe.py index f89c66c..54c756f 100644 --- a/miniprobe/miniprobe.py +++ b/miniprobe/miniprobe.py @@ -1,16 +1,16 @@ #!/usr/bin/env python -#Copyright (c) 2014, Paessler AG -#All rights reserved. -#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +# Copyright (c) 2014, Paessler AG +# All rights reserved. +# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the # following conditions are met: -#1. Redistributions of source code must retain the above copyright notice, this list of conditions +# 1. Redistributions of source code must retain the above copyright notice, this list of conditions # and the following disclaimer. -#2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions +# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions # and the following disclaimer in the documentation and/or other materials provided with the distribution. -#3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse +# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse # or promote products derived from this software without specific prior written permission. -#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, @@ -20,9 +20,9 @@ # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -### PRTG Python Miniprobe -### Miniprobe needs at least Python 2.7 because of "importlib" -### If older python version is used you will have to install "importlib" +# PRTG Python Miniprobe +# Miniprobe needs at least Python 2.7 because of "importlib" +# If older python version is used you will have to install "importlib" # import general modules import sys @@ -149,4 +149,3 @@ def clean_mem(): os.popen("sysctl vm.drop_caches=1") os.popen("sysctl vm.drop_caches=2") os.popen("sysctl vm.drop_caches=3") - diff --git a/miniprobe/probe.py b/miniprobe/probe.py index 68712e9..b61714c 100644 --- a/miniprobe/probe.py +++ b/miniprobe/probe.py @@ -1,16 +1,16 @@ #!/usr/bin/env python -#Copyright (c) 2014, Paessler AG -#All rights reserved. -#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +# Copyright (c) 2014, Paessler AG +# All rights reserved. +# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the # following conditions are met: -#1. Redistributions of source code must retain the above copyright notice, this list of conditions +# 1. Redistributions of source code must retain the above copyright notice, this list of conditions # and the following disclaimer. -#2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions +# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions # and the following disclaimer in the documentation and/or other materials provided with the distribution. -#3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse +# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse # or promote products derived from this software without specific prior written permission. -#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, @@ -20,9 +20,9 @@ # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -### PRTG Python Miniprobe -### Miniprobe needs at least Python 2.7 because of "importlib" -### If older python version is used you will have to install "importlib" +# PRTG Python Miniprobe +# Miniprobe needs at least Python 2.7 because of "importlib" +# If older python version is used you will have to install "importlib" # import general modules import sys @@ -46,7 +46,6 @@ import multiprocessing except Exception as e: print e - #sys.exit() # Implemented for internal testing only. Not for public usage! http = False @@ -94,8 +93,6 @@ def main(): data_announce = mini_probe.create_parameters(config, announce_json, 'announce') logging.debug("Announce Data: %s" % data_announce) json_history = [] - timeout = False - while not announce: try: # announcing the probe and all sensors @@ -107,8 +104,7 @@ def main(): logging.info("ANNOUNCE request successfully sent to PRTG Core Server at %s:%s." % (config["server"], config["port"])) logging.debug("Connecting to %s:%s" % (config["server"], config["port"])) - logging.debug("Status Code: %s | Message: %s" % (request_announce.status_code, - request_announce.text)) + logging.debug("Status Code: %s | Message: %s" % (request_announce.status_code, request_announce.text)) request_announce.close() except requests.exceptions.Timeout: logging.error("ANNOUNCE Timeout: " + str(data_announce)) @@ -137,8 +133,8 @@ def main(): logging.debug(request_task.text) try: json_response = request_task.json() - except Exception as e: - logging.info("Error: %s! Server returned: %s" % (e, request_task.text)) + except Exception as ex: + logging.info("Error: %s! Server returned: %s" % (ex, request_task.text)) request_task.close() gc.collect() task = True @@ -147,8 +143,8 @@ def main(): logging.debug("task_url: " + url_task + "\ntask_data: " + str(task_data)) except requests.exceptions.Timeout: logging.error("TASK Timeout: " + str(task_data)) - logging.debug("Timeout encountered. Need to write more code to handle timeoutzzzzz: %s" % json_history) - timeout = True + logging.debug("Timeout encountered. Need to write more code to handle timeoutzzzzz: %s" + % json_history) except Exception as announce_error: logging.error(announce_error) time.sleep(int(config['baseinterval']) / 2) @@ -178,13 +174,14 @@ def main(): while len(json_payload_data) < len(element): out = out_queue.get() json_payload_data.append(out) - except Exception as e: - logging.error(e) + except Exception as ex: + logging.error(ex) pass url_data = mini_probe.create_url(config, 'data', http) try: - request_data = requests.post(url_data, data=json.dumps(json_payload_data), verify=False, timeout=30) + request_data = requests.post(url_data, data=json.dumps(json_payload_data), + verify=False, timeout=30) logging.info("DATA request successfully sent to PRTG Core Server at %s:%s. Status: %s" % (config["server"], config["port"], request_data.status_code)) logging.debug("data_url: " + url_data + "\ndata_data: " + str(json_payload_data)) diff --git a/miniprobe/sensors/adns.py b/miniprobe/sensors/adns.py index d542ec6..12a758d 100644 --- a/miniprobe/sensors/adns.py +++ b/miniprobe/sensors/adns.py @@ -32,7 +32,7 @@ pass -class aDNS(object): +class ADNS(object): def __init__(self): gc.enable() @@ -49,10 +49,12 @@ def get_sensordef(): Definition of the sensor and data to be shown in the PRTG WebGUI """ sensordefinition = { - "kind": aDNS.get_kind(), + "kind": ADNS.get_kind(), "name": "DNS", - "description": "Monitors a DNS server (Domain Name Service), resolves a domain name, and compares it to an IP address", - "help": "The DNS sensor monitors a Domain Name Service (DNS) server. It resolves a domain name and compares it to a given IP address.", + "description": "Monitors a DNS server (Domain Name Service), " + "resolves a domain name, and compares it to an IP address", + "help": "The DNS sensor monitors a Domain Name Service (DNS) server. " + "It resolves a domain name and compares it to a given IP address.", "tag": "mpdnssensor", "groups": [ { @@ -114,18 +116,16 @@ def get_sensordef(): @staticmethod def get_data(data, out_queue): - adns = aDNS() - result = "" - timed = 0 + adns = ADNS() logging.debug("Running sensor: %s" % adns.get_kind()) try: start_time = timeit.default_timer() - result = adns.get_record(data['timeout'],data['port'],data['domain'],data['type'],data['host']) + result = adns.get_record(data['timeout'], data['port'], data['domain'], data['type'], data['host']) timed = timeit.default_timer() - start_time logging.debug("DNS: %s" % result) - except Exception as e: + except Exception as ex: logging.error("Ooops Something went wrong with '%s' sensor %s. Error: %s" % (adns.get_kind(), - data['sensorid'], e)) + data['sensorid'], ex)) data_r = { "sensorid": int(data['sensorid']), "error": "Exception", @@ -134,7 +134,7 @@ def get_data(data, out_queue): } out_queue.put(data_r) return 1 - dns_channel = adns.get_dns(int(timed*1000)) + dns_channel = adns.get_dns(int(timed * 1000)) addressdata = [] for element in dns_channel: addressdata.append(element) @@ -176,9 +176,9 @@ def get_record(timeout, port, domain, type, host): resolver.port = port if type == 'PTR': addr = dns.reversename.from_address(domain) - answers = dns.resolver.query(addr,type) + answers = dns.resolver.query(addr, type) else: - answers = dns.resolver.query(domain,type) + answers = dns.resolver.query(domain, type) if (type == 'A') or (type == 'AAAA'): for rdata in answers: result = result + str(rdata.address) + ", " @@ -187,10 +187,12 @@ def get_record(timeout, port, domain, type, host): result = result + rdata.preference + ": " + rdata.exchange + ", " elif type == 'SOA': for rdata in answers: - result = result + "NS: " + str(rdata.mname) + ", TECH: " + str(rdata.rname) + ", S/N: " + str(rdata.serial) + ", Refresh: " + str(rdata.refresh/60) + " min, Expire: " + str(rdata.expire/60) + " min " + result = result + "NS: " + str(rdata.mname) + ", TECH: " + str(rdata.rname) + ", S/N: " + str(rdata.serial) + ", Refresh: " + str(rdata.refresh / 60) + " min, Expire: " \ + + str(rdata.expire / 60) + " min " elif (type == 'CNAME') or (type == 'NS') or (type == 'PTR'): for rdata in answers: result = result + str(rdata.target) + ", " except dns.resolver.NoAnswer: - result = "DNS Error while getting %s record. This could be the result of a misconfiguration in the sensor settings" % type + result = "DNS Error while getting %s record. " \ + "This could be the result of a misconfiguration in the sensor settings" % type return result[:-2] diff --git a/miniprobe/sensors/apt.py b/miniprobe/sensors/apt.py index 9ed59d2..004bd8e 100644 --- a/miniprobe/sensors/apt.py +++ b/miniprobe/sensors/apt.py @@ -1,16 +1,16 @@ #!/usr/bin/env python -#Copyright (c) 2014, Paessler AG -#All rights reserved. -#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +# Copyright (c) 2014, Paessler AG +# All rights reserved. +# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the # following conditions are met: -#1. Redistributions of source code must retain the above copyright notice, this list of conditions +# 1. Redistributions of source code must retain the above copyright notice, this list of conditions # and the following disclaimer. -#2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions +# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions # and the following disclaimer in the documentation and/or other materials provided with the distribution. -#3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse +# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse # or promote products derived from this software without specific prior written permission. -#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, @@ -22,7 +22,7 @@ import os import gc import logging -import sys + class APT(object): def __init__(self): @@ -55,7 +55,6 @@ def check(self): upgrade = 0 install = 0 remove = 0 - total = 0 ret = os.popen("apt-get -s dist-upgrade | grep 'newly inst'") updatedata = ret.readlines() ret.close() diff --git a/miniprobe/sensors/cpuload.py b/miniprobe/sensors/cpuload.py index 27e4dce..f794e3d 100644 --- a/miniprobe/sensors/cpuload.py +++ b/miniprobe/sensors/cpuload.py @@ -1,16 +1,16 @@ #!/usr/bin/env python -#Copyright (c) 2014, Paessler AG -#All rights reserved. -#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +# Copyright (c) 2014, Paessler AG +# All rights reserved. +# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the # following conditions are met: -#1. Redistributions of source code must retain the above copyright notice, this list of conditions +# 1. Redistributions of source code must retain the above copyright notice, this list of conditions # and the following disclaimer. -#2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions +# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions # and the following disclaimer in the documentation and/or other materials provided with the distribution. -#3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse +# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse # or promote products derived from this software without specific prior written permission. -#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, @@ -88,20 +88,27 @@ def read_cpu(path): for line in cpu: for element in line.split(" "): data.append(element) - channel_list = [{"name": "Load Average 1min", - "mode": "float", - "kind": "Custom", - "customunit": "", - "value": float(data[0])}, - {"name": "Load Average 5min", - "mode": "float", - "kind": "Custom", - "customunit": "", - "value": float(data[1])}, - {"name": "Load Average 10min", - "mode": "float", - "kind": "Custom", - "customunit": "", - "value": float(data[2])}] + channel_list = [ + { + "name": "Load Average 1min", + "mode": "float", + "kind": "Custom", + "customunit": "", + "value": float(data[0]) + }, + { + "name": "Load Average 5min", + "mode": "float", + "kind": "Custom", + "customunit": "", + "value": float(data[1]) + }, + { + "name": "Load Average 10min", + "mode": "float", + "kind": "Custom", + "customunit": "", + "value": float(data[2]) + }] cpu.close() return channel_list diff --git a/miniprobe/sensors/cputemp.py b/miniprobe/sensors/cputemp.py index 84c0456..5d7753c 100644 --- a/miniprobe/sensors/cputemp.py +++ b/miniprobe/sensors/cputemp.py @@ -26,6 +26,7 @@ if not os.path.exists("/sys/class/thermal/thermal_zone0/temp"): temp = False + class CPUTemp(object): def __init__(self): gc.enable() @@ -78,7 +79,7 @@ def get_data(data, out_queue): temperature = CPUTemp() logging.debug("Running sensor: %s" % temperature.get_kind()) try: - temp = temperature.read_temp(data) + tmp = temperature.read_temp(data) except Exception as e: logging.error("Ooops Something went wrong with '%s' sensor %s. Error: %s" % (temperature.get_kind(), data['sensorid'], e)) @@ -91,7 +92,7 @@ def get_data(data, out_queue): out_queue.put(data) return 1 tempdata = [] - for element in temp: + for element in tmp: tempdata.append(element) data = { "sensorid": int(data['sensorid']), @@ -107,9 +108,9 @@ def get_data(data, out_queue): def read_temp(config): data = [] chandata = [] - temp = open("/sys/class/thermal/thermal_zone0/temp", "r") - lines = temp.readlines() - temp.close() + tmp = open("/sys/class/thermal/thermal_zone0/temp", "r") + lines = tmp.readlines() + tmp.close() temp_string = lines[0] logging.debug("CPUTemp Debug message: Temperature from file: %s" % temp_string) temp_c = float(temp_string) / 1000.0 diff --git a/miniprobe/sensors/diskspace.py b/miniprobe/sensors/diskspace.py index 0c06c21..17fe330 100644 --- a/miniprobe/sensors/diskspace.py +++ b/miniprobe/sensors/diskspace.py @@ -1,16 +1,16 @@ #!/usr/bin/env python -#Copyright (c) 2014, Paessler AG -#All rights reserved. -#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +# Copyright (c) 2014, Paessler AG +# All rights reserved. +# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the # following conditions are met: -#1. Redistributions of source code must retain the above copyright notice, this list of conditions +# 1. Redistributions of source code must retain the above copyright notice, this list of conditions # and the following disclaimer. -#2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions +# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions # and the following disclaimer in the documentation and/or other materials provided with the distribution. -#3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse +# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse # or promote products derived from this software without specific prior written permission. -#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, @@ -117,11 +117,3 @@ def read_disk(self): channel_list.append(channel4) channel_list.append(channel5) return channel_list - - - - - - - - diff --git a/miniprobe/sensors/ds18b20.py b/miniprobe/sensors/ds18b20.py index 567d96f..2895335 100644 --- a/miniprobe/sensors/ds18b20.py +++ b/miniprobe/sensors/ds18b20.py @@ -28,6 +28,7 @@ if not os.path.isdir("/sys/bus/w1/devices"): dev = False + class DS18B20(object): def __init__(self): gc.enable() @@ -123,16 +124,18 @@ def read_temp(config): time.sleep(0.2) equals_pos = lines[1].find('t=') if equals_pos != -1: - temp_string = lines[1][equals_pos+2:] + temp_string = lines[1][equals_pos + 2:] logging.debug("DS18B20 Debug message: Temperature from file: %s" % temp_string) temp_c = float(temp_string) / 1000.0 temp_f = 1.8 * temp_c + 32.0 if config['celfar'] == "C": data.append(temp_c) - logging.debug("DS18B20 Debug message: Temperature after calculations:: %s %s" % (temp_c, config['celfar'])) + logging.debug("DS18B20 Debug message: Temperature after calculations:: %s %s" % + (temp_c, config['celfar'])) else: data.append(temp_f) - logging.debug("DS18B20 Debug message: Temperature after calculations:: %s %s" % (temp_f, config['celfar'])) + logging.debug("DS18B20 Debug message: Temperature after calculations:: %s %s" % + (temp_f, config['celfar'])) temp.close() for i in range(len(data)): chandata.append({"name": "Sensor: " + sens[i], diff --git a/miniprobe/sensors/external_ip.py b/miniprobe/sensors/externalip.py similarity index 76% rename from miniprobe/sensors/external_ip.py rename to miniprobe/sensors/externalip.py index 33f26a6..5a53a68 100644 --- a/miniprobe/sensors/external_ip.py +++ b/miniprobe/sensors/externalip.py @@ -1,16 +1,16 @@ #!/usr/bin/env python -#Copyright (c) 2014, Paessler AG -#All rights reserved. -#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +# Copyright (c) 2014, Paessler AG +# All rights reserved. +# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the # following conditions are met: -#1. Redistributions of source code must retain the above copyright notice, this list of conditions +# 1. Redistributions of source code must retain the above copyright notice, this list of conditions # and the following disclaimer. -#2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions +# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions # and the following disclaimer in the documentation and/or other materials provided with the distribution. -#3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse +# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse # or promote products derived from this software without specific prior written permission. -#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, @@ -27,7 +27,8 @@ import struct server = "http://icanhazip.com" -class External_IP(object): + +class ExternalIP(object): def __init__(self): gc.enable() @@ -44,7 +45,7 @@ def get_sensordef(): Definition of the sensor and data to be shown in the PRTG WebGUI """ sensordefinition = { - "kind": External_IP.get_kind(), + "kind": ExternalIP.get_kind(), "name": "External IP", "description": "Returns the external ip address of the probe", "default": "yes", @@ -57,8 +58,8 @@ def get_sensordef(): @staticmethod def get_data(data, out_queue): - ip = External_IP() - address = "" + ip = ExternalIP() + # address = "" logging.debug("Running sensor: %s" % ip.get_kind()) try: address = ip.get_ip(server) @@ -89,13 +90,16 @@ def get_data(data, out_queue): @staticmethod def get_ip(url): - channel_list = [{"name": "IP-Address", - "ShowChart": 0, - "ShowTable": 0, - "mode": "integer", - "kind": "Custom", - "customunit": "", - "value": 1}] + channel_list = [ + { + "name": "IP-Address", + "ShowChart": 0, + "ShowTable": 0, + "mode": "integer", + "kind": "Custom", + "customunit": "", + "value": 1 + }] return channel_list @staticmethod @@ -105,7 +109,7 @@ def remote_ip(url): ip.close return address - def local_ip(url, ifname): + def local_ip(self, ifname): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) return socket.inet_ntoa(fcntl.ioctl( s.fileno(), diff --git a/miniprobe/sensors/http.py b/miniprobe/sensors/http.py index 21eea9d..6992840 100644 --- a/miniprobe/sensors/http.py +++ b/miniprobe/sensors/http.py @@ -1,16 +1,16 @@ #!/usr/bin/env python -#Copyright (c) 2014, Paessler AG -#All rights reserved. -#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +# Copyright (c) 2014, Paessler AG +# All rights reserved. +# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the # following conditions are met: -#1. Redistributions of source code must retain the above copyright notice, this list of conditions +# 1. Redistributions of source code must retain the above copyright notice, this list of conditions # and the following disclaimer. -#2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions +# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions # and the following disclaimer in the documentation and/or other materials provided with the distribution. -#3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse +# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse # or promote products derived from this software without specific prior written permission. -#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, @@ -151,9 +151,10 @@ def request(self, url, request_method=None, auth_method=None, timeout=None, post req = requests.head(url, auth=(user, password), timeout=timeout, verify=False) else: req = requests.head(url, timeout=timeout, verify=False) + time = req.elapsed except Exception as e: logging.error(e) - time = req.elapsed + raise try: code = req.status_code response_time = time.microseconds / 1000 diff --git a/miniprobe/sensors/memory.py b/miniprobe/sensors/memory.py index e0f3c40..b8006ea 100644 --- a/miniprobe/sensors/memory.py +++ b/miniprobe/sensors/memory.py @@ -1,16 +1,16 @@ #!/usr/bin/env python -#Copyright (c) 2014, Paessler AG -#All rights reserved. -#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +# Copyright (c) 2014, Paessler AG +# All rights reserved. +# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the # following conditions are met: -#1. Redistributions of source code must retain the above copyright notice, this list of conditions +# 1. Redistributions of source code must retain the above copyright notice, this list of conditions # and the following disclaimer. -#2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions +# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions # and the following disclaimer in the documentation and/or other materials provided with the distribution. -#3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse +# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse # or promote products derived from this software without specific prior written permission. -#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, @@ -87,21 +87,30 @@ def read_memory(self, path): for line in mem: tmp = line.split(":")[1].lstrip() data[line.split(":")[0].rstrip()] = tmp.split(" ")[0].rstrip() - channel_list = [{"name": "Memory Total", - "mode": "integer", - "kind": "BytesMemory", - "value": int(data['MemTotal']) * 1024}, - {"name": "Memory Free", - "mode": "integer", - "kind": "BytesMemory", - "value": int(data['MemFree']) * 1024}, - {"name": "Swap Total", - "mode": "integer", - "kind": "BytesMemory", - "value": int(data['SwapTotal']) * 1024}, - {"name": "Swap Free", - "mode": "integer", - "kind": "BytesMemory", - "value": int(data['SwapFree']) * 1024}] + channel_list = [ + { + "name": "Memory Total", + "mode": "integer", + "kind": "BytesMemory", + "value": int(data['MemTotal']) * 1024 + }, + { + "name": "Memory Free", + "mode": "integer", + "kind": "BytesMemory", + "value": int(data['MemFree']) * 1024 + }, + { + "name": "Swap Total", + "mode": "integer", + "kind": "BytesMemory", + "value": int(data['SwapTotal']) * 1024 + }, + { + "name": "Swap Free", + "mode": "integer", + "kind": "BytesMemory", + "value": int(data['SwapFree']) * 1024 + }] mem.close() return channel_list diff --git a/miniprobe/sensors/ping.py b/miniprobe/sensors/ping.py index da67146..af464e8 100644 --- a/miniprobe/sensors/ping.py +++ b/miniprobe/sensors/ping.py @@ -1,16 +1,16 @@ #!/usr/bin/env python -#Copyright (c) 2014, Paessler AG -#All rights reserved. -#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +# Copyright (c) 2014, Paessler AG +# All rights reserved. +# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the # following conditions are met: -#1. Redistributions of source code must retain the above copyright notice, this list of conditions +# 1. Redistributions of source code must retain the above copyright notice, this list of conditions # and the following disclaimer. -#2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions +# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions # and the following disclaimer in the documentation and/or other materials provided with the distribution. -#3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse +# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse # or promote products derived from this software without specific prior written permission. -#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, @@ -22,7 +22,7 @@ import os import gc import logging -import sys + class Ping(object): def __init__(self): @@ -103,7 +103,6 @@ def ping(self, target, count, timeout, packetsize): if ping == '': return "Not reachable!" values = ping.split("/") + [pack_loss] - #logging.debug("Ping Sensor values: %s %s %s %s %s" % (values[0], values[1], values[2], values[3], values[4])) channel_list = [ { "name": "Ping Time Min", @@ -157,7 +156,8 @@ def get_data(data, out_queue): "channel": pingdata } logging.debug("Running sensor: %s" % ping.get_kind()) - logging.debug("Host: %s Pingcount: %s timeout: %s packetsize: %s" % (data['host'], data['pingcount'], data['timeout'], data['packsize'])) + logging.debug("Host: %s Pingcount: %s timeout: %s packetsize: %s" % (data['host'], data['pingcount'], + data['timeout'], data['packsize'])) except Exception as e: logging.error("Ooops Something went wrong with '%s' sensor %s. Error: %s" % (ping.get_kind(), data['sensorid'], e)) @@ -165,7 +165,7 @@ def get_data(data, out_queue): "sensorid": int(data['sensorid']), "error": "Exception", "code": 1, - "message": "Ping failed." #%s" % e + "message": "Ping failed." } out_queue.put(data_r) return 1 diff --git a/miniprobe/sensors/port.py b/miniprobe/sensors/port.py index f9961bc..1d8fb62 100644 --- a/miniprobe/sensors/port.py +++ b/miniprobe/sensors/port.py @@ -1,16 +1,16 @@ #!/usr/bin/env python -#Copyright (c) 2014, Paessler AG -#All rights reserved. -#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +# Copyright (c) 2014, Paessler AG +# All rights reserved. +# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the # following conditions are met: -#1. Redistributions of source code must retain the above copyright notice, this list of conditions +# 1. Redistributions of source code must retain the above copyright notice, this list of conditions # and the following disclaimer. -#2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions +# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions # and the following disclaimer in the documentation and/or other materials provided with the distribution. -#3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse +# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse # or promote products derived from this software without specific prior written permission. -#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, @@ -89,7 +89,6 @@ def port(self, target, timeout, port): start_time = time.time() conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) conn.settimeout(float(timeout)) - #result = conn.connect((remote_server, int(port))) conn.connect((remote_server, int(port))) conn.close() end_time = time.time() diff --git a/miniprobe/sensors/probehealth.py b/miniprobe/sensors/probehealth.py index b753c19..00edeb8 100644 --- a/miniprobe/sensors/probehealth.py +++ b/miniprobe/sensors/probehealth.py @@ -69,7 +69,8 @@ def get_sensordef(): "required": "1", "minimum": 20, "maximum": 75, - "help": "Set the maximum temperature above which the temperature sensor will provide a error (not below 20 or above 75)", + "help": "Set the maximum temperature above which the temperature sensor will " + "provide a error (not below 20 or above 75)", "default": 45 }, ] @@ -213,7 +214,7 @@ def read_temp(self): lines = temp.readlines() temp.close() temp_string = lines[0] - except Exception as e: + except OSError: logging.debug("Could not read temp file, no data will be returned") return chandata logging.debug("CPUTemp Debug message: Temperature from file: %s" % temp_string) @@ -242,27 +243,27 @@ def read_probe_health(self, config): temp.close() temp_float = float(lines[0]) / 1000.0 if temp_float > config['maxtemp']: - health = health - 25 + health -= 25 logging.debug("Current Health: %s percent" % health) - except Exception as e: + except OSError: logging.debug("Health not changed, no temperature available") pass disks = [] for line in os.popen("df -k"): if line.startswith("/"): disks.append(line.rstrip().split()) - tmpHealth = 25 / len(disks) + tmphealth = 25 / len(disks) for line in disks: free = (float(line[3]) / (float(line[2]) + float(line[3]))) * 100 if free < 10: - health = health - tmpHealth + health -= tmphealth logging.debug("Current Health: %s percent" % health) cpu = open('/proc/loadavg', "r") for line in cpu: for element in line.split(" "): data.append(element) if float(data[1]) > 0.70: - health = health - 25 + health -= 25 logging.debug("Current Health: %s percent" % health) chandata.append({"name": "Overall Probe Health", "mode": "integer", diff --git a/miniprobe/sensors/snmpcustom.py b/miniprobe/sensors/snmpcustom.py index e8a5bdb..036ace4 100644 --- a/miniprobe/sensors/snmpcustom.py +++ b/miniprobe/sensors/snmpcustom.py @@ -145,11 +145,12 @@ def snmp_get(self, oid, target, snmp_type, community, port, unit, multiplication try: sys.path.append('./') from pysnmp.entity.rfc3413.oneliner import cmdgen + snmpget = cmdgen.CommandGenerator() + error_indication, error_status, error_index, var_binding = snmpget.getCmd( + cmdgen.CommunityData(community), cmdgen.UdpTransportTarget((target, port)), oid) except Exception as import_error: logging.error(import_error) - snmpget = cmdgen.CommandGenerator() - error_indication, error_status, error_index, var_binding = snmpget.getCmd( - cmdgen.CommunityData(community), cmdgen.UdpTransportTarget((target, port)), oid) + raise if snmp_type == "1": channellist = [ @@ -176,7 +177,6 @@ def snmp_get(self, oid, target, snmp_type, community, port, unit, multiplication @staticmethod def get_data(data, out_queue): snmpcustom = SNMPCustom() - snmp_data = [] try: snmp_data = snmpcustom.snmp_get(str(data['oid']), data['host'], data['value_type'], data['community'], int(data['port']), data['unit'], diff --git a/miniprobe/sensors/snmptraffic.py b/miniprobe/sensors/snmptraffic.py index 5153154..5561a0e 100644 --- a/miniprobe/sensors/snmptraffic.py +++ b/miniprobe/sensors/snmptraffic.py @@ -30,6 +30,7 @@ snmp = False pass + class SNMPTraffic(object): def __init__(self): @@ -124,12 +125,8 @@ def get_sensordef(): def snmp_get(self, target, countertype, community, port, ifindex): if countertype == "1": data = ["1.3.6.1.2.1.2.2.1.10.%s" % str(ifindex), "1.3.6.1.2.1.2.2.1.16.%s" % str(ifindex)] - # data.append("1.3.6.1.2.1.2.2.1.10.%s" % str(ifindex)) - # data.append("1.3.6.1.2.1.2.2.1.16.%s" % str(ifindex)) else: data = ["1.3.6.1.2.1.31.1.1.1.6.%s" % str(ifindex), "1.3.6.1.2.1.31.1.1.1.10.%s" % str(ifindex)] - # data.append("1.3.6.1.2.1.31.1.1.1.6.%s" % str(ifindex)) - # data.append("1.3.6.1.2.1.31.1.1.1.10.%s" % str(ifindex)) snmpget = cmdgen.CommandGenerator() error_indication, error_status, error_index, var_binding = snmpget.getCmd( cmdgen.CommunityData(community), cmdgen.UdpTransportTarget((target, port)), *data) @@ -169,7 +166,6 @@ def snmp_get(self, target, countertype, community, port, ifindex): @staticmethod def get_data(data, out_queue): snmptraffic = SNMPTraffic() - snmp_data = [] try: snmp_data = snmptraffic.snmp_get(data['host'], data['snmp_counter'], data['community'], int(data['port']), data['ifindex']) diff --git a/miniprobe/tests/__init__.py b/miniprobe/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/miniprobe/tests/test_sensors.py b/miniprobe/tests/test_sensors.py index b0c4504..c36a444 100644 --- a/miniprobe/tests/test_sensors.py +++ b/miniprobe/tests/test_sensors.py @@ -1,15 +1,14 @@ #!/usr/bin/env python - from nose.tools import * -from miniprobe.sensors import adns,apt,cpuload,cputemp,diskspace,ds18b20,external_ip,http,memory,nmap,ping,port,portrange,probehealth,snmpcustom,snmptraffic +from miniprobe.sensors import adns,apt,cpuload,cputemp,diskspace,ds18b20,externalip,http,memory,nmap,ping,port,portrange,probehealth,snmpcustom,snmptraffic import multiprocessing class TestSensors: @classmethod def setup_class(cls): cls.test_nmap = nmap.NMAP() - cls.test_adns = adns.aDNS() + cls.test_adns = adns.ADNS() cls.test_apt = apt.APT() cls.test_cpuload = cpuload.CPULoad() cls.test_cputemp = cputemp.CPUTemp() @@ -17,7 +16,7 @@ def setup_class(cls): cls.test_snmpcustom = snmpcustom.SNMPCustom() cls.test_diskspace = diskspace.Diskspace() cls.test_ds18b20 = ds18b20.DS18B20() - cls.test_external_ip = external_ip.External_IP() + cls.test_external_ip = externalip.ExternalIP() cls.test_http = http.HTTP() cls.test_memory = memory.Memory() cls.test_ping = ping.Ping() @@ -38,7 +37,8 @@ def test_nmap_get_sensordef(self): "kind": self.test_nmap.get_kind(), "name": "NMAP", "description": "Checks the availability of systems.", - "help": "Checks the availability of systems on a network and logs this to a separate logfile on the miniprobe.", + "help": "Checks the availability of systems on a network and logs this to a separate " + "logfile on the miniprobe.", "tag": "mpnmapsensor", "groups": [ { From 649ed064e1371ddaaed7bdde8aae5e722f13573c Mon Sep 17 00:00:00 2001 From: Konstantin Wolff Date: Wed, 3 Jun 2015 08:33:40 +0200 Subject: [PATCH 2/2] adapted setup.py to new classnames, fixed bug in probehealth sensor --- miniprobe/sensors/probehealth.py | 28 +++++++++++++++++----------- setup.py | 2 +- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/miniprobe/sensors/probehealth.py b/miniprobe/sensors/probehealth.py index 00edeb8..dd77c8c 100644 --- a/miniprobe/sensors/probehealth.py +++ b/miniprobe/sensors/probehealth.py @@ -210,10 +210,13 @@ def read_temp(self): data = [] chandata = [] try: - temp = open("/sys/class/thermal/thermal_zone0/temp", "r") - lines = temp.readlines() - temp.close() - temp_string = lines[0] + if os.path.exists("/sys/class/thermal/thermal_zone0/temp"): + temp = open("/sys/class/thermal/thermal_zone0/temp", "r") + lines = temp.readlines() + temp.close() + temp_string = lines[0] + else: + return chandata except OSError: logging.debug("Could not read temp file, no data will be returned") return chandata @@ -238,13 +241,16 @@ def read_probe_health(self, config): data = [] chandata = [] try: - temp = open("/sys/class/thermal/thermal_zone0/temp", "r") - lines = temp.readlines() - temp.close() - temp_float = float(lines[0]) / 1000.0 - if temp_float > config['maxtemp']: - health -= 25 - logging.debug("Current Health: %s percent" % health) + if os.path.exists("/sys/class/thermal/thermal_zone0/temp"): + temp = open("/sys/class/thermal/thermal_zone0/temp", "r") + lines = temp.readlines() + temp.close() + temp_float = float(lines[0]) / 1000.0 + if temp_float > config['maxtemp']: + health -= 25 + logging.debug("Current Health: %s percent" % health) + else: + return chandata except OSError: logging.debug("Health not changed, no temperature available") pass diff --git a/setup.py b/setup.py index 7098c09..3c300c9 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,External_IP,aDNS,APT,NMAP" + default_sensors = "Ping,HTTP,Port,SNMPCustom,CPULoad,Memory,Diskspace,SNMPTraffic,CPUTemp,Probehealth,ExternalIP,ADNS,APT,NMAP" if not (other_sensors == ""): default_sensors = default_sensors + "," + other_sensors f=open("./miniprobe/sensors/__init__.py","a")