def check(self, textkey, data, config={}): if textkey == 'cpu_temp': cpu_temp = 0 runs = 0 raw_temp = '' while cpu_temp == 0 and runs < 3: ret, raw_temp = agent_util.execute_command( "cat /sys/class/thermal/thermal_zone0/temp") t1 = float(raw_temp) / 1000 t2 = float(raw_temp) / 100 cpu_temp = float(t2 % t1) runs += 1 self.log.error("Raw: %s - Measured: %s" % (raw_temp.strip(), cpu_temp)) if cpu_temp == 0: self.log.warning( "CPU temp of '%s' doesn't seem right. Measuring again..." % raw_temp.strip()) if runs >= 3: self.log.error( "Invalid CPU temp of '%s'. Retried 3 times and got same result!" % raw_temp.strip()) return float("%.1f" % cpu_temp) if textkey == 'gpu_temp': ret, raw_temp = agent_util.execute_command( "/opt/vc/bin/vcgencmd measure_temp") gpu_temp = raw_temp.replace("temp=", "") gpu_temp = gpu_temp.replace("'C", "") return float(gpu_temp) return 1337
def get_metadata(self, config): status = agent_util.SUPPORTED msg = None iostat_bin = agent_util.which("iostat") if not iostat_bin: self.log.info("iostat not found") status = agent_util.MISCONFIGURED msg = "Install iostat." return {} # get our devices to monitor devices = [] if 'freebsd' in platform: ret_code, output = agent_util.execute_command("%s -dx" % iostat_bin) output = output.splitlines() if config.get("debug", False): self.log.debug('#####################################################') self.log.debug("IO stats command '%s -dx' output:" % iostat_bin) self.log.debug(str(output)) self.log.debug('#####################################################') for line in output[2:]: try: dev, f2, f3, f4, f5, f6, f7, f8 = line.strip().split() except: continue dev = dev.strip() devices.append(dev) else: ret_code, output = agent_util.execute_command("%s -d" % iostat_bin) output = output.splitlines() if config.get("debug", False): self.log.debug('#####################################################') self.log.debug("IO stats command '%s -d' output:" % iostat_bin) self.log.debug(str(output)) self.log.debug('#####################################################') for line in output[3:]: try: dev, tps, blk_reads, blk_writes, blk_read, blk_write = line.strip().split() except: continue dev = dev.strip() devices.append(dev) # no devices? no resources to monitor then if not devices: status = agent_util.MISCONFIGURED msg = "No devices found from iostat." data = { "stats.util": { "label": "Percentage of CPU time during which I/O requests were issued to the device", "options": devices, "status": status, "error_message": msg } } return data
def check(self, textkey, data, config): ret, blocked = agent_util.execute_command("1m=$(date \"+%b %e\");cat /var/log/pihole.log | awk '/\/etc\/pihole\/gravity.list/ {print $6}' | wc -l") ret, queries = agent_util.execute_command("today=$(date \"+%b %e\");cat /var/log/pihole.log | awk '/query/ {print $6}' | wc -l") # Should really make this a bit faster/leaner but this is pretty fast and uncomplicated. if textkey == 'blocked.today': return float(blocked) if textkey == 'ad_traffic.today': return ((float(blocked) / float(queries)) * 100.0) if textkey == 'dns_queries.today': return float(queries) return 0
def execute_query(sid, config, query): "Run an Oracle query via sqlplus and parse the results" # Generate a temporary file for the query script (file, filename) = tempfile.mkstemp() orig_filename = filename filename += ".sql" f = open(filename, "w") f.write("set pages 1000;\n %s\nquit;" % query) f.close() # Build the SQL*PLUS command and call it cmd = "ORACLE_HOME=%s ORACLE_SID=%s " % (config["oracle_home"], sid) cmd += os.path.join(config.get("oracle_home"), "bin", "sqlplus") cmd += " -S %s/%s @%s" % (config["username"], config["password"], filename) status, output = agent_util.execute_command(cmd) # Remove our temporary file os.remove(filename) os.remove(orig_filename) # Parse the output results = [] lines = output.strip().split("\n") columns = lines[0].lower().split() for line in lines[2:]: line = line.strip() if not line: continue if line.endswith("rows selected."): continue values = line.split() results.append(dict(zip(columns, values))) return results
def check(self, textkey, dev_mount, config): dev_mount = dev_mount.split() device = dev_mount[0] mounted = dev_mount[-1] ret_code, output = agent_util.execute_command(get_df_cmd()) self.log.debug("df output: %s" % str(output)) output = output.splitlines() for line in output[1:]: if line.startswith('Filesystem'): continue line = line.strip() try: df_device, blocks, used, available, capacity, df_mounted = line.split() except: self.log.error("Unable to parse df output: %s" % line) continue if device in [df_device, df_mounted] or mounted in [df_device, df_mounted]: if textkey == "usage.percent_used": return int(capacity.rstrip('%')) elif textkey == "usage.kb_available": return int(available) elif textkey == "filesystem.mounted": return True if textkey == "filesystem.mounted": return False else: raise Exception("device %r not found" % device)
def get_metadata(self, config): status = agent_util.SUPPORTED msg = None # check for tomcat configuration block if ("username" not in config or "console_url" not in config or "password" not in config): self.log.info("tomcat is not configured") status = agent_util.MISCONFIGURED msg = "tomcat is not configured properly" return {} # check if tomcat is even installed or running ret, output = agent_util.execute_command('wget -qO- %s' % config['console_url']) if config.get("debug", False): self.log.debug('#####################################################') self.log.debug("Tomcat command 'wget -qO- %s' output:" % config['console_url']) self.log.debug(str(output)) self.log.debug('#####################################################') if ret != 0: self.log.info("tomcat is not running or installed") status = agent_util.UNSUPPORTED msg = "tomcat not found" return {} data = {} for metric, properties in get_all_data(config).items(): data[metric] = { "label": metric, "options": sorted(properties["options"].keys()), "status": status, "error_message": msg, "unit": properties["unit"] or None } return data
def execute_query(config, query): username = config['username'].strip() password = config["password"].strip() url = config['console_url'] queryType = 'wget -qO-' query = query % (queryType, url, username, password) ret, output = agent_util.execute_command(query) return str(output)
def check(self, textkey, data, config={}): exim_bin = agent_util.which("exim", exc=True) retcode, output = agent_util.execute_command("%s -bpc" % exim_bin) self.log.debug("exim -bpc output: %s" % str(output)) output = output.splitlines() fields = output[0].split() return int(fields[0])
def check(self, textkey, data, config): if textkey.startswith("resource."): sid = data junk, metric, kind = textkey.split(".") metric_mapping = { "process": "processes", "session": "sessions", "enqueue_lock": "enqueue_locks", "enqueue_resource": "enqueue_resources", "ges_lock": "ges_locks", "ges_proc": "ges_procs", "ges_resource": "ges_ress", "max_shared_servers": "max_shared_servers", "transactions": "transactions", } results = execute_query(sid, config, resource_query) for r in results: if r["resource_name"] == metric_mapping.get(metric, None): if kind == "current": return int(r["current_utilization"]) elif kind == "max": return int(r["max_utilization"]) elif textkey.startswith("tablespace"): sid, tablespace = data.split(":") results = execute_query(sid, config, tablespace_query) for r in results: if r["tablespace_name"] == tablespace: if textkey.endswith(".size"): return float(r["sizemb"]) elif textkey.endswith(".free"): return float(r["freemb"]) elif textkey.endswith(".percent_free"): if float(r["sizemb"]) == 0: return 0.0 else: return float(r["freemb"]) * 100.0 / float(r["sizemb"]) # If we got here, the target tablespace wasn't found return 0 elif textkey == "tnslistener": sid = data ip_address = config.get("tns_listener_ip", "127.0.0.1") cmd = "ORACLE_HOME=%s ORACLE_SID=%s " % (config["oracle_home"], sid) cmd += "%s %s" % (os.path.join(config.get("oracle_home"), "bin", "tnsping"), ip_address) status, output = agent_util.execute_command(cmd) if "OK" in output: return 1 else: return 0 else: # Unknown metric type, return 0 by default return 0
def check(self, textkey, data, config): ret, blocked = agent_util.execute_command( "1m=$(date \"+%b %e\");cat /var/log/pihole.log | awk '/\/etc\/pihole\/gravity.list/ {print $6}' | wc -l" ) ret, queries = agent_util.execute_command( "today=$(date \"+%b %e\");cat /var/log/pihole.log | awk '/query/ {print $6}' | wc -l" ) # Should really make this a bit faster/leaner but this is pretty fast and uncomplicated. if textkey == 'blocked.today': return float(blocked) if textkey == 'ad_traffic.today': return ((float(blocked) / float(queries)) * 100.0) if textkey == 'dns_queries.today': return float(queries) return 0
def check(self, textkey, data, config): query = '' if (textkey == 'users.unique_login_count'): query = 'who | wc -l' if (textkey == 'users.total_login_count'): query = 'who |cut -c 1-9 |sort -u |wc -l' ret, output = agent_util.execute_command('%s' % query) return int(output)
def get_sysctl_dict(): status, output = agent_util.execute_command("/sbin/sysctl -a") if status != 0: raise Exception(output) metadata = {} for item in output.splitlines(): m = item.split(" = ") try: metadata[m[0]] = int(m[-1].strip()) except: pass return metadata
def execute_query(config, query): cmd = agent_util.which("psql", exc=True) if "username" in config: cmd += " -U %s" % config["username"] cmd += " -d %s" % config.get("database", "postgres").strip() cmd += (" -c %r" % query) cmd = 'su - %s -c "%s"' % (config.get("username", "postgres"), cmd) if "password" in config and config["password"].strip(): cmd = "PGPASSWORD=%s %s" % (config["password"].strip(), cmd) status, output = agent_util.execute_command(cmd) if status != 0: raise Exception(output) output = agent_util.StringIO(output) parsed_output = list(csv.reader(output, delimiter="|")) return parsed_output
def execute_query(config, query): cmd = agent_util.which("mysql", exc=True) if "username" in config: cmd += " -u %s" % config["username"] if "password" in config and config["password"].strip(): cmd += " -p%s" % config["password"].strip() cmd += (" -Be %r" % str(query)) if "database" in config: cmd += " %s" % config["database"].strip() status, output = agent_util.execute_command(cmd) if status != 0: raise Exception(output) output = agent_util.StringIO(output) parsed_output = list(csv.reader(output, delimiter="\t")) return parsed_output
def check(self, textkey, option, config): cmd = 'tail -25 /var/log/logstash-forwarder/logstash-forwarder.err' retcode, output = agent_util.execute_command(cmd) logs_per_min = 0 last_minute = output.strip().split('\n') for item in last_minute: if 'processing' in item: line = item.split() time = ' '.join(line[0:2]) parts = time.split('.') time = datetime.strptime(parts[0], "%Y/%m/%d %H:%M:%S") time = time.replace(microsecond=int(parts[1])) if (datetime.now() - timedelta(seconds=60)) > time: continue else: logs_per_min = logs_per_min + int(line[-2]) else: continue return logs_per_min
def execute_query(query, config): mongo = agent_util.which("mongo", exc=True) query = "printjson(%s)" % query cmd = "%s --eval %r" % (mongo, query) if "username" in config: cmd += " -u %s" % config["username"] if "password" in config and config["password"].strip(): cmd += " -p%s" % config["password"].strip() status, output = agent_util.execute_command(cmd) if status != 0: raise Exception(output) result = "\n".join(output.split("\n")[2:]) result = re.sub("Timestamp\((.*?), (.*?)\)", r'{"__timestamp__": {"t": \1, "i": \2}}', result) result = re.sub("ISODate\((.*?)\)", r'{"__datetime__": \1}', result) result = json.loads(result, object_hook=custom_json_converter) return result
def get_metadata(self, config): status = agent_util.SUPPORTED msg = None # check if oracle weblogic is installed, running, and on path set_env_command = ("source %s; " % os.path.join(config['wl_home'], "server/bin/setWLSEnv.sh")) if 'wl_home' in config else "" installed = agent_util.which("java") and agent_util.execute_command(set_env_command + "java weblogic.Admin") if not installed: self.log.info("oracle weblogic not installed or not on path") status = agent_util.UNSUPPORTED msg = "oracle weblogic not installed or not on path" return {} if not ("wl_home" in config and "username" in config and "password" in config): self.log.info("Weblogic configuration parameters missing") return {} if not os.path.exists(os.path.join(config['wl_home'], "server/bin/setWLSEnv.sh")): self.log.info("Weblogic setWLSEnv.sh script not found") return {} if status is agent_util.SUPPORTED: try: output = get_metric(config, "ApplicationRuntime") except: self.log.exception("error getting weblogic metric") status = agent_util.MISCONFIGURED msg = "Double check your Weblogic login username and password as well as wl_home." data = {} for type, vals in metrics.items(): try: output = get_metric(config, vals["type"]) except: continue for property, meta in vals["metrics"].items(): textkey = "%s.%s" % (type, property) data[textkey] = { "label": meta["label"], "options": meta.get('options', None), "status": status, "error_message": msg } if "unit" in meta: data[textkey]["unit"] = meta["unit"] return data
def get_metric(config, type, property=None): if 'wl_home' in config: set_env_command = ("source %s; " % os.path.join(config['wl_home'], "server/bin/setWLSEnv.sh")) else: set_env_command = "" cmd = set_env_command + "java weblogic.Admin" if "username" in config: cmd += " -username %s" % config["username"] if "password" in config and config["password"].strip(): cmd += " -password %s" % config["password"].strip() cmd += " GET -pretty -type %s" % type if property: cmd += " -property %s" % property status, output = agent_util.execute_command(cmd) if status != 0: raise Exception(output) output = output.strip().split("\n")[-1] if not property: if output == "No MBeans found": raise Exception(output) else: return output else: parsed_output = output[output.index(":") + 1:].strip() return parsed_output
def get_cpu_metrics(cls): retcode, output = agent_util.execute_command("cat /proc/stat") cls.log.debug("cat /proc/stat output: %s" % str(output)) output = output.splitlines() cpus = {} for line in output: if not line.startswith("cpu"): continue parts = filter(lambda p: p, line.split(" ")) core = parts[0] if core == "cpu": core = "Total" user, nice, system, idle, iowait, irq, softirq = map(int, parts[1:8]) cpus[core] = { "user": user, "nice": nice, "system": system, "idle": idle, "iowait": iowait, "irq": irq, "softirq": softirq } return cpus
def check(self, textkey, device, config): iostat_bin = agent_util.which("iostat") ret, output = agent_util.execute_command("%s -dx %s 1 2" % (iostat_bin, device)) if config.get("debug", False): self.log.debug('#####################################################') self.log.debug("IO stats command '%s -dx %s 1 2' output:" % (iostat_bin, device)) self.log.debug(str(output)) self.log.debug('#####################################################') self.log.debug("iostat -dx output: %s" % str(output)) if 'freebsd' in platform: output = output.splitlines() output = output[3].strip().split() util = float(output[7].strip()) else: output = output.splitlines() output = output[6].strip().split() util = float(output[11].strip()) return util
def execute_query(config, query, data=None): if "username" in config: username = config['username'] + ':' else: username = '' if ("password" in config and config["password"].strip()): password = config["password"].strip() + '@' else: password = '' url = config['console_url'].replace('://', '://' + username + password) if (check_for_curl_installation()): queryType = 'curl --digest --silent' else: queryType = 'wget -qO-' if (data != None): query = query % (queryType, url, data) else: query = query % (queryType, url) ret, output = agent_util.execute_command(query) return str(output);
def get_metadata(self, config): if 'freebsd' in sys.platform: status = agent_util.SUPPORTED msg = None if not agent_util.which("sysctl"): self.log.info("sysctl binary not found") status = agent_util.UNSUPPORTED msg = "sysctl binary not found" return {} if status is agent_util.SUPPORTED: ret, output = agent_util.execute_command("sysctl -a") if config.get("debug", False): self.log.debug('#####################################################') self.log.debug("Memory Usage command 'sysctl -a' output:") self.log.debug(str(output)) self.log.debug('#####################################################') if ret != 0 or not output: status = agent_util.UNSUPPORTED msg = "error executing 'sysctl -a'" if status is agent_util.SUPPORTED: d = self._parse_sysctl(output) required_keys = ( "hw.pagesize", "hw.physmem", "vfs.bufspace", "vm.stats.vm.v_inactive_count", "vm.stats.vm.v_active_count", "vm.stats.vm.v_cache_count", "vm.stats.vm.v_free_count" ) # here we're making sure the set of all the keys we need # are in the set of all keys (subset) if not set(d.keys()).issubset(set(required_keys)): status = agent_util.UNSUPPORTED msg = "could not find all the required sysctl keys" data = { "ram.percent": { "label": "RAM percent usage", "options": None, "status": status, "error_message": msg, "unit": "percent" }, "ram.kb_used": { "label": "RAM used (kB)", "options": None, "status": status, "error_message": msg, "unit": "kB" }, "ram.kb_buffer": { "label": "RAM buffer (kB)", "options": None, "status": status, "error_message": msg, "unit": "kB" }, "ram.kb_active": { "label": "RAM active (kB)", "options": None, "status": status, "error_message": msg, "unit": "kB" }, "ram.kb_inactive": { "label": "RAM inactive (kB)", "options": None, "status": status, "error_message": msg, "unit": "kB" }, "ram.kb_cached": { "label": "RAM cached (kB)", "options": None, "status": status, "error_message": msg, "unit": "kB" }, } return data elif 'aix' in sys.platform: status = agent_util.SUPPORTED msg = None data = { "ram.percent": { "label": "RAM percent usage", "options": None, "status": status, "error_message": msg }, "ram.kb_used": { "label": "RAM used (kB)", "options": None, "status": status, "error_message": msg, "unit": "kB" }, "swap.percent": { "label": "Swap percent usage", "options": None, "status": status, "error_message": msg }, "swap.kb_used": { "label": "Swap used (kB)", "options": None, "status": status, "error_message": msg, "unit": "kB" }, } return data elif 'sunos' in sys.platform: status = agent_util.SUPPORTED msg = None data = { "ram.percent": { "label": "RAM percent usage", "options": None, "status": status, "error_message": msg }, "ram.kb_used": { "label": "RAM used (kB)", "options": None, "status": status, "error_message": msg, "unit": "kB" }, } return data else: # Default Linux logic status = agent_util.SUPPORTED msg = None if not os.path.exists("/proc/meminfo"): status = agent_util.MISCONFIGURED msg = "Enable procfs." data = { "ram.percent": { "label": "RAM percent usage", "options": None, "status": status, "error_message": msg }, "ram.kb_used": { "label": "RAM used (kB)", "options": None, "status": status, "error_message": msg, "unit": "kB" }, "ram.kb_buffer": { "label": "RAM buffer (kB)", "options": None, "status": status, "error_message": msg, "unit": "kB" }, "swap.percent": { "label": "Swap percent usage", "options": None, "status": status, "error_message": msg, "unit": "percent", }, "swap.kb_used": { "label": "Swap used (Kb)", "options": None, "status": status, "error_message": msg }, "ram.kb_active": { "label": "RAM active (kB)", "options": None, "status": status, "error_message": msg, "unit": "kB" }, "ram.kb_inactive": { "label": "RAM inactive (kB)", "options": None, "status": status, "error_message": msg, "unit": "kB" }, "ram.kb_cached": { "label": "RAM cached (kB)", "options": None, "status": status, "error_message": msg, "unit": "kB" }, "swap.kb_cached": { "label": "Swap cached (kB)", "options": None, "status": status, "error_message": msg, "unit": "kB" } } return data
def check(self, textkey, data, config): if 'aix' in sys.platform or 'sunos' in sys.platform: #ps_cmd = "ps -eo %p' '%a" if 'aix' in sys.platform: ps_cmd = "ps axww" elif 'sunos' in sys.platform: ps_cmd = "ps -eo pid' 'args" retcode, output = agent_util.execute_command(ps_cmd) output = output.split('\n') if textkey.endswith('.full'): textkey = textkey.rstrip('.full') if textkey == 'process.running_count': return len(output)-1 else: count = 0 pids = [] for line in output[1:]: if data in line: count += 1 pids.append(line.split()[0]) if textkey == 'process.named_count': return count elif textkey == 'process.exists': if count: return 1 else: return 0 elif textkey in ["process.named_memory_percentage", "process.named_cpu_percentage"]: all_cpu = 0 all_mem = 0 for pid in pids: if 'aix' in sys.platform: ps = "ps -fp %s -o pcpu' 'pmem" % pid elif 'sunos' in sys.platform: ps = "ps -fp %s -o pcpu' 'pmem" % pid ret, output = agent_util.execute_command(ps) output = output.strip().split('\n') if len(output) < 2: continue fields = output[1].split() cpu = float(fields[0]) mem = float(fields[1]) all_cpu += cpu all_mem += mem if textkey == "process.named_memory_percentage": return all_mem else: return all_cpu # Unknown AIX/Solaris textkey return None # Default Linux/FreeBSD logic full = "" if textkey.endswith(".full"): textkey = textkey.rstrip(".full") full = "-f" if textkey == "process.running_count" or textkey == "count": num = 0 for f in os.listdir("/proc"): if f.isdigit(): num += 1 return num if textkey == "process.named_count": ret, output = agent_util.execute_command("pgrep %s %s" % (full, data)) if not output.strip(): return 0 else: return len(output.strip().split("\n")) elif textkey == "process.exists": ret, output = agent_util.execute_command("pgrep %s %s" % (full, data)) if not output.strip(): return 0 else: return 1 elif textkey in ["process.named_memory_percentage", "process.named_cpu_percentage"]: ret, output = agent_util.execute_command("pgrep %s %s" % (full, data)) if not output.strip(): return 0 all_cpu = 0 all_mem = 0 for pid in output.strip().split("\n"): ret, output = agent_util.execute_command("ps -p %s -o %%cpu,%%mem" % pid) if not output.strip() or len(output.strip().split("\n")) == 1: continue cpu, mem = [float(n.strip()) for n in output.strip().split("\n")[1].strip() .split(" ") if n.strip()] all_cpu += cpu all_mem += mem if textkey == "process.named_memory_percentage": return all_mem else: return all_cpu return 0
def check(self, textkey, interface, config): interface_found = False if 'freebsd' in sys.platform: ret, output = agent_util.execute_command("netstat -ib") lines = output.splitlines()[1:] for line in lines: line = line.split() si, mtu, network, addr, packets_read, ierr, idrop, bytes_read, packets_written, oerr, bytes_written, coll = line packets_read = int(packets_read) packets_written = int(packets_written) kbytes_read = int(bytes_read) / 1024 kbytes_written = int(bytes_written) / 1024 if si == interface and network.startswith("<Link"): interface_found = True break elif 'aix' in sys.platform: ret, output = agent_util.execute_command('netstat -v %s | grep "^Bytes:"' % interface) fields = output.split() kbytes_written = int(fields[1])/1024 kbytes_read = int(fields[3])/1024 ret, output = agent_util.execute_command('netstat -v %s | grep "^Packets:"' % interface) fields = output.split() packets_written = int(fields[1])/1024 packets_read = int(fields[3])/1024 interface_found = True elif 'sunos' in sys.platform: ret, output = agent_util.execute_command('netstat -i') for line in output.split('\n'): fields = line.strip().split() if not fields: continue if fields[0] == interface: interface_found = True packets_read = int(fields[4]) packets_written = int(fields[6]) kbytes_read = 0 kbytes_written = 0 ret, output = agent_util.execute_command("kstat -n %s 1 2 | egrep 'bytes64' | uniq" % interface) for line in output.split('\n'): if not line: continue if 'obytes' in line: fields = line.split() kbytes_read = int(fields[1]) / 1024 elif 'rbytes' in line: fields = line.split() kbytes_written = int(fields[1]) / 1024 else: output = open("/proc/net/dev", "r").read() self.log.debug("/proc/net/dev output: %s" % str(output)) output = output.splitlines() for line in output[2:]: stuff = line.strip().split() if not stuff[0].endswith(":"): stuff[0], new_insert = stuff[0].split(":") stuff.insert(1, new_insert) else: stuff[0] = stuff[0].rstrip(":") iface = stuff[0] bytes_read = int(stuff[1]) bytes_written = int(stuff[9]) kbytes_read = int(bytes_read) / 1024 kbytes_written = int(stuff[9]) / 1024 packets_read = int(stuff[2]) packets_written = int(stuff[10]) if interface == iface: interface_found = True break # Special handling for monthly bandwidth - each time through we bank the # difference in the current reading vs. the previous, taking into account # cases where we cross a month boundary and when the byte counters wrap if textkey.startswith("bandwidth.monthly"): if textkey == "bandwidth.monthly.in": current_bytes = bytes_read else: current_bytes = bytes_written # First get the cached values c = self.get_cache_results(textkey+":current_bytes", interface) previous_bytes = c and c[0][1] or current_bytes c = self.get_cache_results(textkey+":banked_bytes", interface) banked_bytes = c and c[0][1] or 0 c = self.get_cache_results(textkey+":current_month", interface) current_month = c and c[0][1] or datetime.now().month c = self.get_cache_results(textkey+":current_year", interface) current_year = c and c[0][1] or datetime.now().year now = datetime.now() if now.year != current_year or now.month != current_month: # If we"ve crossed a month boundary, zero out bank and reset counters banked_bytes = 0 current_year = now.year current_month = now.month previous_bytes = current_bytes elif current_bytes < previous_bytes: # The OS counters wrapped, need to handle this banked_bytes += current_bytes previous_bytes = current_bytes else: # Standard case, just bank the difference between current and last banked_bytes += (current_bytes - previous_bytes) previous_bytes = current_bytes # Cache the new values self.cache_result(textkey+":current_bytes", interface, current_bytes, replace=True) self.cache_result(textkey+":banked_bytes", interface, banked_bytes, replace=True) self.cache_result(textkey+":current_month", interface, current_month, replace=True) self.cache_result(textkey+":current_year", interface, current_year, replace=True) return banked_bytes/1024 # Because of AIX's interface naming convention, every # command provides a different interface name, we need to ignore that if "aix" in sys.platform: pass else: if not interface_found: raise Exception("interface %s not found!?" % interface) # try to get the old cache cache = self.get_cache_results(textkey, interface) # cache our result always if textkey == "bandwidth.kbytes.in": result = kbytes_read elif textkey == "bandwidth.kbytes.out": result = kbytes_written elif textkey == "bandwidth.packets.in": result = packets_read elif textkey == "bandwidth.packets.out": result = packets_written self.cache_result(textkey, interface, result) if not cache: return 0.0 delta, cached_result = cache[0] self.log.debug("kbytes read: %d" % kbytes_read) self.log.debug("kbytes written: %d" % kbytes_written) self.log.debug("packets read: %d" % packets_read) self.log.debug("packets written: %d" % packets_written) return (result - cached_result) / float(delta)
def get_metadata(self, config): status = agent_util.SUPPORTED msg = None if not agent_util.which("df", exc=False): self.log.info("df binary not found") status = agent_util.UNSUPPORTED msg = "df binary not found" return {} devices = [] if status is agent_util.SUPPORTED: ret_code, output = agent_util.execute_command(get_df_cmd()) output = output.splitlines() if config.get("debug", False): self.log.debug('#####################################################') self.log.debug("Disk command '%s' output :" % get_df_cmd()) self.log.debug(str(output)) self.log.debug('#####################################################') if "aix" in sys.platform or "sunos" in sys.platform: self.device_ignore_list = self.device_ignore_list + ("proc", "swap") for line in output[1:]: line = line.strip() try: device, blocks, used, available, capacity, mounted = line.split() if device in self.device_ignore_list: continue devices.append("%s mounted at %s" % (device, mounted)) except: self.log.error("Unable to parse df output: %s" % line) continue if status is agent_util.SUPPORTED and not devices: status = agent_util.MISCONFIGURED msg = "No disks found (or none visible from df)." data = { "usage.percent_used": { "label": "Percentage of disk used", "options": devices, "status": status, "error_message": msg, "unit": "percent", }, "usage.kb_available": { "label": "Disk space available", "options": devices, "status": status, "error_message": msg, "unit": "kB" }, "filesystem.mounted": { "label": "Filesystem mounted", "options": devices, "status": status, "error_message": msg, }, } return data
def execute_query(query): ret, output = agent_util.execute_command(query) return str(output);
def get_metadata(self, config): status = agent_util.SUPPORTED msg = None interfaces = set() if 'freebsd' in sys.platform: if not agent_util.which("netstat"): self.log.info("netstat not found") status = agent_util.UNSUPPORTED msg = "Please install netstat." return {} if status is agent_util.SUPPORTED: ret, output = agent_util.execute_command("netstat -ib") if config.get("debug", False): self.log.debug('#####################################################') self.log.debug("Bandwidth command 'netstat -ib' output:") self.log.debug(output) self.log.debug('#####################################################') output = output.splitlines()[1:] for line in output: stuff = line.strip().split() iface = stuff[0] interfaces.add(iface) elif 'aix' in sys.platform: if not agent_util.which("netstat"): self.log.info("netstat not found") status = agent_util.UNSUPPORTED msg = "Please install netstat." return {} # Get the list of network devices interfaces = [] ret, output = agent_util.execute_command("netstat -v | grep 'ETHERNET STATISTICS'") output = output.strip().split('\n') for line in output: fields = line.split() try: interfaces.append(fields[2].strip('(').strip(')')) except: pass metadata = {} metadata["bandwidth.kbytes.in"] = { "label": "Kilobytes IN per second", "options": interfaces, "status": status, "error_message": msg, "unit": "kB" } metadata["bandwidth.kbytes.out"] = { "label": "Kilobytes OUT per second", "options": interfaces, "status": status, "error_message": msg, "unit": "kB" } metadata["bandwidth.packets.in"] = { "label": "Packets IN per second", "options": interfaces, "status": status, "error_message": msg, "unit": "packets" } metadata["bandwidth.packets.out"] = { "label": "Packets OUT per second", "options": interfaces, "status": status, "error_message": msg, "unit": "packets" } return metadata elif 'sunos' in sys.platform: if not agent_util.which("netstat"): self.log.info("netstat not found") status = agent_util.UNSUPPORTED msg = "Please install netstat." return {} # Get the list of network devices interfaces = [] ret, output = agent_util.execute_command("netstat -i") output = output.strip().split('\n') for line in output: fields = line.split() if fields[0] in ('lo', 'inet', 'ether', 'Name'): continue try: interfaces.append(fields[0]) except: pass metadata = {} metadata["bandwidth.kbytes.in"] = { "label": "Kilobytes IN per second", "options": interfaces, "status": status, "error_message": msg, "unit": "kB" } metadata["bandwidth.kbytes.out"] = { "label": "Kilobytes OUT per second", "options": interfaces, "status": status, "error_message": msg, "unit": "kB" } metadata["bandwidth.packets.in"] = { "label": "Packets IN per second", "options": interfaces, "status": status, "error_message": msg, "unit": "packets" } metadata["bandwidth.packets.out"] = { "label": "Packets OUT per second", "options": interfaces, "status": status, "error_message": msg, "unit": "packets" } return metadata else: # Default Linux options if not os.path.exists("/proc/net/dev"): self.log.info("/proc/net/dev not found") status = agent_util.UNSUPPORTED msg = "/proc/net/dev not found" return {} if status is agent_util.SUPPORTED: # get the interfaces output = open("/proc/net/dev", "r").read() output = output.splitlines() if config.get("debug", False): self.log.debug('#####################################################') self.log.debug("Content of file '/proc/net/dev':") self.log.debug(str(output)) self.log.debug('#####################################################') for line in output[2:]: stuff = line.strip().split() iface, bytes_read = stuff[0].split(":") interfaces.add(iface) interfaces = list(interfaces) interfaces.sort() if status is agent_util.SUPPORTED and not interfaces: status = agent_util.MISCONFIGURED msg = "No network interfaces found." metadata = {} metadata["bandwidth.kbytes.in"] = { "label": "Kilobytes IN per second", "options": interfaces, "status": status, "error_message": msg, "unit": "kB" } metadata["bandwidth.kbytes.out"] = { "label": "Kilobytes OUT per second", "options": interfaces, "status": status, "error_message": msg, "unit": "kB" } metadata["bandwidth.packets.in"] = { "label": "Packets IN per second", "options": interfaces, "status": status, "error_message": msg, "unit": "packets" } metadata["bandwidth.packets.out"] = { "label": "Packets OUT per second", "options": interfaces, "status": status, "error_message": msg, "unit": "packets" } if 'freebsd' not in sys.platform: metadata["bandwidth.monthly.in"] = { "label": "Kilobytes IN for the month", "options": interfaces, "status": status, "error_message": msg, "unit": "kB" } metadata["bandwidth.monthly.out"] = { "label": "Kilobytes OUT for the month", "options": interfaces, "status": status, "error_message": msg, "unit": "kB" } return metadata
def check(self, textkey, data, config={}): # AIX-specific logic if 'aix' in sys.platform: if textkey.startswith('load_average'): retcode, output = agent_util.execute_command('uptime') fields = output.strip().split() if textkey == 'load_average.1': return float(fields[-3].strip(',')) elif textkey == 'load_average.5': return float(fields[-2].strip(',')) elif textkey == 'load_average.15': return float(fields[-1]) else: return None else: retcode, output = agent_util.execute_command('iostat | grep -p tty') output = output.strip().split('\n') self.log.debug("iostat output: %s" % output) iostatline = False enti = False entc = 0 inuse = 0 user = 0 system = 0 idle = 0 iowait = 0 for line in output: if line.startswith('tty'): iostatline = True if 'entc' in line.split()[-1]: enti = True continue fields = line.split() user = float(fields[2]) system = float(fields[3]) idle = float(fields[4]) iowait = float(fields[5]) if enti == True: entc = float(fields[-1]) inuse = 100. - idle if textkey == 'usage_percentage': return inuse elif textkey == 'user_usage_percentage': print user elif textkey == 'system_usage_percentage': return system elif textkey == 'idle_usage_percentage': return idle elif textkey == 'iowait_usage_percentage': return iowait elif textkey == 'cpu_entitlement_percentage' and enti == True: return entc # If we got here, we don't know how to gather this metric # for AIX - return None return None elif 'sunos' in sys.platform: retcode, output = agent_util.execute_command('mpstat') output = output.split('\n') for line in output: if 'CPU' in line or not line: continue fields = line.split() if textkey == 'usage_percentage': return 100.-float(fields[-1]) elif textkey == 'user_usage_percentage': return float(fields[-4]) elif textkey == 'system_usage_percentage': return float(fields[-3]) elif textkey == 'idle_usage_percentage': return float(fields[-1]) elif textkey == 'iowait_usage_percentage': return float(fields[-2]) # If we got here we don't know how to gather this metric for Solaris return None # Default Linux/FreeBSD logic usage_textkey_map = { 'user_usage_percentage': 'us', 'system_usage_percentage': 'sy', 'idle_usage_percentage': 'id', 'iowait_usage_percentage': 'wa', 'irq_usage_percentage': 'hi', 'softirg_usage_percentage': 'si', 'stealtime_usage_percentage': 'st', 'nice_usage_percentage': 'ni', } if textkey.startswith("load_average") or textkey in usage_textkey_map: retcode, output = agent_util.execute_command("top -b -n 1") if config.get("debug", False): self.log.debug('#####################################################') self.log.debug("CPU usage command 'top -b -n 1' output :") self.log.debug(str(output)) self.log.debug('#####################################################') self.log.debug("top -b -n 1 output: %s" % str(output)) output = output.splitlines() if textkey.startswith("load_average"): fields = output[0].split() if textkey == "load_average.1": index = -3 elif textkey == "load_average.5": index = -2 elif textkey == "load_average.15": index = -1 return float(fields[index].strip(",")) else: fields = [f.strip(",") for f in output[2].split()][1:] fields = dict([(f[f.index("%") + 1:], float(f[0:f.index("%")])) for f in fields]) return fields[usage_textkey_map[textkey]] elif textkey == 'usage_percentage': old_stat = get_cpu_metrics(self)[data] time.sleep(0.5) current_stat = get_cpu_metrics(self)[data] old_usage = old_stat["user"] + old_stat["nice"] + old_stat["system"] + old_stat["idle"] current_usage = current_stat["user"] + current_stat["nice"] + current_stat["system"] + current_stat["idle"] usage = int(100.0 * ((current_usage - old_usage) - (current_stat["idle"] - old_stat["idle"])) / (current_usage - old_usage)) return usage return 0
def get_metadata(self, config): package_count_status = agent_util.UNSUPPORTED package_date_status = agent_util.UNSUPPORTED package_count_msg = None package_date_msg = None if IS_DEBIAN or IS_REDHAT: package_date_status = agent_util.SUPPORTED if IS_DEBIAN: try: import apt_check if agent_util.execute_command("sudo /usr/bin/apt-get")[0] == 0: package_count_status = agent_util.SUPPORTED except: package_count_msg = "Insufficient permission - enable sudo access to apt-get for agent user" else: if agent_util.execute_command("sudo /usr/bin/yum --help")[0] == 0: package_count_status = agent_util.SUPPORTED else: package_count_msg = "Insufficient permission - enable sudo access to yum for agent user" else: package_date_msg = "Unsupported platform" package_count_msg = "Unsupported platform" self.log.info("Unsupported platform") return {} metadata = { "packages.security": { "label": "Security-related packages waiting to be updated", "options": None, "status": package_count_status, "error_message": package_count_msg, "unit": "", "option_string": False }, "packages.nonsecurity": { "label": "Non-security-related packages waiting to be updated", "options": None, "status": package_count_status, "error_message": package_count_msg, "unit": "", "option_string": False }, "packages.lastupdated": { "label": "Days since the last package update was run", "options": None, "status": package_date_status, "error_message": package_date_msg, "unit": "", "option_string": False }, "packages.check_installation": { "label": "Check for Package installation", "options": None, "status": package_date_status, "error_message": package_date_msg, "unit": "", "option_string": True } } return metadata
def check(self, textkey, data, config={}): if IS_DEBIAN: if textkey in ['packages.security', 'packages.nonsecurity']: try: import apt_check except: return 0 if agent_util.execute_command("sudo /usr/bin/apt-get update")[0] != 0: return 0 upgrades, security_updates = apt_check.check() if textkey == 'packages.security': return security_updates else: return upgrades if textkey == 'packages.security': return security_updates else: return upgrades elif textkey == 'packages.lastupdated': # Get list of apt history log files, from newest to oldest, search each one til we find an update files = agent_util.execute_command("ls -t /var/log/apt/history*")[1].strip().split('\n') for f in files: lines = agent_util.execute_command("zgrep -A 1 Upgrade %s | tail -n 2" % f)[1].strip().split('\n') if len(lines) >= 2: d = lines[-1].split(' ')[1] d = datetime.strptime(d, "%Y-%m-%d") age = (datetime.now() - d).days return max(age, 0) # if we got here, we didn't find anything. Return -1 as a marker return -1 elif textkey == 'packages.check_installation': if data: command = "dpkg-query -l %s" % data.strip() if agent_util.execute_command(command)[0] != 0: return 0 else: return 1 elif IS_REDHAT: if textkey in ['packages.security', 'packages.nonsecurity']: retcode, output = agent_util.execute_command("sudo yum check-update --security") if '\n\n' not in output: num_sec_packages = 0 else: num_sec_packages = len(output.split('\n\n')[-1].split('\n')) if textkey == 'packages.security': return num_sec_packages else: retcode, output = agent_util.execute_command("sudo yum check-update") if '\n\n' not in output: num_packages = 0 else: num_packages = len(output.split('\n\n')[-1].split('\n')) return max(0, num_packages - num_sec_packages) elif textkey == 'packages.lastupdated': # Get list of apt history log files, from newest to oldest, search each one til we find an update files = agent_util.execute_command("ls -t /var/log/yum.log*")[1].strip().split('\n') for f in files: lines = agent_util.execute_command("sudo zgrep -A 1 Updated: %s | tail -n 1" % f)[1].strip().split('\n') if len(lines) >= 1: d = lines[-1][:6] d = datetime.strptime(d, "%b %d").replace(year=date.today().year) if d > datetime.now(): d = d.replace(year=date.today().year-1) age = (datetime.now() - d).days return max(age, 0) elif textkey == 'packages.check_installation': if data: command = "rpm -qi %s" % data.strip() if agent_util.execute_command(command)[0] != 0: return 0 else: return 1 # if we got here, we didn't find anything. Return -1 as a marker return -1 # If we get here, we aren't running on a system where we can actually determine what's available. # Default to zero. return 0
def get_metadata(self, config): status = agent_util.SUPPORTED msg = None self.log.info("looking for apache2ctl") apache_bin = agent_util.which("apache2ctl") if not apache_bin: self.log.info("couldn't find apache2ctl, looking for apachectl") apache_bin = agent_util.which("apachectl") if not apache_bin: self.log.info("couldn't find apachectl or apache2ctl") status = agent_util.UNSUPPORTED msg = "Couldn't find apachectl or apache2ctl" return {} if 'freebsd' in platform: if not agent_util.which("lynx"): status = agent_util.MISCONFIGURED msg = "Lynx required." if status is agent_util.SUPPORTED: ret, output = agent_util.execute_command("%s status" % apache_bin) if config.get("debug", False): self.log.info('#####################################################') self.log.info("Apache command '%s status' output:" % apache_bin) self.log.info(output) self.log.info('#####################################################') if ret != 0 or "Can't load" in output or "failed" in output or "not found" in output: self.log.error("couldn't get apache status") status = agent_util.MISCONFIGURED msg = "Couldn't get apache status, make sure Apache is running and the status module is enabled" metadata = { "apache.workers_used": { "label": "Workers - percent serving requests", "options": None, "status": status, "error_message": msg, "unit": "%" }, "apache.workers_idle": { "label": "Workers - percent idle", "options": None, "status": status, "error_message": msg, "unit": "%" }, "apache.workers_used_count": { "label": "Workers - count serving requests", "options": None, "status": status, "error_message": msg, "unit": "workers" }, "apache.workers_idle_count": { "label": "Workers - count idle", "options": None, "status": status, "error_message": msg, "unit": "workers" }, "apache.uptime": { "label": "Server uptime", "options": None, "status": status, "error_message": msg, "unit": "seconds" } } # other require an extended status enabled if self.get_data("apache.total_accesses") == None: ret, output = agent_util.execute_command("%s -V" % apache_bin) match = re.search("HTTPD_ROOT=\"(.+?)\"", output) try: server_root = match.group(1) except: server_root = "" match = re.search("SERVER_CONFIG_FILE=\"(.+?)\"", output) try: server_config_file = os.path.join(server_root, match.group(1)) except: server_config_file = "Apache server config file" status = agent_util.MISCONFIGURED msg = "Enable 'ExtendedStatus On' in %s" % server_config_file metadata.update({ "apache.total_accesses": { "label": "Request count", "options": None, "status": status, "error_message": msg, "unit": "requests" }, "apache.total_traffic": { "label": "Total content served", "options": None, "status": status, "error_message": msg, "unit": "MB" }, "apache.cpu_load": { "label": "Percentage of CPU used by all workers", "options": None, "status": status, "error_message": msg, "unit": None }, "apache.connections": { "label": "Requests per second", "options": None, "status": status, "error_message": msg, "unit": "requests" }, "apache.transfer_rate": { "label": "Transfer rate", "options": None, "status": status, "error_message": msg, "unit": "MB/s" }, "apache.avg_request_size": { "label": "Request size average", "options": None, "status": status, "error_message": msg, "unit": "MB" } }) return metadata
def get_data(self, textkey): apache_bin = agent_util.which("apache2ctl") self.log.debug("apache_bin: %s" % str(apache_bin)) if not apache_bin: apache_bin = agent_util.which("apachectl", exc=True) ret, output = agent_util.execute_command("%s status" % apache_bin) if textkey == "apache.uptime": if output.find("Server uptime: ") == -1: return None output = output[output.index("Server uptime: "):] uptime = output[:output.index("\n")].replace("Server uptime: ", "").strip() uptime = uptime.replace(" seconds", "*1").replace(" second", "*1") \ .replace(" minutes", "*60").replace(" minute", "*60") \ .replace(" hours", "*60*60").replace(" hour", "*60*60") \ .replace(" days", "*60*60*24").replace(" day", "*60*60*24") \ .replace(" ", "+") uptime = eval(uptime) return uptime elif textkey in ("apache.total_accesses", "apache.total_traffic"): for line in output.lower().split('\n'): if "total accesses" in line: fields = line.split() accesses = int(fields[2]) traffic = float(fields[-2]) units = fields[-1] # Convert from various units to megabytes if units == 'b': traffic = traffic / (1024 * 1024) elif units == 'kb': traffic = traffic / 1024 elif units == 'gb': traffic = traffic * 1024 elif units == 'tb': traffic = traffic * 1024 * 1024 if textkey == "apache.total_accesses": return accesses else: return traffic return None elif textkey == "apache.cpu_load": for line in output.lower().split('\n'): if "cpu usage" in line: fields = line.split() cpu_load = float(fields[-3].rstrip('%')) return cpu_load return None elif textkey in ("apache.connections", "apache.transfer_rate", "apache.avg_request_size"): for line in output.lower().split('\n'): if "requests/sec" in line: fields = line.split() if textkey == "apache.connections": return float(fields[0]) elif textkey == "apache.transfer_rate": value = float(fields[3]) units = fields[4].split('/')[0] if units == 'b': value = value / (1024 * 1024) elif units == 'kb': value = value / 1024 elif units == 'gb': value = value * 1024 elif units == 'tb': value = value * 1024 * 1024 return value elif textkey == "apache.avg_request_size": value = float(fields[-2]) units = fields[-1].split('/')[0] if units == 'b': value = value / (1024 * 1024) elif units == 'kb': value = value / 1024 elif units == 'gb': value = value * 1024 elif units == 'tb': value = value * 1024 * 1024 return value elif textkey in ("apache.workers_used", "apache.workers_idle", "apache.workers_used_count", "apache.workers_idle_count"): for line in output.lower().split('\n'): if "requests currently being processed" in line: fields = line.split() workers = int(fields[0]) idle = int(fields[-3]) total = workers + idle if total == 0: return 0 if textkey == "apache.workers_used": return float(100. * workers / total) elif textkey == "apache.workers_idle": return float(100. * idle / total) elif textkey == "apache.workers_used_count": return workers elif textkey == "apache.workers_idle_count": return idle return None