#!/usr/bin/python """ =head1 NAME monit_parser - Monit status parser plugin for munin. =head1 APPLICABLE SYSTEMS Any system running monit. Monit needs to be configured with the httpd port enabled, e.g.: set httpd port 2812 The configured port is not important, since this plugin uses "monit status" for retrieving data. Thus the monit configuration is parsed implicitly. =head1 CONFIGURATION This plugin requires read access for the monit configuration. Thus it needs to run as root: [monit_parser] user root =head1 AUTHOR Todd Troxell Lars Kruse =head1 MAGIC MARKERS family=auto capabilities=autoconf =cut """ import os import re import subprocess import sys def sanitize(s): OK_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789" out = str() for char in s: if char.lower() in OK_CHARS: out += char return out procs = dict() try: output = subprocess.check_output(STATUS_CMD.split()) except (OSError, subprocess.CalledProcessError) as exc: sys.stderr.write("Error running monit status command: %s%s" % (exc, os.linesep)) sys.exit(1) # python3: the result of command execution is bytes and needs to be converted if not isinstance(output, str): output = output.decode("ascii", "ignore") output = output.splitlines() cur_proc = None for line in output: m = re.match("^Process '(.*)'.*$", line) if m: cur_proc = sanitize(m.group(1)) try: procs[cur_proc] except KeyError: procs[cur_proc] = dict() continue m = re.match(" memory kilobytes total\s+([0-9]+).*$", line) if m: procs[cur_proc]["total_memory"] = m.group(1) continue m = re.match(" cpu percent total\s+([.0-9]+)%.*$", line) if m: procs[cur_proc]["total_cpu"] = m.group(1) continue if len(sys.argv) > 1 and sys.argv[1] == 'config': print('graph_title Per process stats from Monit') print('graph_vlabel numbers') print('graph_category monit') for process in procs: for stat in procs[process]: print("monit_%s_%s.label %s.%s" % (process, stat, process, stat)) if stat == 'total_memory': print("monit_%s_%s.warning 1:" % (process, stat)) sys.exit(0) for process in procs: for stat in procs[process]: print("monit_%s_%s.value %s" % (process, stat, procs[process][stat]))